fix for bug 75183, "separate eviction policy for chrome needed". sr=darin.

This commit is contained in:
gordon%netscape.com 2001-05-08 00:04:50 +00:00
Родитель 7f033b21f1
Коммит 96f47a92dc
2 изменённых файлов: 89 добавлений и 57 удалений

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

@ -41,14 +41,16 @@ const char *gMemoryCacheSizePref = "browser.cache.memory_cache_size";
nsMemoryCacheDevice::nsMemoryCacheDevice() nsMemoryCacheDevice::nsMemoryCacheDevice()
: mHardLimit(0), : mEvictionThreshold(40 * 1024),
mHardLimit(0),
mSoftLimit(0), mSoftLimit(0),
mTotalSize(0), mTotalSize(0),
mInactiveSize(0), mInactiveSize(0),
mEntryCount(0), mEntryCount(0),
mMaxEntryCount(0) mMaxEntryCount(0)
{ {
PR_INIT_CLIST(&mEvictionList); PR_INIT_CLIST(&mEvictionList[mostLikelyToEvict]);
PR_INIT_CLIST(&mEvictionList[leastLikelyToEvict]);
} }
@ -130,20 +132,22 @@ nsMemoryCacheDevice::Shutdown()
// evict all entries // evict all entries
nsCacheEntry * entry, * next; nsCacheEntry * entry, * next;
entry = (nsCacheEntry *)PR_LIST_HEAD(&mEvictionList); for (int i=mostLikelyToEvict; i <= leastLikelyToEvict; ++i) {
while (entry != &mEvictionList) { entry = (nsCacheEntry *)PR_LIST_HEAD(&mEvictionList[i]);
NS_ASSERTION(entry->IsInUse() == PR_FALSE, "### shutting down with active entries.\n"); while (entry != &mEvictionList[i]) {
next = (nsCacheEntry *)PR_NEXT_LINK(entry); NS_ASSERTION(entry->IsInUse() == PR_FALSE, "### shutting down with active entries.\n");
PR_REMOVE_AND_INIT_LINK(entry); next = (nsCacheEntry *)PR_NEXT_LINK(entry);
PR_REMOVE_AND_INIT_LINK(entry);
// update statistics
PRUint32 memoryRecovered = entry->Size(); // update statistics
mTotalSize -= memoryRecovered; PRUint32 memoryRecovered = entry->Size();
mInactiveSize -= memoryRecovered; mTotalSize -= memoryRecovered;
--mEntryCount; mInactiveSize -= memoryRecovered;
--mEntryCount;
delete entry; delete entry;
entry = next; entry = next;
}
} }
/* /*
@ -169,9 +173,9 @@ nsMemoryCacheDevice::FindEntry(nsCString * key)
nsCacheEntry * entry = mMemCacheEntries.GetEntry(key); nsCacheEntry * entry = mMemCacheEntries.GetEntry(key);
if (!entry) return nsnull; if (!entry) return nsnull;
// move entry to the tail of the eviction list // move entry to the tail of an eviction list
PR_REMOVE_AND_INIT_LINK(entry); PR_REMOVE_AND_INIT_LINK(entry);
PR_APPEND_LINK(entry, &mEvictionList); PR_APPEND_LINK(entry, &mEvictionList[EvictionList(entry, 0)]);
mInactiveSize -= entry->Size(); mInactiveSize -= entry->Size();
@ -214,7 +218,7 @@ nsMemoryCacheDevice::BindEntry(nsCacheEntry * entry)
if (!entry->IsDoomed()) { if (!entry->IsDoomed()) {
// append entry to the eviction list // append entry to the eviction list
PR_APPEND_LINK(entry, &mEvictionList); PR_APPEND_LINK(entry, &mEvictionList[EvictionList(entry, 0)]);
// add entry to hashtable of mem cache entries // add entry to hashtable of mem cache entries
nsresult rv = mMemCacheEntries.AddEntry(entry); nsresult rv = mMemCacheEntries.AddEntry(entry);
@ -293,6 +297,12 @@ nsMemoryCacheDevice::OnDataSizeChange( nsCacheEntry * entry, PRInt32 deltaSize)
// adjust our totals // adjust our totals
mTotalSize += deltaSize; mTotalSize += deltaSize;
if (!entry->IsDoomed()) {
// move entry to the tail of the appropriate eviction list
PR_REMOVE_AND_INIT_LINK(entry);
PR_APPEND_LINK(entry, &mEvictionList[EvictionList(entry, deltaSize)]);
}
EvictEntriesIfNecessary(); EvictEntriesIfNecessary();
@ -336,25 +346,36 @@ nsMemoryCacheDevice::EvictEntriesIfNecessary(void)
if ((mTotalSize < mHardLimit) && (mInactiveSize < mSoftLimit)) if ((mTotalSize < mHardLimit) && (mInactiveSize < mSoftLimit))
return; return;
// XXX implement more sophisticated eviction ordering for (int i=mostLikelyToEvict; i<=leastLikelyToEvict; ++i) {
entry = (nsCacheEntry *)PR_LIST_HEAD(&mEvictionList[i]);
while (entry != &mEvictionList[i]) {
if (entry->IsInUse()) {
entry = (nsCacheEntry *)PR_NEXT_LINK(entry);
continue;
}
entry = (nsCacheEntry *)PR_LIST_HEAD(&mEvictionList); next = (nsCacheEntry *)PR_NEXT_LINK(entry);
while (entry != &mEvictionList) { EvictEntry(entry);
if (entry->IsInUse()) { entry = next;
entry = (nsCacheEntry *)PR_NEXT_LINK(entry);
continue; if ((mTotalSize < mHardLimit) && (mInactiveSize < mSoftLimit))
return;
} }
next = (nsCacheEntry *)PR_NEXT_LINK(entry);
EvictEntry(entry);
entry = next;
if ((mTotalSize < mHardLimit) && (mInactiveSize < mSoftLimit))
break;
} }
} }
int
nsMemoryCacheDevice::EvictionList(nsCacheEntry * entry, PRUint32 deltaSize)
{
PRUint32 size = entry->Size() + deltaSize;
if ((size > mEvictionThreshold) || (entry->ExpirationTime() != 0))
return mostLikelyToEvict;
return leastLikelyToEvict;
}
nsresult nsresult
nsMemoryCacheDevice::Visit(nsICacheVisitor * visitor) nsMemoryCacheDevice::Visit(nsICacheVisitor * visitor)
{ {
@ -372,20 +393,21 @@ nsMemoryCacheDevice::Visit(nsICacheVisitor * visitor)
nsCacheEntry * entry; nsCacheEntry * entry;
nsCOMPtr<nsICacheEntryInfo> entryRef; nsCOMPtr<nsICacheEntryInfo> entryRef;
entry = (nsCacheEntry *)PR_LIST_HEAD(&mEvictionList); for (int i=mostLikelyToEvict; i <= leastLikelyToEvict; ++i) {
while (entry != &mEvictionList) { entry = (nsCacheEntry *)PR_LIST_HEAD(&mEvictionList[i]);
nsCacheEntryInfo * entryInfo = new nsCacheEntryInfo(entry); while (entry != &mEvictionList[i]) {
if (!entryInfo) return NS_ERROR_OUT_OF_MEMORY; nsCacheEntryInfo * entryInfo = new nsCacheEntryInfo(entry);
entryRef = entryInfo; if (!entryInfo) return NS_ERROR_OUT_OF_MEMORY;
entryRef = entryInfo;
rv = visitor->VisitEntry(gMemoryDeviceID, entryInfo, &keepGoing); rv = visitor->VisitEntry(gMemoryDeviceID, entryInfo, &keepGoing);
entryInfo->DetachEntry(); entryInfo->DetachEntry();
if (NS_FAILED(rv)) return rv; if (NS_FAILED(rv)) return rv;
if (!keepGoing) break; if (!keepGoing) break;
entry = (nsCacheEntry *)PR_NEXT_LINK(entry); entry = (nsCacheEntry *)PR_NEXT_LINK(entry);
}
} }
return NS_OK; return NS_OK;
} }
@ -396,20 +418,22 @@ nsMemoryCacheDevice::EvictEntries(const char * clientID)
nsCacheEntry * entry; nsCacheEntry * entry;
PRUint32 prefixLength = (clientID ? nsCRT::strlen(clientID) : 0); PRUint32 prefixLength = (clientID ? nsCRT::strlen(clientID) : 0);
PRCList * elem = PR_LIST_HEAD(&mEvictionList); for (int i=mostLikelyToEvict; i<=leastLikelyToEvict; ++i) {
while (elem != &mEvictionList) { PRCList * elem = PR_LIST_HEAD(&mEvictionList[i]);
entry = (nsCacheEntry *)elem; while (elem != &mEvictionList[i]) {
elem = PR_NEXT_LINK(elem); entry = (nsCacheEntry *)elem;
elem = PR_NEXT_LINK(elem);
const char * key = entry->Key()->get();
if (clientID && nsCRT::strncmp(clientID, key, prefixLength) != 0) const char * key = entry->Key()->get();
continue; if (clientID && nsCRT::strncmp(clientID, key, prefixLength) != 0)
continue;
if (entry->IsInUse()) {
nsresult rv = nsCacheService::GlobalInstance()->DoomEntry_Locked(entry); if (entry->IsInUse()) {
if (NS_FAILED(rv)) return rv; nsresult rv = nsCacheService::GlobalInstance()->DoomEntry_Locked(entry);
} else { if (NS_FAILED(rv)) return rv;
EvictEntry(entry); } else {
EvictEntry(entry);
}
} }
} }
return NS_OK; return NS_OK;

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

@ -70,9 +70,17 @@ private:
void AdjustMemoryLimits( PRUint32 softLimit, PRUint32 hardLimit); void AdjustMemoryLimits( PRUint32 softLimit, PRUint32 hardLimit);
void EvictEntry( nsCacheEntry * entry ); void EvictEntry( nsCacheEntry * entry );
void EvictEntriesIfNecessary(); void EvictEntriesIfNecessary();
int EvictionList(nsCacheEntry * entry, PRUint32 deltaSize);
/*
* Data members
*/
nsCacheEntryHashTable mMemCacheEntries; nsCacheEntryHashTable mMemCacheEntries;
PRCList mEvictionList;
enum { mostLikelyToEvict = 0, leastLikelyToEvict = 1 }; // constants to differentiate eviction lists
PRCList mEvictionList[2];
PRUint32 mEvictionThreshold;
PRUint32 mHardLimit; PRUint32 mHardLimit;
PRUint32 mSoftLimit; PRUint32 mSoftLimit;