include/VersionDictionary.h
changeset 0 31a43d94cc26
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/include/VersionDictionary.h	Sun Sep 20 15:14:12 2009 -0700
     1.3 @@ -0,0 +1,127 @@
     1.4 +/*
     1.5 + *  VersionDictionary.h
     1.6 + *  Ottoman
     1.7 + *
     1.8 + *  Created by Jens Alfke on 8/21/09.
     1.9 + *  Copyright 2009 Jens Alfke. All rights reserved.
    1.10 + *  BSD-Licensed: See the file "LICENSE.txt" for details.
    1.11 + */
    1.12 +
    1.13 +#ifndef _MOOSEYARD_VERSIONDICTIONARY_
    1.14 +#define _MOOSEYARD_VERSIONDICTIONARY_
    1.15 +#include "Dictionary.h"
    1.16 +
    1.17 +namespace Mooseyard {
    1.18 +    
    1.19 +    class File;
    1.20 +    class Index;
    1.21 +    
    1.22 +    /** A persistent Dictionary embedded in a memory-mapped file, 
    1.23 +        representing one complete version of an Ottoman dictionary. */
    1.24 +    class VersionDictionary :public Dictionary {
    1.25 +    public:
    1.26 +        
    1.27 +        /** The generation number. The first version in a new file is zero. */
    1.28 +        int generation() const;
    1.29 +        
    1.30 +        /** The absolute time at which this version was written to the file. */
    1.31 +        time_t timestamp() const;
    1.32 +        
    1.33 +        /** The previous version, before this one was saved. */
    1.34 +        const VersionDictionary* previousVersion() const;
    1.35 +        
    1.36 +        /** Is this the latest version in the file? */
    1.37 +        bool isLatestVersion() const;
    1.38 +        
    1.39 +        virtual int count() const;
    1.40 +        virtual Blob get (Key) const;
    1.41 +        class Iterator;
    1.42 +        virtual Dictionary::Iterator* iterate() const;
    1.43 +        
    1.44 +        class ChangeIterator;
    1.45 +        /** Iterates over the changes between this dictionary and the previous version. */
    1.46 +        virtual ChangeIterator* iterateChanges() const;
    1.47 +
    1.48 +        
    1.49 +        // Stuff you probably won't need to use:
    1.50 +        
    1.51 +        File* file() const                                          {return _file;}
    1.52 +        explicit VersionDictionary (File*);
    1.53 +        VersionDictionary (File *file, FilePosition trailerPosition);
    1.54 +        
    1.55 +    private:
    1.56 +        /** The type of the trailer chunk that's used as the position of the dictionary. */
    1.57 +        static const uint16_t kChunkType = 3;
    1.58 +        
    1.59 +        struct IndexPositions {
    1.60 +            LittleEndian<FilePosition> position[256];
    1.61 +            LittleEndian<FilePosition>& operator[] (int i)              {return position[i];}
    1.62 +            LittleEndian<FilePosition> const& operator[] (int i) const  {return position[i];}
    1.63 +        };
    1.64 +                
    1.65 +        class Trailer;
    1.66 +        const Trailer* _trailer() const;
    1.67 +        const Index* _index (int i) const;
    1.68 +        void _read (FilePosition trailerPosition =0);
    1.69 +        static FilePosition _append (const VersionDictionary *baseDict, 
    1.70 +                                     const Dictionary *addDict, 
    1.71 +                                     File *dstFile, 
    1.72 +                                     bool replace);
    1.73 +        
    1.74 +        File *_file;
    1.75 +        FilePosition _trailerPosition, _previousTrailerPosition;
    1.76 +        IndexPositions _indexPositions;
    1.77 +        int _count;
    1.78 +        mutable const VersionDictionary *_previousVersion;
    1.79 +        
    1.80 +#if VERSIONDICTIONARY_TESTING
    1.81 +    public:
    1.82 +#endif
    1.83 +        static VersionDictionary* create (File *file, const Dictionary *srcDict);
    1.84 +        VersionDictionary* byAppending (const Dictionary* d) const     {return _appendAndOpen(d,_file,false);}
    1.85 +        VersionDictionary* byReplacing (const Dictionary* d) const     {return _appendAndOpen(d,_file,true);}
    1.86 +        VersionDictionary* _appendAndOpen (const Dictionary *addDict, File *dstFile, bool replace) const;
    1.87 +        
    1.88 +        friend class Ottoman;
    1.89 +        UNCOPYABLE(VersionDictionary);
    1.90 +    };
    1.91 +    
    1.92 +    
    1.93 +    class VersionDictionary::Iterator :public Dictionary::Iterator {
    1.94 +    public:
    1.95 +        explicit Iterator (const VersionDictionary*);
    1.96 +        virtual ~Iterator();
    1.97 +        virtual Key key() const;
    1.98 +        virtual Blob value() const;
    1.99 +        virtual bool next();
   1.100 +        virtual bool hasValue() const;
   1.101 +    private:
   1.102 +        bool nextIndex();
   1.103 +        
   1.104 +        const VersionDictionary *_file;
   1.105 +        int _bucket;
   1.106 +        Dictionary::Iterator *_iter;
   1.107 +        UNCOPYABLE(Iterator);
   1.108 +    };
   1.109 +    
   1.110 +    
   1.111 +    class VersionDictionary::ChangeIterator :public Dictionary::Iterator {
   1.112 +    public:
   1.113 +        explicit ChangeIterator (const VersionDictionary*);
   1.114 +        virtual ~ChangeIterator();
   1.115 +        virtual Key key() const;
   1.116 +        virtual Blob value() const;
   1.117 +        virtual bool next();
   1.118 +        virtual bool hasValue() const;
   1.119 +    private:
   1.120 +        bool nextIndex();
   1.121 +        
   1.122 +        const VersionDictionary *_file;
   1.123 +        int _bucket;
   1.124 +        Dictionary::Iterator *_iter;
   1.125 +        UNCOPYABLE(ChangeIterator);
   1.126 +    };
   1.127 +
   1.128 +}
   1.129 +
   1.130 +#endif //_MOOSEYARD_VERSIONDICTIONARY_