include/VersionDictionary.h
author Jens Alfke <jens@mooseyard.com>
Sun Sep 20 15:14:12 2009 -0700 (2009-09-20)
changeset 0 31a43d94cc26
permissions -rw-r--r--
First official checkin.
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_