зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
003a14761a
Коммит
05b255bcdd
|
@ -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 };
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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; }
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче