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