mux/src/attrcache.cpp File Reference

#include "copyright.h"
#include "autoconf.h"
#include "config.h"
#include "externs.h"

Include dependency graph for attrcache.cpp:

Go to the source code of this file.

Data Structures

struct  tagAttrRecord
struct  tagCacheEntryHeader

Defines

#define N_TEMP_FILES   8

Typedefs

typedef tagAttrRecord ATTR_RECORD
typedef tagAttrRecordPATTR_RECORD
typedef tagCacheEntryHeader CENT_HDR
typedef tagCacheEntryHeaderPCENT_HDR

Functions

int cache_init (const char *game_dir_file, const char *game_pag_file, int nCachePages)
void cache_redirect (void)
void cache_pass2 (void)
void cache_close (void)
void cache_tick (void)
static void REMOVE_ENTRY (PCENT_HDR pEntry)
static void ADD_ENTRY (PCENT_HDR pEntry)
static void TrimCache (void)
const char * cache_get (Aname *nam, int *pLen)
bool cache_put (Aname *nam, const char *value, size_t len)
bool cache_sync (void)
void cache_del (Aname *nam)

Variables

static CHashFile hfAttributeFile
static bool cache_initted = false
static bool cache_redirected = false
static FILE * TempFiles [N_TEMP_FILES]
CLinearTimeAbsolute cs_ltime
static ATTR_RECORD TempRecord
static PCENT_HDR pCacheHead = 0
static PCENT_HDR pCacheTail = 0
static unsigned int CacheSize = 0


Define Documentation

#define N_TEMP_FILES   8

Definition at line 18 of file attrcache.cpp.

Referenced by cache_pass2(), cache_put(), and cache_redirect().


Typedef Documentation

typedef struct tagAttrRecord ATTR_RECORD

typedef struct tagCacheEntryHeader CENT_HDR

typedef struct tagAttrRecord * PATTR_RECORD

typedef struct tagCacheEntryHeader * PCENT_HDR


Function Documentation

static void ADD_ENTRY ( PCENT_HDR  pEntry  )  [static]

Definition at line 182 of file attrcache.cpp.

References pCacheHead, pCacheTail, tagCacheEntryHeader::pNextEntry, and tagCacheEntryHeader::pPrevEntry.

Referenced by cache_get(), and cache_put().

00183 {
00184     if (pCacheHead)
00185     {
00186         pCacheHead->pPrevEntry = pEntry;
00187     }
00188     pEntry->pNextEntry = pCacheHead;
00189     pEntry->pPrevEntry = 0;
00190     pCacheHead = pEntry;
00191     if (!pCacheTail)
00192     {
00193         pCacheTail = pCacheHead;
00194     }
00195 }

void cache_close ( void   ) 

Definition at line 115 of file attrcache.cpp.

References cache_initted, CHashFile::CloseAll(), and hfAttributeFile.

00116 {
00117     hfAttributeFile.CloseAll();
00118     cache_initted = false;
00119 }

void cache_del ( Aname nam  ) 

Definition at line 432 of file attrcache.cpp.

References statedata::acache_htab, tagAttrRecord::attrKey, Aname::attrnum, statedata::bStandAlone, cache_initted, CacheSize, CHashFile::Copy(), CRC32_ProcessInteger2(), ENDLINE, CHashFile::FindFirstKey(), CHashFile::FindNextKey(), hashdeleteLEN(), hashfindLEN(), HF_FIND_END, hfAttributeFile, Log, MEMFREE, mudstate, Aname::object, CHashFile::Remove(), REMOVE_ENTRY(), TempRecord, CLogFile::tinyprintf(), and statedata::write_protect.

Referenced by atr_clr().

00433 {
00434     if (  !nam
00435        || !cache_initted)
00436     {
00437         return;
00438     }
00439 
00440 #ifndef WIN32
00441     if (mudstate.write_protect)
00442     {
00443         Log.tinyprintf("cache_del((%d,%d)) while database is write-protected" ENDLINE,
00444             nam->object, nam->attrnum);
00445         return;
00446     }
00447 #endif
00448 
00449     UINT32 nHash = CRC32_ProcessInteger2(nam->object, nam->attrnum);
00450 
00451     HP_DIRINDEX iDir = hfAttributeFile.FindFirstKey(nHash);
00452     while (iDir != HF_FIND_END)
00453     {
00454         HP_HEAPLENGTH nRecord;
00455         hfAttributeFile.Copy(iDir, &nRecord, &TempRecord);
00456 
00457         if (  TempRecord.attrKey.attrnum == nam->attrnum
00458            && TempRecord.attrKey.object == nam->object)
00459         {
00460             hfAttributeFile.Remove(iDir);
00461         }
00462         iDir = hfAttributeFile.FindNextKey(iDir, nHash);
00463     }
00464 
00465     if (!mudstate.bStandAlone)
00466     {
00467         // Update cache.
00468         //
00469         PCENT_HDR pCacheEntry = (PCENT_HDR)hashfindLEN(nam, sizeof(Aname),
00470             &mudstate.acache_htab);
00471         if (pCacheEntry)
00472         {
00473             // It was in the cache, so delete it.
00474             //
00475             REMOVE_ENTRY(pCacheEntry);
00476             CacheSize -= pCacheEntry->nSize;;
00477             hashdeleteLEN((char *)nam, sizeof(Aname), &mudstate.acache_htab);
00478             MEMFREE(pCacheEntry);
00479             pCacheEntry = NULL;
00480         }
00481     }
00482 }

const char* cache_get ( Aname nam,
int *  pLen 
)

Definition at line 221 of file attrcache.cpp.

References statedata::acache_htab, ADD_ENTRY(), tagAttrRecord::attrKey, tagCacheEntryHeader::attrKey, Aname::attrnum, tagAttrRecord::attrText, statedata::bStandAlone, cache_initted, CacheSize, CHashFile::Copy(), CRC32_ProcessInteger2(), CHashFile::FindFirstKey(), CHashFile::FindNextKey(), hashaddLEN(), hashfindLEN(), HF_FIND_END, hfAttributeFile, MEMALLOC, mudstate, tagCacheEntryHeader::nSize, Aname::object, REMOVE_ENTRY(), TempRecord, and TrimCache().

Referenced by atr_get_raw_LEN().

00222 {
00223     if (  nam == (Aname *) 0
00224        || !cache_initted)
00225     {
00226         *pLen = 0;
00227         return NULL;
00228     }
00229 
00230     PCENT_HDR pCacheEntry = NULL;
00231     if (!mudstate.bStandAlone)
00232     {
00233         // Check the cache, first.
00234         //
00235         pCacheEntry = (PCENT_HDR)hashfindLEN(nam, sizeof(Aname),
00236             &mudstate.acache_htab);
00237         if (pCacheEntry)
00238         {
00239             // It was in the cache, so move this entry to the head of the queue.
00240             // and return a pointer to it.
00241             //
00242             REMOVE_ENTRY(pCacheEntry);
00243             ADD_ENTRY(pCacheEntry);
00244             if (sizeof(CENT_HDR) < pCacheEntry->nSize)
00245             {
00246                 *pLen = pCacheEntry->nSize - sizeof(CENT_HDR);
00247                 return (char *)(pCacheEntry+1);
00248             }
00249             else
00250             {
00251                 *pLen = 0;
00252                 return NULL;
00253             }
00254         }
00255     }
00256 
00257     UINT32 nHash = CRC32_ProcessInteger2(nam->object, nam->attrnum);
00258 
00259     HP_DIRINDEX iDir;
00260     iDir = hfAttributeFile.FindFirstKey(nHash);
00261     while (iDir != HF_FIND_END)
00262     {
00263         HP_HEAPLENGTH nRecord;
00264         hfAttributeFile.Copy(iDir, &nRecord, &TempRecord);
00265 
00266         if (  TempRecord.attrKey.attrnum == nam->attrnum
00267            && TempRecord.attrKey.object == nam->object)
00268         {
00269             int nLength = nRecord - sizeof(Aname);
00270             *pLen = nLength;
00271             if (!mudstate.bStandAlone)
00272             {
00273                 // Add this information to the cache.
00274                 //
00275                 pCacheEntry = (PCENT_HDR)MEMALLOC(sizeof(CENT_HDR)+nLength);
00276                 if (pCacheEntry)
00277                 {
00278                     pCacheEntry->attrKey = *nam;
00279                     pCacheEntry->nSize = nLength + sizeof(CENT_HDR);
00280                     CacheSize += pCacheEntry->nSize;
00281                     memcpy((char *)(pCacheEntry+1), TempRecord.attrText, nLength);
00282                     ADD_ENTRY(pCacheEntry);
00283                     hashaddLEN(nam, sizeof(Aname), pCacheEntry,
00284                         &mudstate.acache_htab);
00285 
00286                     TrimCache();
00287                 }
00288             }
00289             return TempRecord.attrText;
00290         }
00291         iDir = hfAttributeFile.FindNextKey(iDir, nHash);
00292     }
00293 
00294     // We didn't find that one.
00295     //
00296     if (!mudstate.bStandAlone)
00297     {
00298         // Add this information to the cache.
00299         //
00300         pCacheEntry = (PCENT_HDR)MEMALLOC(sizeof(CENT_HDR));
00301         if (pCacheEntry)
00302         {
00303             pCacheEntry->attrKey = *nam;
00304             pCacheEntry->nSize = sizeof(CENT_HDR);
00305             CacheSize += pCacheEntry->nSize;
00306             ADD_ENTRY(pCacheEntry);
00307             hashaddLEN(nam, sizeof(Aname), pCacheEntry,
00308                 &mudstate.acache_htab);
00309 
00310             TrimCache();
00311         }
00312     }
00313 
00314     *pLen = 0;
00315     return NULL;
00316 }

int cache_init ( const char *  game_dir_file,
const char *  game_pag_file,
int  nCachePages 
)

Definition at line 45 of file attrcache.cpp.

References cache_initted, cs_ltime, CLinearTimeAbsolute::GetUTC(), HF_OPEN_STATUS_ERROR, hfAttributeFile, and CHashFile::Open().

Referenced by init_dbfile().

00047 {
00048     if (cache_initted)
00049     {
00050         return HF_OPEN_STATUS_ERROR;
00051     }
00052 
00053     int cc = hfAttributeFile.Open(game_dir_file, game_pag_file, nCachePages);
00054     if (cc != HF_OPEN_STATUS_ERROR)
00055     {
00056         // Mark caching system live
00057         //
00058         cache_initted = true;
00059         cs_ltime.GetUTC();
00060     }
00061     return cc;
00062 }

void cache_pass2 ( void   ) 

Definition at line 77 of file attrcache.cpp.

References tagAttrRecord::attrKey, tagAttrRecord::attrText, cache_put(), cache_redirected, cnt, ENDLINE, mux_assert, N_TEMP_FILES, tagCacheEntryHeader::nSize, RemoveFile(), and TempFiles.

Referenced by dbconvert().

00078 {
00079     ATTR_RECORD Record;
00080     cache_redirected = false;
00081     fprintf(stderr, "2nd Pass:\n");
00082     for (int i = 0; i < N_TEMP_FILES; i++)
00083     {
00084         fprintf(stderr, "File %d: ", i);
00085         long int li = fseek(TempFiles[i], 0, SEEK_SET);
00086         mux_assert(0L == li);
00087 
00088         int cnt = 1000;
00089         size_t nSize;
00090         for (;;)
00091         {
00092             size_t cc = fread(&nSize, 1, sizeof(nSize), TempFiles[i]);
00093             if (cc != sizeof(nSize))
00094             {
00095                 break;
00096             }
00097             cc = fread(&Record, 1, nSize, TempFiles[i]);
00098             mux_assert(cc == nSize);
00099             cache_put(&Record.attrKey, Record.attrText, nSize - sizeof(Aname));
00100             if (cnt-- == 0)
00101             {
00102                 fputc('.', stderr);
00103                 fflush(stderr);
00104                 cnt = 1000;
00105             }
00106         }
00107         fclose(TempFiles[i]);
00108         char TempFileName[20];
00109         sprintf(TempFileName, "$convtemp.%d", i);
00110         RemoveFile(TempFileName);
00111         fprintf(stderr, ENDLINE);
00112     }
00113 }

bool cache_put ( Aname nam,
const char *  value,
size_t  len 
)

Definition at line 321 of file attrcache.cpp.

References statedata::acache_htab, ADD_ENTRY(), tagAttrRecord::attrKey, tagCacheEntryHeader::attrKey, Aname::attrnum, tagAttrRecord::attrText, statedata::bStandAlone, cache_initted, cache_redirected, CacheSize, CHashFile::Copy(), CRC32_ProcessInteger2(), ENDLINE, CHashFile::FindFirstKey(), CHashFile::FindNextKey(), hashaddLEN(), hashdeleteLEN(), hashfindLEN(), HF_FIND_END, hfAttributeFile, CHashFile::Insert(), Log, MEMALLOC, MEMFREE, mudstate, N_TEMP_FILES, tagCacheEntryHeader::nSize, Aname::object, CHashFile::Remove(), REMOVE_ENTRY(), TempFiles, TempRecord, CLogFile::tinyprintf(), TrimCache(), and statedata::write_protect.

Referenced by atr_add_raw_LEN(), and cache_pass2().

00322 {
00323     if (  !value
00324        || !nam
00325        || !cache_initted
00326        || len == 0)
00327     {
00328         return false;
00329     }
00330 #ifndef WIN32
00331     if (mudstate.write_protect)
00332     {
00333         Log.tinyprintf("cache_put((%d,%d), '%s', %u) while database is write-protected" ENDLINE,
00334             nam->object, nam->attrnum, value, len);
00335         return false;
00336     }
00337 #endif
00338 
00339     if (len > sizeof(TempRecord.attrText))
00340     {
00341         len = sizeof(TempRecord.attrText);
00342     }
00343 
00344     // Removal from DB.
00345     //
00346     UINT32 nHash = CRC32_ProcessInteger2(nam->object, nam->attrnum);
00347 
00348     if (cache_redirected)
00349     {
00350         TempRecord.attrKey = *nam;
00351         memcpy(TempRecord.attrText, value, len);
00352         TempRecord.attrText[len-1] = '\0';
00353 
00354         int iFile = (N_TEMP_FILES-1) & (nHash >> 29);
00355         size_t nSize = len+sizeof(Aname);
00356         fwrite(&nSize, 1, sizeof(nSize), TempFiles[iFile]);
00357         fwrite(&TempRecord, 1, nSize, TempFiles[iFile]);
00358         return true;
00359     }
00360 
00361     HP_DIRINDEX iDir = hfAttributeFile.FindFirstKey(nHash);
00362     while (iDir != HF_FIND_END)
00363     {
00364         HP_HEAPLENGTH nRecord;
00365         hfAttributeFile.Copy(iDir, &nRecord, &TempRecord);
00366 
00367         if (  TempRecord.attrKey.attrnum == nam->attrnum
00368            && TempRecord.attrKey.object  == nam->object)
00369         {
00370             hfAttributeFile.Remove(iDir);
00371         }
00372         iDir = hfAttributeFile.FindNextKey(iDir, nHash);
00373     }
00374 
00375     TempRecord.attrKey = *nam;
00376     memcpy(TempRecord.attrText, value, len);
00377     TempRecord.attrText[len-1] = '\0';
00378 
00379     // Insertion into DB.
00380     //
00381     if (!hfAttributeFile.Insert((HP_HEAPLENGTH)(len+sizeof(Aname)), nHash, &TempRecord))
00382     {
00383         Log.tinyprintf("cache_put((%d,%d), '%s', %u) failed" ENDLINE,
00384             nam->object, nam->attrnum, value, len);
00385     }
00386 
00387     if (!mudstate.bStandAlone)
00388     {
00389         // Update cache.
00390         //
00391         PCENT_HDR pCacheEntry = (PCENT_HDR)hashfindLEN(nam, sizeof(Aname),
00392             &mudstate.acache_htab);
00393         if (pCacheEntry)
00394         {
00395             // It was in the cache, so delete it.
00396             //
00397             REMOVE_ENTRY(pCacheEntry);
00398             CacheSize -= pCacheEntry->nSize;
00399             hashdeleteLEN((char *)nam, sizeof(Aname), &mudstate.acache_htab);
00400             MEMFREE(pCacheEntry);
00401             pCacheEntry = NULL;
00402         }
00403 
00404         // Add information about the new entry back into the cache.
00405         //
00406         size_t nSizeOfEntry = sizeof(CENT_HDR) + len;
00407         pCacheEntry = (PCENT_HDR)MEMALLOC(nSizeOfEntry);
00408         if (pCacheEntry)
00409         {
00410             pCacheEntry->attrKey = *nam;
00411             pCacheEntry->nSize = nSizeOfEntry;
00412             CacheSize += pCacheEntry->nSize;
00413             memcpy((char *)(pCacheEntry+1), TempRecord.attrText, len);
00414             ADD_ENTRY(pCacheEntry);
00415             hashaddLEN(nam, sizeof(Aname), pCacheEntry,
00416                 &mudstate.acache_htab);
00417 
00418             TrimCache();
00419         }
00420     }
00421     return true;
00422 }

void cache_redirect ( void   ) 

Definition at line 64 of file attrcache.cpp.

References cache_redirected, mux_assert, N_TEMP_FILES, and TempFiles.

Referenced by dbconvert().

00065 {
00066     for (int i = 0; i < N_TEMP_FILES; i++)
00067     {
00068         char TempFileName[20];
00069         sprintf(TempFileName, "$convtemp.%d", i);
00070         TempFiles[i] = fopen(TempFileName, "wb+");
00071         mux_assert(TempFiles[i]);
00072         setvbuf(TempFiles[i], NULL, _IOFBF, 16384);
00073     }
00074     cache_redirected = true;
00075 }

bool cache_sync ( void   ) 

Definition at line 424 of file attrcache.cpp.

References hfAttributeFile, and CHashFile::Sync().

00425 {
00426     hfAttributeFile.Sync();
00427     return true;
00428 }

void cache_tick ( void   ) 

Definition at line 121 of file attrcache.cpp.

References hfAttributeFile, and CHashFile::Tick().

Referenced by dispatch_CacheTick().

00122 {
00123     hfAttributeFile.Tick();
00124 }

static void REMOVE_ENTRY ( PCENT_HDR  pEntry  )  [static]

Definition at line 126 of file attrcache.cpp.

References pCacheHead, pCacheTail, tagCacheEntryHeader::pNextEntry, and tagCacheEntryHeader::pPrevEntry.

Referenced by cache_del(), cache_get(), cache_put(), and TrimCache().

00127 {
00128     // How is X positioned?
00129     //
00130     if (pEntry == pCacheHead)
00131     {
00132         if (pEntry == pCacheTail)
00133         {
00134             // HEAD --> X --> 0
00135             //    0 <--  <-- TAIL
00136             //
00137             // ASSERT: pEntry->pNextEntry == 0;
00138             // ASSERT: pEntry->pPrevEntry == 0;
00139             //
00140             pCacheHead = pCacheTail = 0;
00141         }
00142         else
00143         {
00144             // HEAD  --> X --> Y --> 0
00145             //    0 <--   <--   <--  TAIL
00146             //
00147             // ASSERT: pEntry->pNextEntry != 0;
00148             // ASSERT: pEntry->pPrevEntry == 0;
00149             //
00150             pCacheHead = pEntry->pNextEntry;
00151             pCacheHead->pPrevEntry = 0;
00152             pEntry->pNextEntry = 0;
00153         }
00154     }
00155     else if (pEntry == pCacheTail)
00156     {
00157         // HEAD  --> Y --> X --> 0
00158         //    0 <--   <--   <-- TAIL
00159         //
00160         // ASSERT: pEntry->pNextEntry == 0;
00161         // ASSERT: pEntry->pPrevEntry != 0;
00162         //
00163         pCacheTail = pEntry->pPrevEntry;
00164         pCacheTail->pNextEntry = 0;
00165         pEntry->pPrevEntry = 0;
00166     }
00167     else
00168     {
00169         // HEAD  --> Y --> X --> Z --> 0
00170         //    0 <--   <--   <--   <-- TAIL
00171         //
00172         // ASSERT: pEntry->pNextEntry != 0;
00173         // ASSERT: pEntry->pNextEntry != 0;
00174         //
00175         pEntry->pNextEntry->pPrevEntry = pEntry->pPrevEntry;
00176         pEntry->pPrevEntry->pNextEntry = pEntry->pNextEntry;
00177         pEntry->pNextEntry = 0;
00178         pEntry->pPrevEntry = 0;
00179     }
00180 }

static void TrimCache ( void   )  [static]

Definition at line 197 of file attrcache.cpp.

References statedata::acache_htab, tagCacheEntryHeader::attrKey, CacheSize, hashdeleteLEN(), confdata::max_cache_size, MEMFREE, mudconf, mudstate, tagCacheEntryHeader::nSize, pCacheTail, and REMOVE_ENTRY().

Referenced by cache_get(), and cache_put().

00198 {
00199     // Check to see if the cache needs to be trimmed.
00200     //
00201     while (CacheSize > mudconf.max_cache_size)
00202     {
00203         // Blow something away.
00204         //
00205         PCENT_HDR pCacheEntry = pCacheTail;
00206         if (!pCacheEntry)
00207         {
00208             CacheSize = 0;
00209             break;
00210         }
00211 
00212         REMOVE_ENTRY(pCacheEntry);
00213         CacheSize -= pCacheEntry->nSize;
00214         hashdeleteLEN(&(pCacheEntry->attrKey), sizeof(Aname),
00215             &mudstate.acache_htab);
00216         MEMFREE(pCacheEntry);
00217         pCacheEntry = NULL;
00218     }
00219 }


Variable Documentation

bool cache_initted = false [static]

Definition at line 15 of file attrcache.cpp.

Referenced by cache_close(), cache_del(), cache_get(), cache_init(), and cache_put().

bool cache_redirected = false [static]

Definition at line 17 of file attrcache.cpp.

Referenced by cache_pass2(), cache_put(), and cache_redirect().

unsigned int CacheSize = 0 [static]

Definition at line 43 of file attrcache.cpp.

Referenced by cache_del(), cache_get(), cache_put(), and TrimCache().

CLinearTimeAbsolute cs_ltime

Definition at line 21 of file attrcache.cpp.

Referenced by cache_init(), and list_db_stats().

CHashFile hfAttributeFile [static]

Definition at line 14 of file attrcache.cpp.

Referenced by cache_close(), cache_del(), cache_get(), cache_init(), cache_put(), cache_sync(), and cache_tick().

PCENT_HDR pCacheHead = 0 [static]

Definition at line 41 of file attrcache.cpp.

Referenced by ADD_ENTRY(), and REMOVE_ENTRY().

PCENT_HDR pCacheTail = 0 [static]

Definition at line 42 of file attrcache.cpp.

Referenced by ADD_ENTRY(), REMOVE_ENTRY(), and TrimCache().

FILE* TempFiles[N_TEMP_FILES] [static]

Definition at line 19 of file attrcache.cpp.

Referenced by cache_pass2(), cache_put(), and cache_redirect().

ATTR_RECORD TempRecord [static]

Definition at line 31 of file attrcache.cpp.

Referenced by cache_del(), cache_get(), and cache_put().


Generated on Mon May 28 04:40:12 2007 for MUX by  doxygen 1.4.7