jens@0: /*
jens@0:  *  Index.h
jens@0:  *  Ottoman
jens@0:  *
jens@0:  *  Created by Jens Alfke on 8/27/09.
jens@0:  *  Copyright 2009 Jens Alfke. All rights reserved.
jens@0:  *  BSD-Licensed: See the file "LICENSE.txt" for details.
jens@0:  */
jens@0: 
jens@0: #ifndef _MOOSEYARD_INDEX_
jens@0: #define _MOOSEYARD_INDEX_
jens@0: #include "Chunk.h"
jens@0: #include "Dictionary.h"
jens@0: 
jens@0: namespace Mooseyard {
jens@0:     
jens@0:     class KeyValueChunk;
jens@0:     
jens@0:     /** An in-file hash table. This structure is stored directly in the file, memory-mapped.
jens@0:         Index is normally only used internally by VersionDictionary. */
jens@0:     class Index :public Chunk {
jens@0:     public:
jens@0:         
jens@0:         class Entry;
jens@0:         
jens@0:         static const Index* indexMappedAt (const void*);
jens@0:         static Index* create (int capacity);
jens@0:         
jens@0:         int count() const                                   {return _count;}
jens@0:         
jens@0:         Blob get (File *file, Key) const;
jens@0:         bool put (File *file, Key, FilePosition valuePosition, FilePosition maxPosition);
jens@0:         bool remove (File *file, Key, FilePosition maxPosition);
jens@0:         void removeAll();
jens@0:         
jens@0:         void copyFrom (File *file, const Index *index);
jens@0:         
jens@0:         class Iterator;
jens@0:         
jens@0:         void validate() const  throw(File::Error);
jens@0:         void validateEntries (const File *file) const  throw(File::Error);
jens@0:         static const uint16_t kChunkType = 2;
jens@0:         
jens@0:     private:
jens@0:         Index (uint32_t tableSize);
jens@0:         const Entry* table (int index) const;
jens@0:         Entry* table (int index);
jens@0:         const KeyValueChunk* _find (File *file, Key) const;
jens@0:         bool _put (File *file, Key, FilePosition, FilePosition maxPosition);
jens@0: 
jens@0:         // This is mapped to data in the file! Don't mess with it!
jens@0:         LittleEndian<uint32_t>  _magicNumber;
jens@0:         LittleEndian<uint32_t>  _count;
jens@0:         LittleEndian<uint32_t>  _tableSize;
jens@0:         char                    _table[0];      // Actually Entry[]
jens@0:     };
jens@0:   
jens@0:     
jens@0:     
jens@0:     class Index::Iterator :public Dictionary::Iterator {
jens@0:     public:
jens@0:         Iterator (File*, const Index*);
jens@0:         virtual Key key() const;
jens@0:         virtual Blob value() const;
jens@0:         virtual bool next();
jens@0:         virtual bool hasValue() const;
jens@0:         
jens@0:         FilePosition valuePosition();
jens@0:     private:
jens@0:         File* const _file;
jens@0:         const Index::Entry *_current, *_end;
jens@0:     };
jens@0:     
jens@0: }
jens@0: 
jens@0: #endif //_MOOSEYARD_INDEX_