fixes bug 321456 "Setting disk cache greater than 2097 MB fails." patch by alfredkayser@nl.ibm.com, r+sr=darin

This commit is contained in:
darin%meer.net 2006-02-28 22:18:21 +00:00
parent 003a14761a
commit 05b255bcdd
6 changed files with 53 additions and 32 deletions

View File

@ -53,7 +53,7 @@
class nsDiskCache {
public:
enum {
kCurrentVersion = 0x00010009 // format = 16 bits major version/16 bits minor version
kCurrentVersion = 0x0001000A // format = 16 bits major version/16 bits minor version
};
enum { kData, kMetaData };

View File

@ -104,7 +104,7 @@ class nsDiskCacheEvictor : public nsDiskCacheRecordVisitor
public:
nsDiskCacheEvictor( nsDiskCacheMap * cacheMap,
nsDiskCacheBindery * cacheBindery,
PRInt32 targetSize,
PRUint32 targetSize,
const char * clientID)
: mCacheMap(cacheMap)
, mBindery(cacheBindery)
@ -119,7 +119,7 @@ public:
private:
nsDiskCacheMap * mCacheMap;
nsDiskCacheBindery * mBindery;
PRInt32 mTargetSize;
PRUint32 mTargetSize;
const char * mClientID;
PRUint32 mClientIDSize;
};
@ -234,7 +234,8 @@ NS_IMETHODIMP nsDiskCacheDeviceInfo::GetEntryCount(PRUint32 *aEntryCount)
NS_IMETHODIMP nsDiskCacheDeviceInfo::GetTotalSize(PRUint32 *aTotalSize)
{
NS_ENSURE_ARG_POINTER(aTotalSize);
*aTotalSize = mDevice->getCacheSize();
// Returned unit's are in bytes
*aTotalSize = mDevice->getCacheSize() * 1024;
return NS_OK;
}
@ -242,7 +243,8 @@ NS_IMETHODIMP nsDiskCacheDeviceInfo::GetTotalSize(PRUint32 *aTotalSize)
NS_IMETHODIMP nsDiskCacheDeviceInfo::GetMaximumSize(PRUint32 *aMaximumSize)
{
NS_ENSURE_ARG_POINTER(aMaximumSize);
*aMaximumSize = mDevice->getCacheCapacity();
// Returned unit's are in bytes
*aMaximumSize = mDevice->getCacheCapacity() * 1024;
return NS_OK;
}
@ -390,7 +392,7 @@ nsDiskCacheDevice::Shutdown_Private(PRBool flush)
{
if (Initialized()) {
// check cache limits in case we need to evict.
EvictDiskCacheEntries((PRInt32)mCacheCapacity);
EvictDiskCacheEntries(mCacheCapacity);
// write out persistent information about the cache.
(void) mCacheMap.Close(flush);
@ -686,21 +688,25 @@ nsDiskCacheDevice::OnDataSizeChange(nsCacheEntry * entry, PRInt32 deltaSize)
NS_ASSERTION(binding->mRecord.ValidRecord(), "bad record");
PRUint32 newSize = entry->DataSize() + deltaSize;
PRUint32 maxSize = PR_MIN(mCacheCapacity / 2, kMaxDataFileSize);
if (newSize > maxSize) {
PRUint32 newSizeK = ((newSize + 0x3FF) >> 10);
// If the new size is larger than max. file size or larger than
// half the cache capacity (which is in KiB's), doom the entry and abort
if ((newSize > kMaxDataFileSize) || (newSizeK > mCacheCapacity/2)) {
nsresult rv = nsCacheService::DoomEntry(entry);
NS_ASSERTION(NS_SUCCEEDED(rv),"DoomEntry() failed.");
return NS_ERROR_ABORT;
}
PRUint32 sizeK = ((entry->DataSize() + 0x03FF) >> 10); // round up to next 1k
PRUint32 newSizeK = ((newSize + 0x3FF) >> 10);
NS_ASSERTION(sizeK < USHRT_MAX, "data size out of range");
NS_ASSERTION(newSizeK < USHRT_MAX, "data size out of range");
// pre-evict entries to make space for new data
PRInt32 targetCapacity = (PRInt32)(mCacheCapacity - ((newSizeK - sizeK) * 1024));
PRUint32 targetCapacity = mCacheCapacity > (newSizeK - sizeK)
? mCacheCapacity - (newSizeK - sizeK)
: 0;
EvictDiskCacheEntries(targetCapacity);
return NS_OK;
@ -875,11 +881,12 @@ nsDiskCacheDevice::ClearDiskCache()
nsresult
nsDiskCacheDevice::EvictDiskCacheEntries(PRInt32 targetCapacity)
nsDiskCacheDevice::EvictDiskCacheEntries(PRUint32 targetCapacity)
{
if (mCacheMap.TotalSize() < targetCapacity)
return NS_OK;
// targetCapacity is in KiB's
nsDiskCacheEvictor evictor(&mCacheMap, &mBindery, targetCapacity, nsnull);
return mCacheMap.EvictRecords(&evictor);
}
@ -941,10 +948,11 @@ nsDiskCacheDevice::getCacheDirectory(nsILocalFile ** result)
void
nsDiskCacheDevice::SetCapacity(PRUint32 capacity)
{
mCacheCapacity = capacity * 1024;
// Units are KiB's
mCacheCapacity = capacity;
if (Initialized()) {
// start evicting entries if the new size is smaller!
EvictDiskCacheEntries((PRInt32)mCacheCapacity);
EvictDiskCacheEntries(mCacheCapacity);
}
}

View File

@ -115,14 +115,15 @@ private:
nsresult OpenDiskCache();
nsresult ClearDiskCache();
nsresult EvictDiskCacheEntries(PRInt32 targetCapacity);
nsresult EvictDiskCacheEntries(PRUint32 targetCapacity);
/**
* Member variables
*/
nsCOMPtr<nsILocalFile> mCacheDirectory;
nsDiskCacheBindery mBindery;
PRUint32 mCacheCapacity; // XXX need soft/hard limits, currentTotal
PRUint32 mCacheCapacity; // Unit is KiB's
// XXX need soft/hard limits, currentTotal
nsDiskCacheMap mCacheMap;
PRPackedBool mInitialized;
};

View File

@ -730,7 +730,7 @@ nsDiskCacheMap::WriteDiskCacheEntry(nsDiskCacheBinding * binding)
(fileIndex == 0)) { // keeping the separate file
// just decrement total
// XXX if bindRecord.MetaFileSize == USHRT_MAX, stat the file to see how big it is
DecrementTotalSize(binding->mRecord.MetaFileSize() * 1024);
DecrementTotalSize(binding->mRecord.MetaFileSize());
NS_ASSERTION(binding->mRecord.MetaFileGeneration() == binding->mGeneration,
"generations out of sync");
} else {
@ -773,7 +773,7 @@ nsDiskCacheMap::WriteDiskCacheEntry(nsDiskCacheBinding * binding)
goto exit;
}
// XXX handle metaFileSizeK == USHRT_MAX
IncrementTotalSize(metaFileSizeK * 1024);
IncrementTotalSize(metaFileSizeK);
} else {
PRUint32 blockSize = GetBlockSizeForIndex(fileIndex);
@ -797,7 +797,7 @@ nsDiskCacheMap::WriteDiskCacheEntry(nsDiskCacheBinding * binding)
rv = mBlockFile[fileIndex - 1].WriteBlocks(diskEntry, startBlock, blocks);
if (NS_FAILED(rv)) goto exit;
IncrementTotalSize(blocks * blockSize);
IncrementTotalSize(blocks, blockSize);
}
exit:
@ -845,7 +845,7 @@ nsDiskCacheMap::WriteDataCacheBlocks(nsDiskCacheBinding * binding, char * buffer
rv = mBlockFile[fileIndex - 1].WriteBlocks(buffer, startBlock, blockCount);
if (NS_FAILED(rv)) return rv;
IncrementTotalSize(blockCount * blockSize);
IncrementTotalSize(blockCount, blockSize);
}
@ -882,15 +882,15 @@ nsDiskCacheMap::DeleteStorage(nsDiskCacheRecord * record, PRBool metaData)
if (NS_SUCCEEDED(rv)) {
rv = file->Remove(PR_FALSE); // false == non-recursive
}
DecrementTotalSize(sizeK * 1024);
DecrementTotalSize(sizeK);
} else if (fileIndex < 4) {
// deallocate blocks
PRInt32 startBlock = metaData ? record->MetaStartBlock() : record->DataStartBlock();
PRInt32 blockCount = metaData ? record->MetaBlockCount() : record->DataBlockCount();
PRUint32 startBlock = metaData ? record->MetaStartBlock() : record->DataStartBlock();
PRUint32 blockCount = metaData ? record->MetaBlockCount() : record->DataBlockCount();
rv = mBlockFile[fileIndex - 1].DeallocateBlocks(startBlock, blockCount);
DecrementTotalSize(blockCount * GetBlockSizeForIndex(fileIndex));
DecrementTotalSize(blockCount, GetBlockSizeForIndex(fileIndex));
}
if (metaData) record->ClearMetaLocation();
else record->ClearDataLocation();
@ -967,3 +967,4 @@ nsDiskCacheMap::CalculateFileIndex(PRUint32 size)
if (size <= 16384) return 3;
return 0;
}

View File

@ -335,7 +335,7 @@ class nsDiskCacheRecordVisitor {
struct nsDiskCacheHeader {
PRUint32 mVersion; // cache version.
PRInt32 mDataSize; // size of cache in bytes.
PRUint32 mDataSize; // size of cache in units of 256bytes.
PRInt32 mEntryCount; // number of entries stored in cache.
PRUint32 mIsDirty; // dirty flag.
PRInt32 mRecordCount; // Number of records
@ -444,21 +444,32 @@ public:
/**
* Statistical Operations
*/
void IncrementTotalSize( PRInt32 delta)
void IncrementTotalSize( PRUint32 delta)
{
NS_ASSERTION(mHeader.mDataSize >= 0, "disk cache size negative?");
mHeader.mDataSize += delta;
mHeader.mIsDirty = PR_TRUE;
}
void DecrementTotalSize( PRInt32 delta)
void DecrementTotalSize( PRUint32 delta)
{
mHeader.mDataSize -= delta;
NS_ASSERTION(mHeader.mDataSize >= delta, "disk cache size negative?");
mHeader.mDataSize = mHeader.mDataSize > delta ? mHeader.mDataSize - delta : 0;
mHeader.mIsDirty = PR_TRUE;
NS_ASSERTION(mHeader.mDataSize >= 0, "disk cache size negative?");
}
PRInt32 TotalSize() { return mHeader.mDataSize; }
inline void IncrementTotalSize( PRUint32 blocks, PRUint32 blockSize)
{
// Round up to nearest K
IncrementTotalSize(((blocks*blockSize) + 0x03FF) >> 10);
}
inline void DecrementTotalSize( PRUint32 blocks, PRUint32 blockSize)
{
// Round up to nearest K
DecrementTotalSize(((blocks*blockSize) + 0x03FF) >> 10);
}
PRUint32 TotalSize() { return mHeader.mDataSize; }
PRInt32 EntryCount() { return mHeader.mEntryCount; }

View File

@ -636,8 +636,8 @@ nsDiskCacheStreamIO::UpdateFileSize()
// update cache size totals
nsDiskCacheMap * cacheMap = mDevice->CacheMap();
cacheMap->DecrementTotalSize(oldSizeK * 1024); // decrement old size
cacheMap->IncrementTotalSize(newSizeK * 1024); // increment new size
cacheMap->DecrementTotalSize(oldSizeK); // decrement old size
cacheMap->IncrementTotalSize(newSizeK); // increment new size
if (!mBinding->mDoomed) {
nsresult rv = cacheMap->UpdateRecord(record);