Bug 661900 - LRU-SP not fully implemented in memory cache; r=michal

This commit is contained in:
Geoff Brown 2011-09-08 14:00:24 +02:00
Родитель fd4f379019
Коммит f47fc7a087
1 изменённых файлов: 32 добавлений и 14 удалений

46
netwerk/cache/nsMemoryCacheDevice.cpp поставляемый
Просмотреть файл

@ -49,7 +49,7 @@
#include "nsCache.h"
#include "nsReadableUtils.h"
// The memory cache implements a variation of the "LRU-SP" caching algorithm
// The memory cache implements the "LRU-SP" caching algorithm
// described in "LRU-SP: A Size-Adjusted and Popularity-Aware LRU Replacement
// Algorithm for Web Caching" by Kai Cheng and Yahiko Kambayashi.
@ -379,8 +379,8 @@ nsMemoryCacheDevice::EvictEntry(nsCacheEntry * entry, PRBool deleteEntry)
void
nsMemoryCacheDevice::EvictEntriesIfNecessary(void)
{
nsCacheEntry * entry, * next;
nsCacheEntry * entry;
nsCacheEntry * maxEntry;
CACHE_LOG_DEBUG(("EvictEntriesIfNecessary. mTotalSize: %d, mHardLimit: %d,"
"mInactiveSize: %d, mSoftLimit: %d\n",
mTotalSize, mHardLimit, mInactiveSize, mSoftLimit));
@ -388,22 +388,40 @@ nsMemoryCacheDevice::EvictEntriesIfNecessary(void)
if ((mTotalSize < mHardLimit) && (mInactiveSize < mSoftLimit))
return;
for (int i = kQueueCount - 1; i >= 0; --i) {
entry = (nsCacheEntry *)PR_LIST_HEAD(&mEvictionList[i]);
while (entry != &mEvictionList[i]) {
if (entry->IsInUse()) {
PRUint32 now = SecondsFromPRTime(PR_Now());
PRUint64 entryCost = 0;
PRUint64 maxCost = 0;
do {
// LRU-SP eviction selection: Check the head of each segment (each
// eviction list, kept in LRU order) and select the maximal-cost
// entry for eviction. Cost is time-since-accessed * size / nref.
maxEntry = 0;
for (int i = kQueueCount - 1; i >= 0; --i) {
entry = (nsCacheEntry *)PR_LIST_HEAD(&mEvictionList[i]);
// If the head of a list is in use, check the next available entry
while ((entry != &mEvictionList[i]) &&
(entry->IsInUse())) {
entry = (nsCacheEntry *)PR_NEXT_LINK(entry);
continue;
}
next = (nsCacheEntry *)PR_NEXT_LINK(entry);
EvictEntry(entry, DELETE_ENTRY);
entry = next;
if ((mTotalSize < mHardLimit) && (mInactiveSize < mSoftLimit))
return;
if (entry != &mEvictionList[i]) {
entryCost = (PRUint64)
(now - entry->LastFetched()) * entry->Size() /
PR_MAX(1, entry->FetchCount());
if (!maxEntry || (entryCost > maxCost)) {
maxEntry = entry;
maxCost = entryCost;
}
}
}
if (maxEntry) {
EvictEntry(maxEntry, DELETE_ENTRY);
} else {
break;
}
}
while ((mTotalSize >= mHardLimit) || (mInactiveSize >= mSoftLimit));
}