📄 cache.cpp
字号:
char* pContent = new char [nContentRead]; if (pContent) { pChunkyRes->GetData(0, pContent, nContentRead, &ulActual); data.size = ulActual; data.data = pContent; int rc = m_pDbData->put(m_pDbData, &key, &data, 0); if (rc == 0) { m_bCached = TRUE; LOG(" Cache content entry written"); } else { if (rc == DB_KEYEXIST) { LOG(" Duplicate content entry, not written"); m_bCached = TRUE; } else { LOGX((szDbgTemp, "*** Error putting content entry into cache [%lu]", rc)); } } delete [] pContent; } else { LOG ("*** Error allocating buffer for content"); } m_pDbHeader->sync(m_pDbHeader, 0); HX_VECTOR_DELETE(pHeader); return(HXR_OK);}HX_RESULTCCacheEntry::ReadCache (DBT* pdbtKey, DBT* pdbtHeader, DBT* pdbtContent, BOOL bMirroredServers){ HX_RESULT rc = HXR_FAIL; UINT32 ulFlags = 0; LOG ("ReadCache()"); if (m_pDbHeader == NULL || m_pDbData == NULL) { return(HXR_FAIL); } // if bMirroredServers is set, try an abbreviated domain name if (bMirroredServers) { LOG (" Reading abbreviated URL"); DBT dbtMirror = { NULL, 0 }; dbtMirror.data = GetAbbrevUrl ((char*)pdbtKey->data, pdbtKey->size); dbtMirror.size = strlen ((char*)dbtMirror.data); if ((rc = m_pDbHeader->get (m_pDbHeader, &dbtMirror, pdbtHeader, ulFlags)) != HXR_OK) { LOG (" No header entry in cache (Abbreviated URL)"); } else { rc = m_pDbData->get (m_pDbData, &dbtMirror, pdbtContent, ulFlags); } delete [] (char*)dbtMirror.data; } if (rc != HXR_OK) { if ((rc = m_pDbHeader->get (m_pDbHeader, pdbtKey, pdbtHeader, ulFlags)) != HXR_OK) { LOG (" No header entry in cache"); } else { rc = m_pDbData->get (m_pDbData, pdbtKey, pdbtContent, ulFlags); } } // Record usage info if (rc == HXR_OK) { DBT dbtUsage = { NULL, 0 }; if ((rc = m_pDbUsage->get (m_pDbUsage, pdbtKey, &dbtUsage, ulFlags)) != 0) { LOG ("*** Get of usage failed"); } else { PCacheUsage pUsage = (PCacheUsage) dbtUsage.data; CacheUsage usage = { 0, 0, 0, 0, 0, 0 }; DBT dbtUsage2 = { &usage, sizeof (CacheUsage) }; UINT32 ulNow = time (NULL); usage.m_ulSize = pUsage->m_ulSize; usage.m_ulCreateTime = pUsage->m_ulCreateTime; usage.m_ulExpiryTime = pUsage->m_ulExpiryTime; usage.m_ulLastUsedTime = time (NULL); usage.m_ulUseCount = pUsage->m_ulUseCount + 1; if ((rc = m_pDbUsage->put (m_pDbUsage, pdbtKey, &dbtUsage2, ulFlags)) == DB_OK) { LOG (" Put of usage info done"); LOGX((szDbgTemp, " Count=%lu Created=%ld Last=%ld Expiry=%ld", usage.m_ulUseCount, ulNow - usage.m_ulCreateTime, ulNow - usage.m_ulLastUsedTime, usage.m_ulExpiryTime - ulNow)); LOGX((szDbgTemp, " Count=%ld Created=%08X Last=%08X Expiry=%08X", usage.m_ulUseCount, usage.m_ulCreateTime, usage.m_ulLastUsedTime, usage.m_ulExpiryTime)); } else { LOG ("$$$ Put failed (usage)"); } free(dbtUsage.data); } rc = HXR_OK; // Use cache even if usage table has errors } LOGX ((szDbgTemp, " %s: %s", rc ? "Miss" : "Hit", pdbtKey->data)); return(rc);}static char *GetAbbrevUrl (char* pData, UINT32 ulSize){ UINT32 i = 0; UINT32 j = 0; UINT32 ulDotCount = 0; UINT32 ulSlashCount = 0; char* pReturn = NULL; if (pData == NULL) { LOG (" NULL URL cannot be abbreviated"); return(NULL); } // there should be three or more dots in the domain for (i = 0; i < ulSize; i++) { if (pData[i] == '\0') { break; } if ((pData[i] == '/' || pData[i] == '\\') && (++ulSlashCount > 2)) { break; } if (pData[i] == '.') { ulDotCount++; } } if (ulSlashCount < 3 || ulDotCount < 3) { LOG (" URL cannot be abbreviated"); return(NULL); } // allocate storage pReturn = new char[ulSize]; // copy the protocol string for (i = 0; i < ulSize; i++) { if (pData[i] == '\0') break; pReturn[j++] = pData[i]; if (i >= 2) { if (pData[i-2] == ':' && pData[i-1] == '/' && pData[i] == '/') break; } } // skip the first domain label do { if (pData[i] != '.') break; } while (++i < ulSize); // copy the rest of the URL do { pReturn[j++] = pData[i]; } while ((++i < ulSize) && (pData[i] != '\0')); return (pReturn);}#define ENFORCE_SIZE_LIMIT#define SECONDS_IN_UNIT (10 * 60) /* ten minutes */#define BUMP_LIMIT (16)typedef struct _BUMPLIST { UINT32 ulRank; UINT32 ulSize; char* pszUrl;} BUMPLIST, *PBUMPLIST;HX_RESULTCCacheEntry::CleanCache(UINT32 ulCutOffDate, UINT32 ulSlackSeconds){ /* * clean out expired entries */ LOGX ((szDbgTemp, "CleanCache(%ld)", ulCutOffDate)); UINT32 rc = 0; DBT dbtKey = { NULL, 0 }; DBT dbtData = { NULL, 0 }; UINT32 ulIndex = 0; UINT32 ulMbytesFree = 0; static UINT32 ulLowRank = 0; //FNH Why static? static UINT32 ulLastTime = 0; if (m_pDbHeader == NULL || m_pDbHeader == NULL || m_pDbHeader == NULL) { LOG ("*** NULL database handle"); return(HXR_FAIL); } ulMbytesFree = GetFreeMbyteCount(m_pszDbDir); if (ulMbytesFree > DISK_FREE_LOW) { if (time(NULL) - ulLastTime < ulSlackSeconds) // Disk space is not low, and we checked recently return(HXR_OK); } ulLastTime = time(NULL); UINT32 ulDbSize = 0; BUMPLIST bumpList[BUMP_LIMIT] = {{ 0, 0, NULL }}; // Bump up to this many entries /* Initialize the key/data pair so the flags aren't set. */ memset(&dbtKey, 0, sizeof(dbtKey)); memset(&dbtData, 0, sizeof(dbtData)); /* Walk through the database and look at the key/data pairs. */ BOOL firstTimeThrough = TRUE; while (TRUE) { rc = m_pDbUsage->seq(m_pDbUsage, &dbtKey, &dbtData, (firstTimeThrough)? R_FIRST : R_NEXT); firstTimeThrough = FALSE; if (rc != 0) break; PCacheUsage pCacheUsage = (PCacheUsage) dbtData.data; LOGX ((szDbgTemp, " Cache entry: (%7d bytes) UseCount=%ld TTL=%lds, LastUsed=%ld, %.*s", pCacheUsage->m_ulSize, pCacheUsage->m_ulUseCount, (INT32)pCacheUsage->m_ulExpiryTime - (INT32)time(NULL), (INT32)time(NULL) - (INT32)pCacheUsage->m_ulLastUsedTime, (int)dbtKey.size, (char *)dbtKey.data)); // if expiry time is in the past or cutoff time is in the future BOOL fDeleteEntry = TRUE; if (rc == 0 && pCacheUsage) { if (pCacheUsage->m_ulExpiryTime < (UINT32)time(NULL)) { LOG ("$$$ Cache entry has expired"); } else if(ulCutOffDate && pCacheUsage->m_ulCreateTime < ulCutOffDate) { LOG ("$$$ Cache entry was created before cut-off date"); } else if(pCacheUsage->m_ulCreateTime < (UINT32)time(NULL) - SECS_IN_YEAR) { LOG ("$$$ Cache entry more than a year old"); } else if(pCacheUsage->m_ulExpiryTime > (UINT32)time(NULL) + SECS_IN_YEAR) { LOG ("$$$ Cache entry expires more than a year from now"); } else { fDeleteEntry = FALSE; } } // if expiry time is in the past or cutoff time is in the future if (rc == 0 && pCacheUsage && fDeleteEntry) { m_pDbData->del(m_pDbData, &dbtKey, 0); // Remove expired entry from cache m_pDbUsage->del(m_pDbUsage, &dbtKey, 0); // Remove expired entry from cache m_pDbHeader->del(m_pDbHeader, &dbtKey, 0); // Remove expired entry from cache }#ifdef ENFORCE_SIZE_LIMIT else if (pCacheUsage && !(pCacheUsage->m_ulFlags & CACHE_EVERGREEN)) { ulDbSize += pCacheUsage->m_ulSize; // construct a list of entries and sizes so cache size limits can be enforced UINT32 ulRank = (pCacheUsage->m_ulSize * 1000) / m_ulMaxCacheSize; ulRank += (time(NULL) - pCacheUsage->m_ulLastUsedTime) / SECONDS_IN_UNIT; ulRank /= pCacheUsage->m_ulUseCount; LOGX ((szDbgTemp, " Rank=%3lu, %1.*s", ulRank, (int)dbtKey.size, (char *)dbtKey.data)); // Add entry to list of items to possibly purge if (ulRank > ulLowRank) { // The entry will bump the lowest ranked entry on the list for (ulIndex = 0; ulIndex < BUMP_LIMIT; ulIndex++) { UINT32 ulNewLowRank = ulRank; if (bumpList[ulIndex].ulRank == ulLowRank) { bumpList[ulIndex].ulRank = ulRank; bumpList[ulIndex].ulSize = pCacheUsage->m_ulSize; if (bumpList[ulIndex].pszUrl) delete [] bumpList[ulIndex].pszUrl; bumpList[ulIndex].pszUrl = new char [dbtKey.size + 1]; strncpy (bumpList[ulIndex].pszUrl, (char *)dbtKey.data, dbtKey.size); /* Flawfinder: ignore */ bumpList[ulIndex].pszUrl[dbtKey.size] = '\0'; ulLowRank = ulNewLowRank; } else // check for next lowest ranked entry { if (ulNewLowRank > bumpList[ulIndex].ulRank) ulNewLowRank = bumpList[ulIndex].ulRank; } } // Finish the search for the next lowest ranked entry while (++ulIndex < BUMP_LIMIT) { if (ulLowRank > bumpList[ulIndex].ulRank) ulLowRank = bumpList[ulIndex].ulRank; } } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -