![]() |
Shadowrun: Awakened 29 September 2011 - Build 871
|
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.