Changed GetKey() to return key as return value, rather than out parameter. Added flag predicates for storage policy.

git-svn-id: svn://10.0.0.236/trunk@88063 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
gordon%netscape.com
2001-02-27 05:35:53 +00:00
parent cee3eac4fa
commit 8b61a442bc
11 changed files with 149 additions and 225 deletions

View File

@@ -71,10 +71,10 @@ nsCacheEntry::~nsCacheEntry()
nsresult
nsCacheEntry::GetData(nsISupports **result)
{
if (IsStreamData())
return NS_ERROR_CACHE_DATA_IS_STREAM;
if (IsStreamData()) return NS_ERROR_CACHE_DATA_IS_STREAM;
if (!result) return NS_ERROR_NULL_POINTER;
if (result) *result = mData;
NS_IF_ADDREF(*result = mData);
return NS_OK;
}
@@ -112,6 +112,14 @@ nsCacheEntry::SetMetaDataElement( const nsAReadableCString& key,
}
void
nsCacheEntry::MarkValid()
{
//** convert pending requests to descriptors, etc.
mFlags |= eValidMask;
}
/**
* cache entry states
* 0 descriptors (new entry)
@@ -316,7 +324,7 @@ nsCacheEntryHashTable::AddEntry( nsCacheEntry *cacheEntry)
if (!cacheEntry) return NS_ERROR_NULL_POINTER;
hashEntry = PL_DHashTableOperate(&table, cacheEntry->mKey, PL_DHASH_ADD);
NS_ASSERTION(((nsCacheEntryHashTableEntry *)hashEntry)->cacheEntry != 0,
NS_ASSERTION(((nsCacheEntryHashTableEntry *)hashEntry)->cacheEntry == 0,
"nsCacheEntryHashTable::AddEntry - entry already used");
((nsCacheEntryHashTableEntry *)hashEntry)->cacheEntry = cacheEntry;
@@ -355,7 +363,7 @@ nsCacheEntryHashTable::GetKey( PLDHashTable * /*table*/, PLDHashEntryHdr *hashEn
PLDHashNumber
nsCacheEntryHashTable::HashKey( PLDHashTable *table, const void *key)
{
return PLDHashNumber(((nsCString *)key)->get());
return PL_DHashStringKey(table,((nsCString *)key)->get());
}
PRBool

View File

@@ -47,7 +47,7 @@ public:
nsCacheEntry(nsCString * key, nsCacheStoragePolicy storagePolicy);
~nsCacheEntry();
void GetKey( nsCString ** key) { if (key) *key = mKey; }
nsCString * GetKey(void) { return mKey; }
void GetFetchCount( PRInt32 * result) { if (result) *result = mFetchCount; }
void SetFetchCount( PRInt32 count) { mFetchCount = count; }
@@ -113,6 +113,8 @@ public:
PRBool IsActive() { return (mFlags & eActiveMask) != 0; }
PRBool IsInitialized() { return (mFlags & eInitializedMask) != 0; }
PRBool IsValid() { return (mFlags & eValidMask) != 0; }
PRBool IsAllowedInMemory() { return (mFlags & eAllowedInMemoryMask) != 0; }
PRBool IsAllowedOnDisk() { return (mFlags & eAllowedOnDiskMask) !=0; }
// methods for nsCacheService
nsresult Open(nsCacheRequest *request, nsICacheEntryDescriptor ** result);

View File

@@ -38,8 +38,7 @@ nsCacheEntryDescriptor::nsCacheEntryDescriptor(nsCacheEntry * entry,
nsCacheEntryDescriptor::~nsCacheEntryDescriptor()
{
// tell nsCacheService we're going away
nsCacheService::GlobalInstance()->CloseDescriptor(this);
Close();
}
@@ -71,7 +70,7 @@ nsCacheEntryDescriptor::GetKey(char ** result)
nsresult rv = NS_OK;
*result = nsnull;
mCacheEntry->GetKey(&key);
key = mCacheEntry->GetKey();
nsReadingIterator<char> start;
key->BeginReading(start);
@@ -217,6 +216,18 @@ nsCacheEntryDescriptor::MarkValid()
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsCacheEntryDescriptor::Close()
{
if (mCacheEntry) {
// tell nsCacheService we're going away
nsCacheService::GlobalInstance()->CloseDescriptor(this);
mCacheEntry = nsnull;
}
return NS_OK;
}
/* string getMetaDataElement (in string key); */
NS_IMETHODIMP
nsCacheEntryDescriptor::GetMetaDataElement(const char *key, char **result)

View File

@@ -129,10 +129,10 @@ nsCacheMetaData::GetKey( PLDHashTable * /* table */, PLDHashEntryHdr *hashEntry)
}
PLDHashNumber
nsCacheMetaData::HashKey( PLDHashTable * /* table */, const void *key)
nsCacheMetaData::HashKey( PLDHashTable * table, const void *key)
{
//** need scc's new flat string abstract class here (bug 70075)
return PLDHashNumber(((nsCString *)key)->get());
return PL_DHashStringKey(table, ((nsCString *)key)->get());
}
PRBool

View File

@@ -38,4 +38,4 @@ static nsModuleComponentInfo gResComponents[] = {
}
};
NS_IMPL_NSGETMODULE("cache", gResComponents)
NS_IMPL_NSGETMODULE("cacheservice", gResComponents)

View File

@@ -36,7 +36,9 @@ nsCacheService * nsCacheService::gService = nsnull;
NS_IMPL_THREADSAFE_ISUPPORTS1(nsCacheService, nsICacheService)
nsCacheService::nsCacheService()
: mCacheServiceLock(nsnull)
: mCacheServiceLock(nsnull),
mMemoryDevice(nsnull),
mDiskDevice(nsnull)
{
NS_INIT_REFCNT();
@@ -44,7 +46,7 @@ nsCacheService::nsCacheService()
gService = this;
// create list of cache devices
PR_INIT_CLIST(&mDeviceList);
PR_INIT_CLIST(&mDoomedEntries);
}
nsCacheService::~nsCacheService()
@@ -69,39 +71,25 @@ nsCacheService::Init()
if (mCacheServiceLock == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
#if 0
// initialize hashtable for client ids
rv = mClientIDs.Init();
NS_ASSERTION(NS_SUCCEEDED(rv), "mClientIDs.Init() failed");
#endif
// initialize hashtable for active cache entries
rv = mActiveEntries.Init();
if (NS_FAILED(rv)) goto error;
if (NS_SUCCEEDED(rv)) {
// create memory cache
#if 0
nsMemoryCacheDevice *device = new nsMemoryCacheDevice;
// (void) mDeviceList.AppendElement(device);
PRUint32 deviceID = device->GetDeviceID();
#endif
if (NS_SUCCEEDED(rv)) {
// create disk cache
}
// create memory cache
mMemoryDevice = new nsMemoryCacheDevice;
if (!mMemoryDevice) {
rv = NS_ERROR_OUT_OF_MEMORY;
goto error;
}
rv = mMemoryDevice->Init();
if (NS_FAILED(rv)) goto error;
//** create disk cache
return NS_OK;
if (NS_FAILED(rv)) {
// if mem cache - destroy it
// if disk cache - destroy it
PR_DestroyLock(mCacheServiceLock);
mCacheServiceLock = nsnull;
// finish mActiveEntries hashtable
}
error:
(void)Shutdown();
return rv;
}
@@ -118,7 +106,12 @@ nsCacheService::Shutdown()
//** finalize active entries
//** deallocate memory and disk caches
// deallocate memory and disk caches
delete mMemoryDevice;
mMemoryDevice = nsnull;
delete mDiskDevice;
mDiskDevice = nsnull;
PR_DestroyLock(mCacheServiceLock);
mCacheServiceLock = nsnull;
@@ -160,11 +153,9 @@ nsCacheService::CreateSession(const char * clientID,
nsCacheSession * session = new nsCacheSession(clientID, storagePolicy, streamBased);
if (!session) return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(session);
nsresult rv = session->QueryInterface(NS_GET_IID(nsICacheSession),(void**) result);
NS_RELEASE(session);
NS_ADDREF(*result = session);
return rv;
return NS_OK;
}
@@ -176,28 +167,31 @@ NS_IMETHODIMP nsCacheService::VisitEntries(nsICacheVisitor *visitor)
nsresult
nsCacheService::CommonOpenCacheEntry(nsCacheSession * session,
const char * clientKey,
nsCacheAccessMode accessRequested,
nsICacheListener * listener,
nsCacheRequest ** request,
nsCacheEntry ** entry)
nsCacheService::CreateRequest(nsCacheSession * session,
const char * clientKey,
nsCacheAccessMode accessRequested,
nsICacheListener * listener,
nsCacheRequest ** request)
{
NS_ASSERTION(request && entry, "CommonOpenCacheEntry: request or entry is null");
NS_ASSERTION(request, "CommonOpenCacheEntry: request or entry is null");
nsCString * key = new nsCString(*session->ClientID() +
nsCString * key = new nsCString(*session->ClientID() +
nsLiteralCString(":") +
nsLiteralCString(clientKey));
if (!key) {
if (!key)
return NS_ERROR_OUT_OF_MEMORY;
}
// create request
*request = new nsCacheRequest(key, listener, accessRequested,
session->StreamBased(),
session->StoragePolicy());
// procure active entry
return ActivateEntry(*request, entry);
if (!*request) {
delete key;
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;
}
@@ -213,16 +207,18 @@ nsCacheService::OpenCacheEntry(nsCacheSession * session,
nsCacheRequest * request = nsnull;
nsCacheEntry * entry = nsnull;
nsresult rv = CommonOpenCacheEntry(session, key, accessRequested, nsnull,
&request, &entry);
nsresult rv = CreateRequest(session, key, accessRequested, nsnull, &request);
if (NS_FAILED(rv)) return rv;
while (1) {
rv = entry->Open(request, result);
if (rv != NS_ERROR_CACHE_ENTRY_DOOMED) break;
//** acquire lock
rv = ActivateEntry(request, &entry);
if (NS_FAILED(rv)) break;
//** check for NS_ERROR_CACHE_KEY_NOT_FOUND & READ-ONLY request
rv = entry->Open(request, result); //** release lock before waiting on request
if (rv != NS_ERROR_CACHE_ENTRY_DOOMED) break;
}
return rv;
}
@@ -240,30 +236,29 @@ nsCacheService::AsyncOpenCacheEntry(nsCacheSession * session,
nsCacheRequest * request = nsnull;
nsCacheEntry * entry = nsnull;
nsresult rv = CommonOpenCacheEntry(session, key, accessRequested, listener,
&request, &entry);
nsresult rv = CreateRequest(session, key, accessRequested, listener, &request);
//** acquire lock
rv = ActivateEntry(request, &entry);
if (NS_SUCCEEDED(rv)) {
entry->AsyncOpen(request);
entry->AsyncOpen(request); //** release lock after request queued, etc.
}
return rv;
}
nsresult
nsCacheService::ActivateEntry(nsCacheRequest * request,
nsCacheEntry ** result)
{
nsresult rv = NS_OK;
PRBool entryIsNew = PR_FALSE;
nsCacheDevice * device = nsnull;
NS_ASSERTION(request != nsnull, "ActivateEntry called with no request");
if (request == nsnull) return NS_ERROR_NULL_POINTER;
if (result) *result = nsnull;
if ((!request) || (!result)) return NS_ERROR_NULL_POINTER;
nsAutoLock lock(mCacheServiceLock); // hold monitor to keep mActiveEntries coherent
// search active entries (including those not bound to device)
nsCacheEntry *entry = mActiveEntries.GetEntry(request->mKey);
@@ -274,56 +269,46 @@ nsCacheService::ActivateEntry(nsCacheRequest * request,
}
if (!entry) {
entry = new nsCacheEntry(request->mKey, request->mStoragePolicy);
if (!entry)
return NS_ERROR_OUT_OF_MEMORY;
entry = SearchCacheDevices(request->mKey, request->mStoragePolicy);
entryIsNew = PR_TRUE;
rv = mActiveEntries.AddEntry(entry);
if (NS_FAILED(rv)) return rv;
if (!entry) {
//** queue request
if (!(request->mAccessRequested & nsICache::ACCESS_WRITE)) {
// this was a READ-ONLY request
rv = NS_ERROR_CACHE_KEY_NOT_FOUND;
goto end;
}
rv = SearchCacheDevices(entry, &device);
if ((rv == NS_ERROR_CACHE_KEY_NOT_FOUND) &&
!(request->mAccessRequested & nsICache::ACCESS_WRITE)) {
// this was a READ-ONLY request, deallocate entry
//** dealloc entry, call listener with error, etc.
*result = nsnull;
return NS_ERROR_CACHE_KEY_NOT_FOUND;
entry = new nsCacheEntry(request->mKey, request->mStoragePolicy);
if (!entry)
return NS_ERROR_OUT_OF_MEMORY;
}
} else {
//** queue request
rv = mActiveEntries.AddEntry(entry);
if (NS_FAILED(rv)) goto end;
}
end:
*result = entry;
return rv;
}
nsresult
nsCacheService::SearchCacheDevices(nsCacheEntry * entry, nsCacheDevice ** result)
nsCacheEntry *
nsCacheService::SearchCacheDevices(nsCString * key, nsCacheStoragePolicy policy)
{
nsresult rv = NS_OK;
nsCacheDevice * device;
nsCacheEntry * entry = nsnull;
*result = nsnull;
// if we don't alter the device list after initialization,
// we don't have to protect it with the monitor
//** first device
while (device) {
rv = device->ActivateEntryIfFound(entry);
if (NS_SUCCEEDED(rv)) {
*result = device;
break;
} else if (rv != NS_ERROR_CACHE_KEY_NOT_FOUND) {
//** handle errors (no memory, disk full, mismatched streamBased, whatever)
}
//** next device
if ((policy == nsICache::STORE_ANYWHERE) || (policy == nsICache::STORE_IN_MEMORY)) {
entry = mMemoryDevice->FindEntry(key);
}
return rv;
if (!entry &&
((policy == nsICache::STORE_ANYWHERE) || (policy == nsICache::STORE_ON_DISK))) {
//** entry = mDiskDevice->FindEntry(key);
}
return entry;
}
@@ -358,7 +343,9 @@ nsCacheService::DeactivateEntry(nsCacheEntry * entry)
nsCacheDevice * device = entry->CacheDevice();
if (device) {
nsresult rv = device->DeactivateEntry(entry);
if (NS_FAILED(rv)) {
//** what do we do on errors?
}
} else {
//** increment deactivating unbound entry statistic
}

View File

@@ -35,70 +35,6 @@
class nsCacheRequest;
class nsCacheDeviceElement {
private:
friend class nsCacheService;
nsCacheDeviceElement(const char * id, nsCacheDevice * cacheDevice)
: deviceID(id),
device(cacheDevice)
{
PR_INIT_CLIST(&link);
}
~nsCacheDeviceElement() {}
PRCList * GetListNode(void) { return &link; }
static nsCacheDeviceElement * GetInstance(PRCList * qp) {
return (nsCacheDeviceElement*)((char*)qp - offsetof(nsCacheDeviceElement, link));
}
PRCList link;
const char * deviceID;
nsCacheDevice *device;
};
#if 0
typedef struct {
PLDHashNumber keyHash;
char * clientID;
} nsCacheClientHashTableEntry;
class nsCacheClientHashTable
{
public:
nsCacheClientHashTable();
~nsCacheClientHashTable();
nsresult Init();
void AddClientID(const char *clientID);
//** enumerate clientIDs
private:
// PLDHashTable operation callbacks
static const void * GetKey( PLDHashTable *table, PLDHashEntryHdr *entry);
static PLDHashNumber HashKey( PLDHashTable *table, const void *key);
static PRBool MatchEntry( PLDHashTable * table,
const PLDHashEntryHdr * entry,
const void * key);
static void MoveEntry( PLDHashTable *table,
const PLDHashEntryHdr *from,
PLDHashEntryHdr *to);
static void ClearEntry( PLDHashTable *table, PLDHashEntryHdr *entry);
static void Finalize( PLDHashTable *table);
// member variables
static PLDHashTableOps ops;
PLDHashTable table;
PRBool initialized;
};
#endif
/**
* nsCacheService
@@ -135,16 +71,15 @@ public:
private:
nsresult CommonOpenCacheEntry(nsCacheSession * session,
const char * clientKey,
nsCacheAccessMode accessRequested,
nsICacheListener * listener,
nsCacheRequest ** request,
nsCacheEntry ** entry);
nsresult CreateRequest(nsCacheSession * session,
const char * clientKey,
nsCacheAccessMode accessRequested,
nsICacheListener * listener,
nsCacheRequest ** request);
nsresult ActivateEntry(nsCacheRequest * request, nsCacheEntry ** entry);
nsresult SearchCacheDevices(nsCacheEntry *entry, nsCacheDevice ** result);
nsCacheEntry * SearchCacheDevices(nsCString * key, nsCacheStoragePolicy policy);
nsresult Doom(nsCacheEntry * entry);
@@ -162,7 +97,10 @@ private:
static nsCacheService * gService; // there can be only one...
PRLock* mCacheServiceLock;
PRCList mDeviceList;
nsCacheDevice * mMemoryDevice;
nsCacheDevice * mDiskDevice;
// nsCacheClientHashTable mClientIDs;
nsCacheEntryHashTable mActiveEntries;
PRCList mDoomedEntries;

View File

@@ -67,10 +67,10 @@ nsDiskCacheDevice::GetDeviceID()
}
nsresult
nsDiskCacheDevice::ActivateEntryIfFound(nsCacheEntry * entry)
nsCacheEntry *
nsDiskCacheDevice::FindEntry(nsCString * key)
{
return NS_ERROR_CACHE_KEY_NOT_FOUND;
return nsnull;
}

View File

@@ -39,10 +39,10 @@ public:
static nsresult Create(nsCacheDevice **result);
virtual const char * GetDeviceID(void);
virtual nsresult ActivateEntryIfFound( nsCacheEntry * entry );
virtual nsresult DeactivateEntry( nsCacheEntry * entry );
virtual nsresult BindEntry( nsCacheEntry * entry );
virtual const char * GetDeviceID(void);
virtual nsCacheEntry * FindEntry( nsCString * key );
virtual nsresult DeactivateEntry( nsCacheEntry * entry );
virtual nsresult BindEntry( nsCacheEntry * entry );
virtual nsresult GetTransportForEntry( nsCacheEntry * entry,
nsITransport **transport );

View File

@@ -26,8 +26,9 @@
nsMemoryCacheDevice::nsMemoryCacheDevice()
: mCurrentTotal(0)
{
PR_INIT_CLIST(&mEvictionList);
}
nsMemoryCacheDevice::~nsMemoryCacheDevice()
@@ -49,22 +50,6 @@ nsMemoryCacheDevice::Init()
}
nsresult
nsMemoryCacheDevice::Create(nsCacheDevice **result)
{
nsMemoryCacheDevice * device = new nsMemoryCacheDevice();
if (!device) return NS_ERROR_OUT_OF_MEMORY;
nsresult rv = device->Init();
if (NS_FAILED(rv)) {
delete device;
device = nsnull;
}
*result = device;
return rv;
}
const char *
nsMemoryCacheDevice::GetDeviceID()
{
@@ -72,30 +57,24 @@ nsMemoryCacheDevice::GetDeviceID()
}
nsresult
nsMemoryCacheDevice::ActivateEntryIfFound(nsCacheEntry * entry)
nsCacheEntry *
nsMemoryCacheDevice::FindEntry(nsCString * key)
{
//** get the key from the entry
nsCString * key = nsnull; //** = key from entry
nsCacheEntry * ourEntry = mInactiveEntries.GetEntry(key);
if (!ourEntry) {
return NS_ERROR_CACHE_KEY_NOT_FOUND;
}
nsCacheEntry * entry = mInactiveEntries.GetEntry(key);
if (!entry) return nsnull;
//** need entry->UpdateFrom(ourEntry);
entry->MarkActive(); // so we don't evict it
//** find eviction element and move it to the tail of the queue
return NS_OK;
return entry;;
}
nsresult
nsMemoryCacheDevice::DeactivateEntry(nsCacheEntry * entry)
{
nsCString * key;
entry->GetKey(&key);
nsCString * key = entry->GetKey();
nsCacheEntry * ourEntry = mInactiveEntries.GetEntry(key);
NS_ASSERTION(ourEntry, "DeactivateEntry called for an entry we don't have!");
@@ -103,9 +82,11 @@ nsMemoryCacheDevice::DeactivateEntry(nsCacheEntry * entry)
return NS_ERROR_INVALID_POINTER;
//** need ourEntry->UpdateFrom(entry);
//** MarkInactive(); // to make it evictable again
return NS_ERROR_NOT_IMPLEMENTED;
}
nsresult
nsMemoryCacheDevice::BindEntry(nsCacheEntry * entry)
{
@@ -117,6 +98,7 @@ nsMemoryCacheDevice::BindEntry(nsCacheEntry * entry)
return NS_ERROR_NOT_IMPLEMENTED;
}
nsresult
nsMemoryCacheDevice::GetTransportForEntry( nsCacheEntry * entry,
nsITransport **transport )

View File

@@ -36,16 +36,12 @@ public:
nsMemoryCacheDevice();
virtual ~nsMemoryCacheDevice();
nsresult Init();
virtual nsresult Init();
static nsresult Create(nsCacheDevice **result);
virtual const char * GetDeviceID(void);
virtual nsresult ActivateEntryIfFound( nsCacheEntry * entry );
virtual nsresult DeactivateEntry( nsCacheEntry * entry );
virtual nsresult BindEntry( nsCacheEntry * entry );
virtual const char * GetDeviceID(void);
virtual nsCacheEntry * FindEntry( nsCString * key );
virtual nsresult DeactivateEntry( nsCacheEntry * entry );
virtual nsresult BindEntry( nsCacheEntry * entry );
virtual nsresult GetTransportForEntry( nsCacheEntry * entry,
nsITransport **transport );