Shadowrun: Awakened 29 September 2011 - Build 871
BombayTable.hpp
Go to the documentation of this file.
00001 /*
00002     Copyright (c) 2009-2010 Christopher A. Taylor.  All rights reserved.
00003 
00004     Redistribution and use in source and binary forms, with or without
00005     modification, are permitted provided that the following conditions are met:
00006 
00007     * Redistributions of source code must retain the above copyright notice,
00008       this list of conditions and the following disclaimer.
00009     * Redistributions in binary form must reproduce the above copyright notice,
00010       this list of conditions and the following disclaimer in the documentation
00011       and/or other materials provided with the distribution.
00012     * Neither the name of LibCat nor the names of its contributors may be used
00013       to endorse or promote products derived from this software without
00014       specific prior written permission.
00015 
00016     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00017     AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00018     IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00019     ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
00020     LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00021     CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00022     SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00023     INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00024     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00025     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00026     POSSIBILITY OF SUCH DAMAGE.
00027 */
00028 
00029 #ifndef CAT_BOMBAY_TABLE_HPP
00030 #define CAT_BOMBAY_TABLE_HPP
00031 
00032 #include <cat/threads/RWLock.hpp>
00033 #include <cat/io/ThreadPoolFiles.hpp>
00034 #include <cat/db/BombayTableIndex.hpp>
00035 
00036 namespace cat {
00037 
00038 namespace bombay {
00039 
00040 
00041 static u64 INVALID_RECORD_OFFSET = ~(u64)0;
00042 
00043 struct CacheNode
00044 {
00045     CacheNode *parent, *lower, *higher;
00046     u64 offset;
00047 };
00048 
00049 class TableIndex;
00050 class IHash;
00051 
00052 
00053 // Query() AsyncBuffer tag must derive from AsyncQueryRead
00054 struct AsyncQueryRead
00055 {
00056     ThreadRefObject *_reference;
00057     AsyncCallback _callback;
00058 
00059     CAT_INLINE void SetCallback(AsyncCallback callback = 0, ThreadRefObject *reference = 0)
00060     {
00061         if (reference)
00062             reference->AddRef();
00063 
00064         _callback = callback;
00065         _reference = reference;
00066     }
00067 };
00068 
00069 
00071 
00072 class Table : public AsyncFile
00073 {
00074     ShutdownObserver *_shutdown_observer;
00075     u32 _record_bytes; // Bytes per record (without CacheNode overhead)
00076     u64 _next_record; // Next record offset
00077 
00078 protected:
00079     RWLock _lock;
00080 
00081     u64 _index_database_size, _index_read_offset, _index_read_completed;
00082     u32 _index_read_size;
00083     static const u32 MAX_INDEX_READ_SIZE = 32768;
00084     static const int NUM_PARALLEL_INDEX_READS = 3;
00085 
00086     // Cache hash table of binary trees
00087     static const u32 TARGET_TREE_SIZE = 16;
00088     static const u32 MIN_TABLE_SIZE = 2048;
00089 
00090     u32 _hash_table_size;
00091     CacheNode **_cache_hash_table;
00092 
00093     u8 *_cache; // Cache memory
00094     u32 _cache_bytes; // Cache bytes
00095     u32 _next_cache_slot; // Offset in cache memory to next free slot
00096     bool _cache_full; // Cache full flag for optimization
00097 
00098     TableIndex *_head_index, *_head_index_unique;
00099     TableIndex *_head_index_waiting, *_head_index_update;
00100 
00101     bool AllocateCache();
00102     void FreeCache();
00103 
00104     // Node versions
00105     CacheNode *FindNode(u64 offset);
00106     void UnlinkNode(CacheNode *node);
00107     void InsertNode(u64 offset, u32 key, CacheNode *hint, CacheNode *node);
00108 
00109     // Always returns with a cache node; may re-use an old cache node
00110     u8 *SetOffset(u64 offset);
00111     u8 *InsertOffset(u64 offset);
00112     u8 *PeekOffset(u64 offset);
00113     bool RemoveOffset(u64 offset);
00114 
00115 public:
00116     Table(const char *file_path, u32 record_bytes, u32 cache_bytes, ShutdownObserver *shutdown_observer);
00117     virtual ~Table();
00118 
00119 private:
00120     TableIndex *MakeIndex(const char *index_file_path, IHash *hash_function, bool unique);
00121     u64 UniqueIndexLookup(const void *data);
00122 
00123 public:
00124     // To initialize, run MakeIndex() for all of the desired indexing routines,
00125     // and then run Initialize(), which will initialize index objects.
00126     template<class THashFunc> CAT_INLINE TableIndex *MakeIndex(const char *index_file_path, bool unique)
00127     {
00128         return MakeIndex(index_file_path, new THashFunc, unique);
00129     }
00130 
00131     bool Initialize();
00132 
00133 public:
00134     CAT_INLINE u32 GetCacheBytes() { return _cache_bytes; }
00135     CAT_INLINE u32 GetRecordBytes() { return _record_bytes; }
00136 
00137 protected:
00138     virtual bool OnRemoveRead(ThreadPoolLocalStorage *tls, int error, AsyncBuffer *buffer, u32 bytes);
00139     virtual bool OnQueryRead(ThreadPoolLocalStorage *tls, int error, AsyncBuffer *buffer, u32 bytes);
00140 
00141 protected:
00142     bool StartIndexing();
00143     bool StartIndexingRead();
00144     void OnIndexingDone();
00145 
00146     virtual bool OnIndexingRead(ThreadPoolLocalStorage *tls, int error, AsyncBuffer *buffer, u32 bytes);
00147 
00148 public:
00149     bool RequestIndexRebuild(TableIndex *index);
00150 
00151 public:
00152     // Insert an AsyncBuffer data buffer
00153     u64 Insert(void *data);
00154 
00155     // Update with an AsyncBuffer data buffer
00156     bool Update(void *data, u64 offset);
00157 
00158     // Query with an AsyncBuffer
00159     // NOTE: Query() AsyncBuffer tag must derive from AsyncQueryRead
00160     bool Query(u64 offset, AsyncBuffer *buffer);
00161 
00162     // Remove based on offset
00163     bool Remove(u64 offset);
00164 };
00165 
00166 
00167 } // namespace bombay
00168 
00169 } // namespace cat
00170 
00171 #endif // CAT_BOMBAY_TABLE_HPP

Copyright © 2007-2010 by The Shadowrun: Awakened Team. This work is licensed under the GNU Lesser General Public License 3.

GNU Lesser General Public License 3 Sourceforge.net