зеркало из https://github.com/mozilla/gecko-dev.git
Fix for bug 48401.
Number of entries and records limited to 512. All known evict situations fixed. Causing evict to start happening. r=dp
This commit is contained in:
Родитель
eb4561f07e
Коммит
f41b42ce08
|
@ -305,7 +305,10 @@ nsDiskCacheRecord::Delete(void)
|
|||
if (NS_FAILED(rv))
|
||||
return NS_ERROR_FAILURE ;
|
||||
else
|
||||
{
|
||||
mDiskCache->mNumEntries--;
|
||||
return NS_OK ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -73,6 +73,10 @@ static const char * const DISK_CACHE_SIZE_PREF = "browser.cache.disk_cache_size
|
|||
static const char * const CACHE_DIR_PREF = "browser.cache.directory";
|
||||
static const char * const CACHE_ENABLE_PREF = "browser.cache.disk.enable";
|
||||
|
||||
// This number should be the same as MAX_DISK_CACHE_ENTRIES
|
||||
// defined in nsCacheManager.cpp
|
||||
#define MAX_DISK_CACHE_RECORDS 512
|
||||
|
||||
|
||||
static int PR_CALLBACK folderChanged(const char *pref, void *closure)
|
||||
{
|
||||
|
@ -114,8 +118,7 @@ nsNetDiskCache::nsNetDiskCache() :
|
|||
mDB(0) ,
|
||||
mDBCorrupted(PR_FALSE)
|
||||
{
|
||||
// set it to INF for now
|
||||
mMaxEntries = (PRUint32)-1 ;
|
||||
mMaxEntries = MAX_DISK_CACHE_RECORDS ;
|
||||
|
||||
NS_INIT_REFCNT();
|
||||
|
||||
|
|
|
@ -35,9 +35,11 @@
|
|||
#include "nsIServiceManager.h"
|
||||
#define FILE_CACHE_IS_READY
|
||||
// Limit the number of entries in the cache to conserve memory space
|
||||
// in the nsReplacementPolicy code
|
||||
// in the nsReplacementPolicy code.
|
||||
// MAX_DISK_CACHE_ENTRIES should be the same as MAX_DISK_CACHE_RECORDS
|
||||
// defined in nsNetDiskCache.cpp
|
||||
#define MAX_MEM_CACHE_ENTRIES 800
|
||||
#define MAX_DISK_CACHE_ENTRIES 3200
|
||||
#define MAX_DISK_CACHE_ENTRIES 512
|
||||
|
||||
// Cache capacities in MB, overridable via APIs
|
||||
#define DEFAULT_MEMORY_CACHE_CAPACITY 1024
|
||||
|
@ -70,7 +72,7 @@ static int PR_CALLBACK memCacheSizeChanged(const char *pref, void *closure)
|
|||
}
|
||||
|
||||
#define CACHE_HIGH_WATER_MARK(capacity) ((PRUint32)(0.98 * (capacity)))
|
||||
#define CACHE_LOW_WATER_MARK(capacity) ((PRUint32)(0.97 * (capacity)))
|
||||
#define CACHE_LOW_WATER_MARK(capacity) ((PRUint32)(0.75 * (capacity)))
|
||||
|
||||
nsCacheManager* gCacheManager = 0;
|
||||
PRBool gCacheManagerNeedToEvict = PR_FALSE;
|
||||
|
|
|
@ -36,6 +36,8 @@
|
|||
// Constant used to estimate frequency of access to a document based on size
|
||||
#define CACHE_CONST_B 1.35
|
||||
|
||||
#define CACHE_LOW_NUM_ENTRIES(entries) ((PRUint32)(0.75 * (entries)))
|
||||
|
||||
nsReplacementPolicy::nsReplacementPolicy()
|
||||
: mRankedEntries(0), mCaches(0), mRecordsRemovedSinceLastRanking(0),
|
||||
mNumEntries(0), mCapacityRankedEntriesArray(0), mLastRankTime(0), mLoadedAllDatabaseRecords( PR_FALSE ) {}
|
||||
|
@ -411,30 +413,43 @@ nsresult
|
|||
nsReplacementPolicy::CheckForTooManyCacheEntries()
|
||||
{
|
||||
PRUint32 undeletedEntries;
|
||||
PRUint32 maxEntries = 0;
|
||||
PRUint32 numEntriesDeleted = 0;
|
||||
PRBool deleteEntries = PR_FALSE;
|
||||
nsresult rv;
|
||||
CacheInfo *cacheInfo;
|
||||
|
||||
cacheInfo = mCaches;
|
||||
|
||||
undeletedEntries = mNumEntries - mRecordsRemovedSinceLastRanking;
|
||||
|
||||
if (undeletedEntries >= mMaxEntries) {
|
||||
return DeleteOneEntry(0);
|
||||
} else {
|
||||
nsresult rv;
|
||||
CacheInfo *cacheInfo;
|
||||
while (cacheInfo) {
|
||||
|
||||
cacheInfo = mCaches;
|
||||
while (cacheInfo) {
|
||||
PRUint32 numEntries, maxEntries;
|
||||
rv = cacheInfo->mCache->GetMaxEntries(&maxEntries);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (undeletedEntries >= mMaxEntries) {
|
||||
deleteEntries = PR_TRUE;
|
||||
} else {
|
||||
|
||||
PRUint32 numEntries = 0;
|
||||
|
||||
rv = cacheInfo->mCache->GetNumEntries(&numEntries);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = cacheInfo->mCache->GetMaxEntries(&maxEntries);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (numEntries == maxEntries)
|
||||
return DeleteOneEntry(cacheInfo->mCache);
|
||||
|
||||
cacheInfo = cacheInfo->mNext;
|
||||
if (numEntries == maxEntries) {
|
||||
deleteEntries = PR_TRUE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (deleteEntries) {
|
||||
return DeleteAtleastOneEntry(cacheInfo->mCache,
|
||||
CACHE_LOW_NUM_ENTRIES(maxEntries), &numEntriesDeleted);
|
||||
}
|
||||
deleteEntries = PR_FALSE;
|
||||
cacheInfo = cacheInfo->mNext;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -467,10 +482,7 @@ nsReplacementPolicy::AssociateCacheEntryWithRecord(nsINetDataCacheRecord *aRecor
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// If number of tracked cache entries exceeds limits, delete one
|
||||
rv = CheckForTooManyCacheEntries();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
|
||||
// Compact the array of cache entry statistics, so that free entries appear
|
||||
// at the end, for possible reuse.
|
||||
if (mNumEntries && (mNumEntries == mCapacityRankedEntriesArray))
|
||||
|
@ -542,20 +554,45 @@ nsReplacementPolicy::GetCachedNetData(const char* cacheKey, PRUint32 cacheKeyLen
|
|||
rv = aCache->GetCachedNetData(cacheKey, cacheKeyLength,
|
||||
getter_AddRefs(record));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// If number of tracked cache entries exceeds limits, delete one
|
||||
rv = CheckForTooManyCacheEntries();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
return AssociateCacheEntryWithRecord(record, aCache, aResult);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the least desirable record from the cache database. This is used
|
||||
* Delete the atleast one desirable record from the cache database. This is used
|
||||
* when the addition of another record would exceed either the cache manager or
|
||||
* the cache's maximum permitted number of records.
|
||||
* the cache's maximum permitted number of records. This method tries to reduce the
|
||||
* number of records in the cache database to targetNumEntries. targetNumEntriesReached
|
||||
* is set to PR_TRUE, if the nember of records has been reduced to targetNumEntries.
|
||||
* It returns NS_OK, if atleast one record has been succesfully deleted.
|
||||
*/
|
||||
nsresult
|
||||
nsReplacementPolicy::DeleteOneEntry(nsINetDataCache *aCache)
|
||||
nsReplacementPolicy::DeleteAtleastOneEntry(nsINetDataCache *aCache,
|
||||
PRUint32 targetNumEntries,
|
||||
PRUint32* numEntriesDeleted)
|
||||
{
|
||||
PRUint32 i;
|
||||
nsresult rv;
|
||||
nsCachedNetData *entry;
|
||||
PRBool atleastOneEntryDeleted = PR_FALSE;
|
||||
PRUint32 numRecordEntries = 0;
|
||||
|
||||
*numEntriesDeleted = 0;
|
||||
|
||||
if (!aCache)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
rv = aCache->GetNumEntries(&numRecordEntries);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
if (targetNumEntries >= numRecordEntries)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
|
||||
// It's not possible to rank cache entries by their profitability
|
||||
// until all of them are known to the replacement policy.
|
||||
|
@ -566,26 +603,35 @@ nsReplacementPolicy::DeleteOneEntry(nsINetDataCache *aCache)
|
|||
|
||||
i = 0;
|
||||
MaybeRerankRecords();
|
||||
while (1) {
|
||||
for (; i < mNumEntries; i++) {
|
||||
entry = mRankedEntries[i];
|
||||
if (!entry || entry->GetFlag(nsCachedNetData::RECYCLED) || (entry->mRefCnt > 1))
|
||||
continue;
|
||||
if (!aCache || (entry->mCache == aCache))
|
||||
break;
|
||||
}
|
||||
|
||||
// Report error if no record found to delete
|
||||
if (i == mNumEntries)
|
||||
return NS_ERROR_FAILURE;
|
||||
rv = entry->Delete();
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = DeleteCacheEntry(entry);
|
||||
mRecordsRemovedSinceLastRanking++;
|
||||
return rv;
|
||||
}
|
||||
i++;
|
||||
|
||||
for (i = 0; i < mNumEntries; i++) {
|
||||
entry = mRankedEntries[i];
|
||||
if (!entry || entry->GetFlag(nsCachedNetData::RECYCLED) || (entry->mRefCnt > 1))
|
||||
continue;
|
||||
if (entry->mCache == aCache) {
|
||||
rv = entry->Delete();
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = DeleteCacheEntry(entry);
|
||||
mRecordsRemovedSinceLastRanking++;
|
||||
atleastOneEntryDeleted = PR_TRUE;
|
||||
numRecordEntries--;
|
||||
*numEntriesDeleted = mRecordsRemovedSinceLastRanking;
|
||||
if (numRecordEntries <= targetNumEntries) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Report error if no record found to delete
|
||||
if (i == mNumEntries) {
|
||||
if (atleastOneEntryDeleted)
|
||||
return NS_OK;
|
||||
else
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -697,5 +743,8 @@ nsReplacementPolicy::Evict(PRUint32 aTargetOccupancy)
|
|||
}
|
||||
rv = entry->Evict(truncatedLength);
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
if (occupancy <= aTargetOccupancy)
|
||||
return NS_OK;
|
||||
else
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
|
|
@ -71,7 +71,7 @@ private:
|
|||
nsresult RankRecords();
|
||||
void MaybeRerankRecords();
|
||||
void CompactRankedEntriesArray();
|
||||
nsresult DeleteOneEntry(nsINetDataCache* aCache);
|
||||
nsresult DeleteAtleastOneEntry(nsINetDataCache* aCache, PRUint32 targetNumEntries, PRUint32* numEntriesDeleted);
|
||||
nsresult Evict(PRUint32 aTargetOccupancy);
|
||||
|
||||
nsCachedNetData* FindCacheEntryByRecordID(PRInt32 aRecordID, nsINetDataCache *aCache);
|
||||
|
|
Загрузка…
Ссылка в новой задаче