jens@0
|
1 |
/*
|
jens@0
|
2 |
* VersionDictionary.h
|
jens@0
|
3 |
* Ottoman
|
jens@0
|
4 |
*
|
jens@0
|
5 |
* Created by Jens Alfke on 8/21/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_VERSIONDICTIONARY_
|
jens@0
|
11 |
#define _MOOSEYARD_VERSIONDICTIONARY_
|
jens@0
|
12 |
#include "Dictionary.h"
|
jens@0
|
13 |
|
jens@0
|
14 |
namespace Mooseyard {
|
jens@0
|
15 |
|
jens@0
|
16 |
class File;
|
jens@0
|
17 |
class Index;
|
jens@0
|
18 |
|
jens@0
|
19 |
/** A persistent Dictionary embedded in a memory-mapped file,
|
jens@0
|
20 |
representing one complete version of an Ottoman dictionary. */
|
jens@0
|
21 |
class VersionDictionary :public Dictionary {
|
jens@0
|
22 |
public:
|
jens@0
|
23 |
|
jens@0
|
24 |
/** The generation number. The first version in a new file is zero. */
|
jens@0
|
25 |
int generation() const;
|
jens@0
|
26 |
|
jens@0
|
27 |
/** The absolute time at which this version was written to the file. */
|
jens@0
|
28 |
time_t timestamp() const;
|
jens@0
|
29 |
|
jens@0
|
30 |
/** The previous version, before this one was saved. */
|
jens@0
|
31 |
const VersionDictionary* previousVersion() const;
|
jens@0
|
32 |
|
jens@0
|
33 |
/** Is this the latest version in the file? */
|
jens@0
|
34 |
bool isLatestVersion() const;
|
jens@0
|
35 |
|
jens@0
|
36 |
virtual int count() const;
|
jens@0
|
37 |
virtual Blob get (Key) const;
|
jens@0
|
38 |
class Iterator;
|
jens@0
|
39 |
virtual Dictionary::Iterator* iterate() const;
|
jens@0
|
40 |
|
jens@0
|
41 |
class ChangeIterator;
|
jens@0
|
42 |
/** Iterates over the changes between this dictionary and the previous version. */
|
jens@0
|
43 |
virtual ChangeIterator* iterateChanges() const;
|
jens@0
|
44 |
|
jens@0
|
45 |
|
jens@0
|
46 |
// Stuff you probably won't need to use:
|
jens@0
|
47 |
|
jens@0
|
48 |
File* file() const {return _file;}
|
jens@0
|
49 |
explicit VersionDictionary (File*);
|
jens@0
|
50 |
VersionDictionary (File *file, FilePosition trailerPosition);
|
jens@0
|
51 |
|
jens@0
|
52 |
private:
|
jens@0
|
53 |
/** The type of the trailer chunk that's used as the position of the dictionary. */
|
jens@0
|
54 |
static const uint16_t kChunkType = 3;
|
jens@0
|
55 |
|
jens@0
|
56 |
struct IndexPositions {
|
jens@0
|
57 |
LittleEndian<FilePosition> position[256];
|
jens@0
|
58 |
LittleEndian<FilePosition>& operator[] (int i) {return position[i];}
|
jens@0
|
59 |
LittleEndian<FilePosition> const& operator[] (int i) const {return position[i];}
|
jens@0
|
60 |
};
|
jens@0
|
61 |
|
jens@0
|
62 |
class Trailer;
|
jens@0
|
63 |
const Trailer* _trailer() const;
|
jens@0
|
64 |
const Index* _index (int i) const;
|
jens@0
|
65 |
void _read (FilePosition trailerPosition =0);
|
jens@0
|
66 |
static FilePosition _append (const VersionDictionary *baseDict,
|
jens@0
|
67 |
const Dictionary *addDict,
|
jens@0
|
68 |
File *dstFile,
|
jens@0
|
69 |
bool replace);
|
jens@0
|
70 |
|
jens@0
|
71 |
File *_file;
|
jens@0
|
72 |
FilePosition _trailerPosition, _previousTrailerPosition;
|
jens@0
|
73 |
IndexPositions _indexPositions;
|
jens@0
|
74 |
int _count;
|
jens@0
|
75 |
mutable const VersionDictionary *_previousVersion;
|
jens@0
|
76 |
|
jens@0
|
77 |
#if VERSIONDICTIONARY_TESTING
|
jens@0
|
78 |
public:
|
jens@0
|
79 |
#endif
|
jens@0
|
80 |
static VersionDictionary* create (File *file, const Dictionary *srcDict);
|
jens@0
|
81 |
VersionDictionary* byAppending (const Dictionary* d) const {return _appendAndOpen(d,_file,false);}
|
jens@0
|
82 |
VersionDictionary* byReplacing (const Dictionary* d) const {return _appendAndOpen(d,_file,true);}
|
jens@0
|
83 |
VersionDictionary* _appendAndOpen (const Dictionary *addDict, File *dstFile, bool replace) const;
|
jens@0
|
84 |
|
jens@0
|
85 |
friend class Ottoman;
|
jens@0
|
86 |
UNCOPYABLE(VersionDictionary);
|
jens@0
|
87 |
};
|
jens@0
|
88 |
|
jens@0
|
89 |
|
jens@0
|
90 |
class VersionDictionary::Iterator :public Dictionary::Iterator {
|
jens@0
|
91 |
public:
|
jens@0
|
92 |
explicit Iterator (const VersionDictionary*);
|
jens@0
|
93 |
virtual ~Iterator();
|
jens@0
|
94 |
virtual Key key() const;
|
jens@0
|
95 |
virtual Blob value() const;
|
jens@0
|
96 |
virtual bool next();
|
jens@0
|
97 |
virtual bool hasValue() const;
|
jens@0
|
98 |
private:
|
jens@0
|
99 |
bool nextIndex();
|
jens@0
|
100 |
|
jens@0
|
101 |
const VersionDictionary *_file;
|
jens@0
|
102 |
int _bucket;
|
jens@0
|
103 |
Dictionary::Iterator *_iter;
|
jens@0
|
104 |
UNCOPYABLE(Iterator);
|
jens@0
|
105 |
};
|
jens@0
|
106 |
|
jens@0
|
107 |
|
jens@0
|
108 |
class VersionDictionary::ChangeIterator :public Dictionary::Iterator {
|
jens@0
|
109 |
public:
|
jens@0
|
110 |
explicit ChangeIterator (const VersionDictionary*);
|
jens@0
|
111 |
virtual ~ChangeIterator();
|
jens@0
|
112 |
virtual Key key() const;
|
jens@0
|
113 |
virtual Blob value() const;
|
jens@0
|
114 |
virtual bool next();
|
jens@0
|
115 |
virtual bool hasValue() const;
|
jens@0
|
116 |
private:
|
jens@0
|
117 |
bool nextIndex();
|
jens@0
|
118 |
|
jens@0
|
119 |
const VersionDictionary *_file;
|
jens@0
|
120 |
int _bucket;
|
jens@0
|
121 |
Dictionary::Iterator *_iter;
|
jens@0
|
122 |
UNCOPYABLE(ChangeIterator);
|
jens@0
|
123 |
};
|
jens@0
|
124 |
|
jens@0
|
125 |
}
|
jens@0
|
126 |
|
jens@0
|
127 |
#endif //_MOOSEYARD_VERSIONDICTIONARY_
|