jens@0
|
1 |
/*
|
jens@0
|
2 |
* Ottoman.h
|
jens@0
|
3 |
* Ottoman
|
jens@0
|
4 |
*
|
jens@0
|
5 |
* Created by Jens Alfke on 8/31/09.
|
jens@0
|
6 |
* Copyright 2009 Jens Alfke. All rights reserved.
|
jens@0
|
7 |
* BSD-Licensed: See the file "LICENSE.txt" for details.
|
jens@0
|
8 |
*/
|
jens@0
|
9 |
|
jens@0
|
10 |
#ifndef _MOOSEYARD_OTTOMAN_
|
jens@0
|
11 |
#define _MOOSEYARD_OTTOMAN_
|
jens@0
|
12 |
|
jens@0
|
13 |
namespace Mooseyard {
|
jens@0
|
14 |
|
jens@0
|
15 |
class ChunkIterator;
|
jens@0
|
16 |
class Dictionary;
|
jens@0
|
17 |
class File;
|
jens@0
|
18 |
class VersionDictionary;
|
jens@0
|
19 |
class OverlayDictionary;
|
jens@0
|
20 |
|
jens@0
|
21 |
|
jens@0
|
22 |
/** A version-controlled persistent dictionary.
|
jens@0
|
23 |
Each version is stored as a VersionDictionary, unsaved changes as an OverlayDictionary. */
|
jens@0
|
24 |
class Ottoman {
|
jens@0
|
25 |
public:
|
jens@0
|
26 |
/** Creates an "untitled" Ottoman with no file and no lastVersion.
|
jens@0
|
27 |
After adding values to the currentVersion, use saveAs to save it. */
|
jens@0
|
28 |
Ottoman ();
|
jens@0
|
29 |
|
jens@0
|
30 |
/** Opens an existing Ottoman file. */
|
jens@0
|
31 |
explicit Ottoman (const char *filename, bool writeable =true);
|
jens@0
|
32 |
|
jens@0
|
33 |
/** Closes an Ottoman. */
|
jens@0
|
34 |
virtual ~Ottoman();
|
jens@0
|
35 |
|
jens@0
|
36 |
/** The current filename, or NULL if the receiver is still in the "untitled" state. */
|
jens@0
|
37 |
virtual const char* filename() const {return _filename;}
|
jens@0
|
38 |
|
jens@0
|
39 |
/** The latest saved version of the dictionary.
|
jens@0
|
40 |
Earlier versions can be accessed through its previousVersion() accessor.
|
jens@0
|
41 |
This will be NULL if the receiver is still in the "untitled" state. */
|
jens@0
|
42 |
virtual VersionDictionary* lastVersion() const {return _lastVersion;}
|
jens@0
|
43 |
|
jens@0
|
44 |
/** A mutable overlay representing the current state of the dictionary.
|
jens@0
|
45 |
Changes are made in memory until save() is called.
|
jens@0
|
46 |
This will be NULL if the receiver was opened read-only (writeable=false). */
|
jens@0
|
47 |
virtual OverlayDictionary* currentVersion() const {return _current;}
|
jens@0
|
48 |
|
jens@0
|
49 |
/** Has the on-disk file been updated with newer revisions than what I know about? */
|
jens@0
|
50 |
virtual bool needsSync() const;
|
jens@0
|
51 |
|
jens@0
|
52 |
/** Reads any newer versions from disk.
|
jens@0
|
53 |
Returns true if new versions were read, false if there were none.
|
jens@0
|
54 |
Afterwards, lastVersion() will return the latest version in the file.
|
jens@0
|
55 |
(The old lastVersion dictionary is still around, so you can save a pointer to it
|
jens@0
|
56 |
before the call and use it later to see what changed.)
|
jens@0
|
57 |
Changes made to the currentVersion dictionary are not lost, but are now relative
|
jens@0
|
58 |
to the new lastVersion. You may want to scan them and resolve conflicts. */
|
jens@0
|
59 |
virtual bool sync();
|
jens@0
|
60 |
|
jens@0
|
61 |
/** Saves the current version to the file, by appending.
|
jens@0
|
62 |
Returns false if there is a version conflict; in that case you need to call sync(),
|
jens@0
|
63 |
possibly resolve conflicts, and then call save() again. */
|
jens@0
|
64 |
virtual bool save();
|
jens@0
|
65 |
|
jens@0
|
66 |
/** Saves the current version to the file, by writing to a new temporary file and
|
jens@0
|
67 |
then atomically replacing the original.
|
jens@0
|
68 |
Older versions, and older copies of the data, are not preserved, so this
|
jens@0
|
69 |
will typically shrink the file quite a bit.
|
jens@0
|
70 |
Returns false if there is a version conflict. */
|
jens@0
|
71 |
virtual bool saveAndCompact();
|
jens@0
|
72 |
|
jens@0
|
73 |
/** Saves the current version to a new file, leaving the new file open,
|
jens@0
|
74 |
so subsequent saves will be written to it. */
|
jens@0
|
75 |
virtual void saveAs (const char *newFilename, bool overwriteAllowed =true);
|
jens@0
|
76 |
|
jens@0
|
77 |
/** Scans the file for damage. Returns true if the file is OK, false if problems are found.
|
jens@0
|
78 |
If the 'repair' flag is set, will truncate the file to the last valid version. */
|
jens@0
|
79 |
bool scavenge (bool repair =false);
|
jens@0
|
80 |
|
jens@0
|
81 |
ChunkIterator* chunkIterator() const; // for testing purposes
|
jens@0
|
82 |
|
jens@0
|
83 |
private:
|
jens@0
|
84 |
Ottoman(const Ottoman&); // forbid copying/assignment
|
jens@0
|
85 |
Ottoman& operator=(const Ottoman&);
|
jens@0
|
86 |
|
jens@0
|
87 |
void _open();
|
jens@0
|
88 |
void _append (File *dstFile);
|
jens@0
|
89 |
File* _writeTo (const char *dstFileName, bool overwriteAllowed);
|
jens@0
|
90 |
|
jens@0
|
91 |
bool _writeable;
|
jens@0
|
92 |
File *_file;
|
jens@0
|
93 |
char *_filename;
|
jens@0
|
94 |
VersionDictionary *_lastVersion;
|
jens@0
|
95 |
OverlayDictionary *_current;
|
jens@0
|
96 |
};
|
jens@0
|
97 |
|
jens@0
|
98 |
}
|
jens@0
|
99 |
#endif // _MOOSEYARD_OTTOMAN_
|