00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef SVDHASH_H
00010 #define SVDHASH_H
00011
00012 #ifndef MEMORY_BASED
00013
00014
00015
00016 extern int cs_writes;
00017 extern int cs_reads;
00018 extern int cs_dels;
00019 extern int cs_fails;
00020 extern int cs_syncs;
00021 extern int cs_dbreads;
00022 extern int cs_dbwrites;
00023 extern int cs_rhits;
00024 extern int cs_whits;
00025 #endif // !MEMORY_BASED
00026
00027
00028
00029 #define SECTOR_SIZE 512
00030 #define LBUF_BLOCKED (SECTOR_SIZE*((LBUF_SIZE+SECTOR_SIZE-1)/SECTOR_SIZE))
00031 #define HT_SIZEOF_PAGE (1*LBUF_BLOCKED)
00032 #define HF_SIZEOF_PAGE (3*LBUF_BLOCKED)
00033
00034 extern UINT32 CRC32_ProcessBuffer
00035 (
00036 UINT32 ulCrc,
00037 const void *pBuffer,
00038 unsigned int nBuffer
00039 );
00040
00041 extern UINT32 CRC32_ProcessInteger(UINT32 nInteger);
00042 extern UINT32 CRC32_ProcessInteger2
00043 (
00044 UINT32 nInteger1,
00045 UINT32 nInteger2
00046 );
00047
00048 extern UINT32 HASH_ProcessBuffer
00049 (
00050 UINT32 ulHash,
00051 const void *arg_pBuffer,
00052 size_t nBuffer
00053 );
00054
00055 #if defined(_SGI_SOURCE) || ((UINT16_MAX_VALUE-2) <= HF_SIZEOF_PAGE)
00056 typedef UINT32 UINT_OFFSET;
00057 #define UINT_OFFSET_MAX_VALUE UINT32_MAX_VALUE
00058 #define EXPAND_TO_BOUNDARY(x) (((x) + 3) & (~3))
00059 #else
00060 typedef UINT16 UINT_OFFSET;
00061 #define UINT_OFFSET_MAX_VALUE UINT16_MAX_VALUE
00062 #define EXPAND_TO_BOUNDARY(x) (((x) + 1) & (~1))
00063 #endif
00064
00065 typedef UINT_OFFSET HP_HEAPOFFSET, *HP_PHEAPOFFSET;
00066 typedef UINT_OFFSET HP_HEAPLENGTH, *HP_PHEAPLENGTH;
00067 typedef UINT_OFFSET HP_DIRINDEX, *HP_PDIRINDEX;
00068
00069 #define HP_SIZEOF_HEAPOFFSET sizeof(HP_HEAPOFFSET)
00070 #define HP_SIZEOF_HEAPLENGTH sizeof(HP_HEAPLENGTH)
00071 #define HP_SIZEOF_DIRINDEX sizeof(HP_DIRINDEX);
00072
00073 #pragma pack(1)
00074 typedef struct tagHPHeader
00075 {
00076 UINT32 m_nTotalInsert;
00077 UINT32 m_nDirEmptyLeft;
00078 UINT32 m_nHashGroup;
00079 HP_DIRINDEX m_nDirSize;
00080 HP_DIRINDEX m_Primes[16];
00081 HP_HEAPOFFSET m_oFreeList;
00082 HP_DIRINDEX m_nDepth;
00083 } HP_HEADER, *HP_PHEADER;
00084
00085 #define HP_NIL_OFFSET UINT_OFFSET_MAX_VALUE
00086
00087
00088
00089 #define HP_DIR_EMPTY UINT_OFFSET_MAX_VALUE
00090 #define HP_DIR_DELETED (UINT_OFFSET_MAX_VALUE-1)
00091
00092 typedef struct tagHPTrailer
00093 {
00094 UINT32 m_checksum;
00095 } HP_TRAILER, *HP_PTRAILER;
00096
00097 typedef struct tagHPHeapNode
00098 {
00099 HP_HEAPLENGTH nBlockSize;
00100 union
00101 {
00102 HP_HEAPOFFSET oNext;
00103 struct
00104 {
00105 HP_HEAPLENGTH nRecordSize;
00106 UINT32 nHash;
00107 } s;
00108 } u;
00109 } HP_HEAPNODE, *HP_PHEAPNODE;
00110 #define HP_SIZEOF_HEAPNODE sizeof(HP_HEAPNODE)
00111 #pragma pack()
00112
00113 #define HP_MIN_HEAP_ALLOC HP_SIZEOF_HEAPNODE
00114
00115 typedef unsigned long HF_FILEOFFSET, *HF_PFILEOFFSET;
00116 #define HF_SIZEOF_FILEOFFSET sizeof(HF_FILEOFFSET)
00117
00118 class CHashPage
00119 {
00120 private:
00121 unsigned char *m_pPage;
00122 unsigned int m_nPageSize;
00123 HP_PHEADER m_pHeader;
00124 HP_PHEAPOFFSET m_pDirectory;
00125 unsigned char *m_pHeapStart;
00126 unsigned char *m_pHeapEnd;
00127 HP_PTRAILER m_pTrailer;
00128
00129 int m_iDir;
00130 int m_nProbesLeft;
00131 UINT32 m_nDirEmptyTrigger;
00132
00133 #ifdef HP_PROTECTION
00134 bool ValidateAllocatedBlock(UINT32 iDir);
00135 bool ValidateFreeBlock(HP_HEAPOFFSET oBlock);
00136 bool ValidateFreeList(void);
00137 #endif // HP_PROTECTION
00138 bool HeapAlloc(HP_DIRINDEX iDir, HP_HEAPLENGTH nRecord, UINT32 nHash, void *pRecord);
00139 void SetVariablePointers(void);
00140 void SetFixedPointers(void);
00141 void GetStats(HP_HEAPLENGTH nExtra, int *pnRecords, HP_HEAPLENGTH *pnAllocatedSize, int *pnGoodDirSize);
00142
00143 public:
00144 CHashPage(void);
00145 bool Allocate(unsigned int nPageSize);
00146 ~CHashPage(void);
00147 void Empty(HP_DIRINDEX arg_nDepth, UINT32 arg_nHashGroup, HP_DIRINDEX arg_nDirSize);
00148 #ifdef HP_PROTECTION
00149 void Protection(void);
00150 bool Validate(void);
00151 #endif // HP_PROTECTION
00152
00153 #define HP_INSERT_SUCCESS_DEFRAG 0
00154 #define HP_INSERT_SUCCESS 1
00155 #define HP_INSERT_ERROR_FULL 2
00156 #define HP_INSERT_ERROR_ILLEGAL 3
00157 #define IS_HP_SUCCESS(x) ((x) <= HP_INSERT_SUCCESS)
00158 int Insert(HP_HEAPLENGTH nRecord, UINT32 nHash, void *pRecord);
00159 HP_DIRINDEX FindFirstKey(UINT32 nHash, unsigned int *numchecks);
00160 HP_DIRINDEX FindNextKey(HP_DIRINDEX i, UINT32 nHash, unsigned int *numchecks);
00161 HP_DIRINDEX FindFirst(HP_PHEAPLENGTH pnRecord, void *pRecord);
00162 HP_DIRINDEX FindNext(HP_PHEAPLENGTH pnRecord, void *pRecord);
00163 void HeapCopy(HP_DIRINDEX iDir, HP_PHEAPLENGTH pnRecord, void *pRecord);
00164 void HeapFree(HP_DIRINDEX iDir);
00165 void HeapUpdate(HP_DIRINDEX iDir, HP_HEAPLENGTH nRecord, void *pRecord);
00166
00167 bool WritePage(HANDLE hFile, HF_FILEOFFSET oWhere);
00168 bool ReadPage(HANDLE hFile, HF_FILEOFFSET oWhere);
00169
00170 HP_DIRINDEX GetDepth(void);
00171 bool Split(CHashPage &hp0, CHashPage &hp1);
00172
00173 bool Defrag(HP_HEAPLENGTH nExtra);
00174 void GetRange(UINT32 arg_nDirDepth, UINT32 &nStart, UINT32 &nEnd);
00175 };
00176
00177
00178 #define HF_FIND_FIRST HP_DIR_EMPTY
00179 #define HF_FIND_END HP_DIR_EMPTY
00180
00181 #define HF_CACHE_EMPTY 0
00182 #define HF_CACHE_CLEAN 1
00183 #define HF_CACHE_UNPROTECTED 2
00184 #define HF_CACHE_UNWRITTEN 3
00185 #define HF_CACHE_NUM_STATES 4
00186
00187 typedef struct tagHashFileCache
00188 {
00189 CHashPage m_hp;
00190 HF_FILEOFFSET m_o;
00191 int m_iState;
00192 int m_iYounger;
00193 int m_iOlder;
00194 } HF_CACHE;
00195
00196 class CHashFile
00197 {
00198 private:
00199 HANDLE m_hDirFile;
00200 HANDLE m_hPageFile;
00201 int iCache;
00202 int m_iOldest;
00203 int m_iLastFlushed;
00204 int *m_hpCacheLookup;
00205 HF_FILEOFFSET oEndOfFile;
00206 unsigned int m_nDir;
00207 unsigned int m_nDirDepth;
00208 HF_CACHE *m_Cache;
00209 int m_nCache;
00210 HF_PFILEOFFSET m_pDir;
00211 bool DoubleDirectory(void);
00212
00213 int AllocateEmptyPage(int nSafe, int Safe[]);
00214 int ReadCache(UINT32 iFileDir, int *pHits);
00215 bool FlushCache(int iCache);
00216 void WriteDirectory(void);
00217 bool InitializeDirectory(unsigned int nSize);
00218 void ResetAge(int iEntry);
00219
00220 void Init(void);
00221 void InitCache(int nCachePages);
00222 void FinalCache(void);
00223
00224 bool CreateFileSet(const char *szDirFile, const char *szPageFile);
00225 bool RebuildDirectory(void);
00226 bool ReadDirectory(void);
00227
00228 public:
00229 CHashFile(void);
00230 #define HF_OPEN_STATUS_ERROR -1
00231 #define HF_OPEN_STATUS_NEW 0
00232 #define HF_OPEN_STATUS_OLD 1
00233 int Open(const char *szDirFile, const char *szPageFile, int nCachePages);
00234 bool Insert(HP_HEAPLENGTH nRecord, UINT32 nHash, void *pRecord);
00235 HP_DIRINDEX FindFirstKey(UINT32 nHash);
00236 HP_DIRINDEX FindNextKey(HP_DIRINDEX iDir, UINT32 nHash);
00237 void Copy(HP_DIRINDEX iDir, HP_PHEAPLENGTH pnRecord, void *pRecord);
00238 void Remove(HP_DIRINDEX iDir);
00239 void CloseAll(void);
00240 void Sync(void);
00241 void Tick(void);
00242 ~CHashFile(void);
00243 };
00244
00245 typedef CHashPage *pCHashPage;
00246
00247 class CHashTable
00248 {
00249 private:
00250 unsigned int m_nDir;
00251 unsigned int m_nDirDepth;
00252 pCHashPage *m_pDir;
00253 CHashPage *m_hpLast;
00254 unsigned int m_iPage;
00255
00256 unsigned int m_nPages;
00257 unsigned int m_nEntries;
00258 INT64 m_nDeletions;
00259 INT64 m_nScans;
00260 INT64 m_nHits;
00261 INT64 m_nChecks;
00262 unsigned int m_nMaxScan;
00263
00264 bool DoubleDirectory(void);
00265
00266 void Init(void);
00267 void Final(void);
00268
00269 public:
00270 CHashTable(void);
00271 void ResetStats(void);
00272 void GetStats( unsigned int *hashsize, int *entries, INT64 *deletes,
00273 INT64 *scans, INT64 *hits, INT64 *checks, int *max_scan);
00274 INT64 GetEntryCount();
00275
00276 void Reset(void);
00277 bool Insert(HP_HEAPLENGTH nRecord, UINT32 nHash, void *pRecord);
00278 HP_DIRINDEX FindFirstKey(UINT32 nHash);
00279 HP_DIRINDEX FindNextKey(HP_DIRINDEX iDir, UINT32 nHash);
00280 HP_DIRINDEX FindFirst(HP_PHEAPLENGTH pnRecord, void *pRecord);
00281 HP_DIRINDEX FindNext(HP_PHEAPLENGTH pnRecord, void *pRecord);
00282 void Copy(HP_DIRINDEX iDir, HP_PHEAPLENGTH pnRecord, void *pRecord);
00283 void Remove(HP_DIRINDEX iDir);
00284 void Update(HP_DIRINDEX iDir, HP_HEAPLENGTH nRecord, void *pRecord);
00285 ~CHashTable(void);
00286 };
00287
00288
00289 #define SIZEOF_LOG_BUFFER 1024
00290 class CLogFile
00291 {
00292 private:
00293 CLinearTimeAbsolute m_ltaStarted;
00294 #ifdef WIN32
00295 CRITICAL_SECTION csLog;
00296 #endif // WIN32
00297 HANDLE m_hFile;
00298 size_t m_nSize;
00299 size_t m_nBuffer;
00300 char m_aBuffer[SIZEOF_LOG_BUFFER];
00301 bool bEnabled;
00302 bool bUseStderr;
00303 char *m_pBasename;
00304 char m_szPrefix[32];
00305 char m_szFilename[SIZEOF_PATHNAME];
00306
00307 void CreateLogFile(void);
00308 void AppendLogFile(void);
00309 void CloseLogFile(void);
00310 public:
00311 CLogFile(void);
00312 ~CLogFile(void);
00313 void WriteBuffer(size_t nString, const char *pString);
00314 void WriteString(const char *pString);
00315 void WriteInteger(int iNumber);
00316 void DCL_CDECL tinyprintf(char *pFormatSpec, ...);
00317 void Flush(void);
00318 void SetPrefix(const char *pPrefix);
00319 void SetBasename(const char *pBasename);
00320 void StartLogging(void);
00321 void StopLogging(void);
00322 };
00323
00324 extern CLogFile Log;
00325
00326 #endif
00327