зеркало из https://github.com/mozilla/gecko-dev.git
Add code for removing requests and descriptors from cache entries.
This commit is contained in:
Родитель
e3db681306
Коммит
55f28b0eba
|
@ -31,12 +31,14 @@
|
|||
#include "nsICacheService.h"
|
||||
|
||||
#define ONE_YEAR (PR_USEC_PER_SEC * 60 * 60 * 24 * 365)
|
||||
nsCacheEntry::nsCacheEntry(nsCString * key)
|
||||
nsCacheEntry::nsCacheEntry(nsCString * key, nsCacheStoragePolicy storagePolicy)
|
||||
: mKey(key),
|
||||
mFetchCount(0),
|
||||
mFlags(0),
|
||||
mDataSize(0),
|
||||
mMetaSize(0),
|
||||
mFetchCount(0),
|
||||
mLastValidated(LL_ZERO),
|
||||
mExpirationTime(LL_ZERO),
|
||||
mFlags(0),
|
||||
mDataSize(0),
|
||||
mMetaSize(0),
|
||||
mCacheDevice(nsnull),
|
||||
mData(nsnull),
|
||||
mMetaData(nsnull)
|
||||
|
@ -44,8 +46,17 @@ nsCacheEntry::nsCacheEntry(nsCString * key)
|
|||
PR_INIT_CLIST(&mRequestQ);
|
||||
PR_INIT_CLIST(&mDescriptorQ);
|
||||
|
||||
mLastFetched = mLastValidated = PR_Now();
|
||||
mExpirationTime = LL_ZERO;
|
||||
mLastFetched = PR_Now();
|
||||
|
||||
if ((storagePolicy == nsICache::STORE_IN_MEMORY) ||
|
||||
(storagePolicy == nsICache::STORE_ANYWHERE)) {
|
||||
MarkAllowedInMemory();
|
||||
}
|
||||
|
||||
if ((storagePolicy == nsICache::STORE_ON_DISK) ||
|
||||
(storagePolicy == nsICache::STORE_ANYWHERE)) {
|
||||
MarkAllowedOnDisk();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -151,18 +162,33 @@ nsCacheEntry::Open(nsCacheRequest * request, nsICacheEntryDescriptor ** result)
|
|||
|
||||
PRUint32 accessGranted;
|
||||
nsresult rv = CommonOpen(request, &accessGranted);
|
||||
if (rv == NS_ERROR_CACHE_WAIT_FOR_VALIDATION) {
|
||||
//** queue request
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// rv = nsCacheEntryDescriptor::Create(this, accessGranted, result);
|
||||
|
||||
nsCacheEntryDescriptor * descriptor =
|
||||
new nsCacheEntryDescriptor(this, accessGranted);
|
||||
|
||||
if (descriptor == nsnull)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ADDREF(descriptor);
|
||||
rv = descriptor->QueryInterface(NS_GET_IID(nsICacheEntryDescriptor),
|
||||
(void**)result);
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// queue the descriptor
|
||||
PR_APPEND_LINK((descriptor)->GetListNode(), &mDescriptorQ);
|
||||
}
|
||||
|
||||
NS_RELEASE(descriptor);
|
||||
|
||||
} else if (rv == NS_ERROR_CACHE_WAIT_FOR_VALIDATION) {
|
||||
// queue request
|
||||
PR_APPEND_LINK(request->GetListNode(), &mRequestQ);
|
||||
//** allocate PRCondVar for request, if none
|
||||
//** release service lock
|
||||
//** wait until valid or doomed
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = nsCacheEntryDescriptor::Create(this, accessGranted, result);
|
||||
//** queue the descriptor
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -183,12 +209,47 @@ nsCacheEntry::AsyncOpen(nsCacheRequest * request)
|
|||
}
|
||||
} else if (rv == NS_ERROR_CACHE_WAIT_FOR_VALIDATION) {
|
||||
//** queue request and we're done (MarkValid will notify pending requests)
|
||||
} else {
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsCacheEntry::Doom()
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
PRBool
|
||||
nsCacheEntry::RemoveRequest(nsCacheRequest * request)
|
||||
{
|
||||
//** if debug: verify this request belongs to this entry
|
||||
PR_REMOVE_AND_INIT_LINK(request->GetListNode());
|
||||
|
||||
// return true if this entry should stay active
|
||||
return !((PR_CLIST_IS_EMPTY(&mRequestQ)) &&
|
||||
(PR_CLIST_IS_EMPTY(&mDescriptorQ)));
|
||||
}
|
||||
|
||||
|
||||
PRBool
|
||||
nsCacheEntry::RemoveDescriptor(nsCacheEntryDescriptor * descriptor)
|
||||
{
|
||||
//** if debug: verify this descriptor belongs to this entry
|
||||
PR_REMOVE_AND_INIT_LINK(descriptor->GetListNode());
|
||||
|
||||
if (!PR_CLIST_IS_EMPTY(&mDescriptorQ))
|
||||
return PR_TRUE; // stay active if we still have open descriptors
|
||||
|
||||
if (PR_CLIST_IS_EMPTY(&mRequestQ))
|
||||
return PR_FALSE; // no descriptors or requests, we can deactivate
|
||||
|
||||
//** find next best request to give a descriptor to
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* nsCacheEntryHashTable
|
||||
*/
|
||||
|
@ -290,11 +351,11 @@ nsCacheEntryHashTable::GetKey( PLDHashTable * /*table*/, PLDHashEntryHdr *hashEn
|
|||
return cacheEntry->mKey;
|
||||
}
|
||||
|
||||
|
||||
PLDHashNumber
|
||||
nsCacheEntryHashTable::HashKey( PLDHashTable *table, const void *key)
|
||||
{
|
||||
// XXX write a good hash function!
|
||||
return PLDHashNumber(key);
|
||||
return PLDHashNumber(((nsCString *)key)->get());
|
||||
}
|
||||
|
||||
PRBool
|
||||
|
|
|
@ -31,30 +31,20 @@
|
|||
#include "nsString.h"
|
||||
#include "nsAReadableString.h"
|
||||
|
||||
#include "nsICache.h"
|
||||
#include "nsICacheEntryDescriptor.h"
|
||||
|
||||
|
||||
class nsCacheDevice;
|
||||
class nsCacheMetaData;
|
||||
class nsCacheRequest;
|
||||
class nsCacheEntryDescriptor;
|
||||
|
||||
class nsCacheEntry
|
||||
{
|
||||
public:
|
||||
enum CacheEntryFlags {
|
||||
eDoomedMask = 1,
|
||||
eEntryDirtyMask = 2,
|
||||
eDataDirtyMask = 4,
|
||||
eMetaDataDirtyMask = 8,
|
||||
eStreamDataMask = 16,
|
||||
eActiveMask = 32,
|
||||
eInitializedMask = 64,
|
||||
eValidMask = 128,
|
||||
eAllowInMemoryMask = 256,
|
||||
eAllowOnDiskMask = 512
|
||||
};
|
||||
|
||||
nsCacheEntry(nsCString * key);
|
||||
nsCacheEntry(nsCString * key, nsCacheStoragePolicy storagePolicy);
|
||||
~nsCacheEntry();
|
||||
|
||||
void GetKey( nsCString ** key) { if (key) *key = mKey; }
|
||||
|
@ -62,16 +52,14 @@ public:
|
|||
void GetFetchCount( PRInt32 * result) { if (result) *result = mFetchCount; }
|
||||
void SetFetchCount( PRInt32 count) { mFetchCount = count; }
|
||||
|
||||
void GetLastFetched( PRTime * result) { if (result) *result = mLastFetched; }
|
||||
void SetLastFetched( PRTime lastFetched)
|
||||
{ if (!LL_IS_ZERO(lastFetched)) mLastFetched = lastFetched; }
|
||||
void GetLastFetched( PRTime * result) { if (result) *result = mLastFetched; }
|
||||
void SetLastFetched( PRTime lastFetched) { mLastFetched = lastFetched; }
|
||||
|
||||
void GetLastValidated( PRTime * result) { if (result) *result = mLastValidated; }
|
||||
void SetLastValidated( PRTime lastValidated)
|
||||
{ if (!LL_IS_ZERO(lastValidated)) mLastValidated = lastValidated; }
|
||||
void SetLastValidated( PRTime lastValidated) { mLastValidated = lastValidated; }
|
||||
|
||||
void GetExpirationTime( PRTime * result) { if (result) *result = mExpirationTime; }
|
||||
void SetExpirationTime( PRTime expires) { if (!LL_IS_ZERO(expires)) mExpirationTime = expires; }
|
||||
void SetExpirationTime( PRTime expires) { mExpirationTime = expires; }
|
||||
|
||||
void GetDataSize( PRUint32 * result) { if (result) *result = mDataSize; }
|
||||
void SetDataSize( PRUint32 size) { mDataSize = size; }
|
||||
|
@ -85,7 +73,6 @@ public:
|
|||
nsresult GetData( nsISupports ** result);
|
||||
nsresult SetData( nsISupports * data);
|
||||
|
||||
//** should we make these string references instead of pointers?
|
||||
nsresult GetMetaDataElement( const nsAReadableCString& key,
|
||||
nsAReadableCString ** value);
|
||||
nsresult SetMetaDataElement( const nsAReadableCString& key,
|
||||
|
@ -93,31 +80,52 @@ public:
|
|||
|
||||
//** enumerate MetaData method
|
||||
|
||||
void MarkEntryDirty() { mFlags |= eEntryDirtyMask;}
|
||||
void MarkDataDirty() { mFlags |= eDataDirtyMask; }
|
||||
void MarkMetaDataDirty() { mFlags |= eMetaDataDirtyMask; }
|
||||
void MarkActive() { mFlags |= eActiveMask; }
|
||||
void MarkInactive() { mFlags &= ~eActiveMask; }
|
||||
|
||||
enum CacheEntryFlags {
|
||||
eDoomedMask = 0x00000001,
|
||||
eEntryDirtyMask = 0x00000002,
|
||||
eDataDirtyMask = 0x00000004,
|
||||
eMetaDataDirtyMask = 0x00000008,
|
||||
eStreamDataMask = 0x00000010,
|
||||
eActiveMask = 0x00000020,
|
||||
eInitializedMask = 0x00000040,
|
||||
eValidMask = 0x00000080,
|
||||
// eStoragePolicyMask = 0x00000300
|
||||
eAllowedInMemoryMask = 0x00000100,
|
||||
eAllowedOnDiskMask = 0x00000200
|
||||
|
||||
};
|
||||
|
||||
void MarkEntryDirty() { mFlags |= eEntryDirtyMask; }
|
||||
void MarkDataDirty() { mFlags |= eDataDirtyMask; }
|
||||
void MarkMetaDataDirty() { mFlags |= eMetaDataDirtyMask; }
|
||||
void MarkActive() { mFlags |= eActiveMask; }
|
||||
void MarkInactive() { mFlags &= ~eActiveMask; }
|
||||
void MarkValid();
|
||||
|
||||
PRBool IsDoomed() { return (mFlags & eDoomedMask) != 0; }
|
||||
PRBool IsEntryDirty() { return (mFlags & eEntryDirtyMask) != 0; }
|
||||
PRBool IsDataDirty() { return (mFlags & eDataDirtyMask) != 0; }
|
||||
PRBool IsMetaDataDirty() { return (mFlags & eMetaDataDirtyMask) != 0; }
|
||||
PRBool IsStreamData() { return (mFlags & eStreamDataMask) != 0; }
|
||||
PRBool IsActive() { return (mFlags & eActiveMask) != 0; }
|
||||
PRBool IsInitialized() { return (mFlags & eInitializedMask) != 0; }
|
||||
PRBool IsValid() { return (mFlags & eValidMask) != 0; }
|
||||
|
||||
private:
|
||||
friend class nsCacheEntryHashTable;
|
||||
friend class nsCacheService;
|
||||
void MarkAllowedInMemory() { mFlags |= eAllowedInMemoryMask; }
|
||||
void MarkAllowedOnDisk() { mFlags |= eAllowedOnDiskMask; }
|
||||
|
||||
PRBool IsDoomed() { return (mFlags & eDoomedMask) != 0; }
|
||||
PRBool IsEntryDirty() { return (mFlags & eEntryDirtyMask) != 0; }
|
||||
PRBool IsDataDirty() { return (mFlags & eDataDirtyMask) != 0; }
|
||||
PRBool IsMetaDataDirty() { return (mFlags & eMetaDataDirtyMask) != 0; }
|
||||
PRBool IsStreamData() { return (mFlags & eStreamDataMask) != 0; }
|
||||
PRBool IsActive() { return (mFlags & eActiveMask) != 0; }
|
||||
PRBool IsInitialized() { return (mFlags & eInitializedMask) != 0; }
|
||||
PRBool IsValid() { return (mFlags & eValidMask) != 0; }
|
||||
|
||||
// methods for nsCacheService
|
||||
nsresult Open(nsCacheRequest *request, nsICacheEntryDescriptor ** result);
|
||||
nsresult AsyncOpen(nsCacheRequest *request);
|
||||
nsresult Doom() { return NS_ERROR_NOT_IMPLEMENTED; } //** implement
|
||||
nsresult Doom(void);
|
||||
PRBool RemoveRequest( nsCacheRequest * request);
|
||||
PRBool RemoveDescriptor( nsCacheEntryDescriptor * descriptor);
|
||||
|
||||
nsCacheDevice * CacheDevice(void) { return mCacheDevice; }
|
||||
|
||||
private:
|
||||
friend class nsCacheEntryHashTable;
|
||||
friend class nsCacheService;
|
||||
|
||||
// internal methods
|
||||
nsresult CommonOpen(nsCacheRequest * request, PRUint32 *accessGranted);
|
||||
|
@ -140,8 +148,6 @@ private:
|
|||
};
|
||||
|
||||
|
||||
|
||||
|
||||
typedef struct {
|
||||
PLDHashNumber keyHash;
|
||||
nsCacheEntry *cacheEntry;
|
||||
|
|
Загрузка…
Ссылка в новой задаче