diff --git a/mozilla/netwerk/cache/src/nsCacheEntry.cpp b/mozilla/netwerk/cache/src/nsCacheEntry.cpp index 00debba80af..3bfe57bedf6 100644 --- a/mozilla/netwerk/cache/src/nsCacheEntry.cpp +++ b/mozilla/netwerk/cache/src/nsCacheEntry.cpp @@ -67,9 +67,8 @@ nsCacheEntry::nsCacheEntry(nsCString * key, nsCacheEntry::~nsCacheEntry() { - if (mCacheDevice) { - //** ask device to clean up - } + delete mKey; + delete mMetaData; } @@ -105,12 +104,9 @@ nsCacheEntry::SetMetaDataElement( const nsAReadableCString& key, const nsAReadableCString& value) { if (!mMetaData) { - mMetaData = new nsCacheMetaData(); + mMetaData = nsCacheMetaData::Create(); if (!mMetaData) return NS_ERROR_OUT_OF_MEMORY; - nsresult rv = mMetaData->Init(); - if (NS_FAILED(rv)) - return rv; } nsresult rv = mMetaData->SetElement(key, value); if (NS_SUCCEEDED(rv)) @@ -135,15 +131,6 @@ nsCacheEntry::GetKeyValueArray(nsCacheMetaDataKeyValuePair ** array, } -void -nsCacheEntry::MarkValid() -{ - //** bind if not bound - //** convert pending requests to descriptors, etc. - mFlags |= eValidMask; -} - - /** * cache entry states * 0 descriptors (new entry) diff --git a/mozilla/netwerk/cache/src/nsCacheEntry.h b/mozilla/netwerk/cache/src/nsCacheEntry.h index ceecec9fcbf..fc6ed7f406a 100644 --- a/mozilla/netwerk/cache/src/nsCacheEntry.h +++ b/mozilla/netwerk/cache/src/nsCacheEntry.h @@ -103,16 +103,20 @@ public: }; - void MarkDoomed() { mFlags |= eDoomedMask; } - void MarkEntryDirty() { mFlags |= eEntryDirtyMask; } - void MarkDataDirty() { mFlags |= eDataDirtyMask; } - void MarkMetaDataDirty() { mFlags |= eMetaDataDirtyMask; } - void MarkStreamData() { mFlags |= eStreamDataMask; } - void MarkActive() { mFlags |= eActiveMask; } + void MarkDoomed() { mFlags |= eDoomedMask; } + void MarkEntryDirty() { mFlags |= eEntryDirtyMask; } + void MarkEntryClean() { mFlags &= ~eEntryDirtyMask; } + void MarkDataDirty() { mFlags |= eDataDirtyMask; } + void MarkDataClean() { mFlags &= ~eDataDirtyMask; } + void MarkMetaDataDirty() { mFlags |= eMetaDataDirtyMask; } + void MarkMetaDataClean() { mFlags &= ~eMetaDataDirtyMask; } + void MarkStreamData() { mFlags |= eStreamDataMask; } + void MarkActive() { mFlags |= eActiveMask; } void MarkInactive() { mFlags &= ~eActiveMask; } - void MarkValid(); - void MarkAllowedInMemory() { mFlags |= eAllowedInMemoryMask; } - void MarkAllowedOnDisk() { mFlags |= eAllowedOnDiskMask; } + void MarkValid() { mFlags |= eValidMask; } + void MarkInvalid() { mFlags &= ~eValidMask; } + void MarkAllowedInMemory() { mFlags |= eAllowedInMemoryMask; } + void MarkAllowedOnDisk() { mFlags |= eAllowedOnDiskMask; } PRBool IsDoomed() { return (mFlags & eDoomedMask) != 0; } PRBool IsEntryDirty() { return (mFlags & eEntryDirtyMask) != 0; } diff --git a/mozilla/netwerk/cache/src/nsCacheEntryDescriptor.cpp b/mozilla/netwerk/cache/src/nsCacheEntryDescriptor.cpp index 347d56860b1..0e41d349a3e 100644 --- a/mozilla/netwerk/cache/src/nsCacheEntryDescriptor.cpp +++ b/mozilla/netwerk/cache/src/nsCacheEntryDescriptor.cpp @@ -316,17 +316,13 @@ nsCacheEntryDescriptor::GetMetaDataElement(const char *key, char ** result) if (NS_SUCCEEDED(rv) && (value)) { *result = ToNewCString(*value); if (!*result) rv = NS_ERROR_OUT_OF_MEMORY; - else { - NS_ASSERTION(PR_FALSE, "FindCharInRead failed to find ':'"); - rv = NS_ERROR_UNEXPECTED; - } } return rv; } NS_IMETHODIMP -nsCacheEntryDescriptor::SetMetadataElement(const char *key, const char *value) +nsCacheEntryDescriptor::SetMetaDataElement(const char *key, const char *value) { if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE; diff --git a/mozilla/netwerk/cache/src/nsCacheMetaData.cpp b/mozilla/netwerk/cache/src/nsCacheMetaData.cpp index b1b090c408c..3c2c2aded5b 100644 --- a/mozilla/netwerk/cache/src/nsCacheMetaData.cpp +++ b/mozilla/netwerk/cache/src/nsCacheMetaData.cpp @@ -68,17 +68,41 @@ nsCacheMetaData::Init() } +nsCacheMetaData * +nsCacheMetaData::Create() +{ + nsCacheMetaData * metaData = new nsCacheMetaData(); + if (!metaData) + return nsnull; + + nsresult rv = metaData->Init(); + if (NS_FAILED(rv)) { + delete metaData; + return nsnull; + } + + return metaData; +} + + nsAReadableCString * nsCacheMetaData::GetElement(const nsAReadableCString * key) { PLDHashEntryHdr * hashEntry; nsCString * result = nsnull; + //** need to copy string until we have scc's new flat string abstract class + //** see nsCacheMetaData::HashKey below (bug 70075) + nsCString * tempKey = new nsCString(*key); + if (!tempKey) return result; + NS_ASSERTION(initialized, "nsCacheMetaDataHashTable not initialized"); - hashEntry = PL_DHashTableOperate(&table, key, PL_DHASH_LOOKUP); + hashEntry = PL_DHashTableOperate(&table, tempKey, PL_DHASH_LOOKUP); if (PL_DHASH_ENTRY_IS_BUSY(hashEntry)) { result = ((nsCacheMetaDataHashTableEntry *)hashEntry)->value; } + + delete tempKey; return result; } @@ -87,29 +111,38 @@ nsresult nsCacheMetaData::SetElement(const nsAReadableCString& key, const nsAReadableCString& value) { - nsCacheMetaDataHashTableEntry * metaEntry; + nsCacheMetaDataHashTableEntry * metaEntry; - NS_ASSERTION(initialized, "nsCacheMetaDataHashTable not initialized"); + NS_ASSERTION(initialized, "nsCacheMetaDataHashTable not initialized"); - //** should empty value remove the key? + //** need to copy string until we have scc's new flat string abstract class + //** see nsCacheMetaData::HashKey below (bug 70075) + nsCString * tempKey = new nsCString(key); + if (!tempKey) return NS_ERROR_OUT_OF_MEMORY; - metaEntry = (nsCacheMetaDataHashTableEntry *) - PL_DHashTableOperate(&table, &key, PL_DHASH_ADD); - if (metaEntry->key == nsnull) { - metaEntry->key = new nsCString(key); - if (metaEntry->key == nsnull) - return NS_ERROR_OUT_OF_MEMORY; - } - if (metaEntry->value != nsnull) - delete metaEntry->value; + //** should empty value remove the key? - metaEntry->value = new nsCString(value); - if (metaEntry->value == nsnull) { - //** remove key? - return NS_ERROR_OUT_OF_MEMORY; - } + metaEntry = (nsCacheMetaDataHashTableEntry *) + PL_DHashTableOperate(&table, tempKey, PL_DHASH_ADD); + if (metaEntry->key == nsnull) { + metaEntry->key = new nsCString(key); + if (metaEntry->key == nsnull) { + delete tempKey; + return NS_ERROR_OUT_OF_MEMORY; + } + } + if (metaEntry->value != nsnull) + delete metaEntry->value; - return NS_OK; + metaEntry->value = new nsCString(value); + if (metaEntry->value == nsnull) { + //** remove key? + delete tempKey; + return NS_ERROR_OUT_OF_MEMORY; + } + + delete tempKey; + return NS_OK; } @@ -144,6 +177,7 @@ nsCacheMetaData::GetKey( PLDHashTable * /* table */, PLDHashEntryHdr *hashEntry) return ((nsCacheMetaDataHashTableEntry *)hashEntry)->key; } + PLDHashNumber nsCacheMetaData::HashKey( PLDHashTable * table, const void *key) { @@ -151,6 +185,7 @@ nsCacheMetaData::HashKey( PLDHashTable * table, const void *key) return PL_DHashStringKey(table, ((nsCString *)key)->get()); } + PRBool nsCacheMetaData::MatchEntry(PLDHashTable * /* table */, const PLDHashEntryHdr * hashEntry, @@ -159,7 +194,8 @@ nsCacheMetaData::MatchEntry(PLDHashTable * /* table */, NS_ASSERTION(key != nsnull, "nsCacheMetaDataHashTable::MatchEntry : null key"); nsCString * entryKey = ((nsCacheMetaDataHashTableEntry *)hashEntry)->key; NS_ASSERTION(entryKey, "hashEntry->key == nsnull"); - return nsStr::StrCompare(*(nsCString *)key, *entryKey, -1, PR_FALSE) == 0; + + return entryKey->Equals(*NS_STATIC_CAST(const nsAReadableCString*,key)); } diff --git a/mozilla/netwerk/cache/src/nsCacheMetaData.h b/mozilla/netwerk/cache/src/nsCacheMetaData.h index 6b7d1af594e..42b9d763a45 100644 --- a/mozilla/netwerk/cache/src/nsCacheMetaData.h +++ b/mozilla/netwerk/cache/src/nsCacheMetaData.h @@ -48,8 +48,11 @@ class nsCacheMetaData { public: nsCacheMetaData(); ~nsCacheMetaData(); - - nsresult Init(); + + static + nsCacheMetaData * Create(void); + + nsresult Init(void); nsAReadableCString * GetElement(const nsAReadableCString * key); diff --git a/mozilla/netwerk/cache/src/nsCacheService.cpp b/mozilla/netwerk/cache/src/nsCacheService.cpp index e820354b2cf..78236b1694a 100644 --- a/mozilla/netwerk/cache/src/nsCacheService.cpp +++ b/mozilla/netwerk/cache/src/nsCacheService.cpp @@ -39,7 +39,9 @@ NS_IMPL_THREADSAFE_ISUPPORTS1(nsCacheService, nsICacheService) nsCacheService::nsCacheService() : mCacheServiceLock(nsnull), mMemoryDevice(nsnull), - mDiskDevice(nsnull) + mDiskDevice(nsnull), + mDeactivateFailures(0), + mDeactivatedUnboundEntries(0) { NS_INIT_REFCNT(); @@ -371,6 +373,17 @@ nsCacheService::BindEntry(nsCacheEntry * entry) } + +nsresult +nsCacheService::ValidateEntry(nsCacheEntry * entry) +{ + //** bind if not bound + //** convert pending requests to descriptors, etc. + entry->MarkValid(); + return NS_OK; +} + + nsresult nsCacheService::DoomEntry(nsCacheEntry * entry) { @@ -463,15 +476,26 @@ nsCacheService::CloseDescriptor(nsCacheEntryDescriptor * descriptor) void nsCacheService::DeactivateEntry(nsCacheEntry * entry) { - //** check if entry is doomed - //** remove from hashtable + nsresult rv = NS_OK; + + if (entry->IsDoomed()) { + // remove from Doomed list + PR_REMOVE_AND_INIT_LINK(entry->GetListNode()); + } else { + // remove from active entries + rv = mActiveEntries.RemoveEntry(entry); + NS_ASSERTION(NS_SUCCEEDED(rv),"failed to remove an active entry !?!"); + } + nsCacheDevice * device = entry->CacheDevice(); if (device) { - nsresult rv = device->DeactivateEntry(entry); + rv = device->DeactivateEntry(entry); if (NS_FAILED(rv)) { - //** what do we do on errors? + // increment deactivate failure count + ++mDeactivateFailures; } } else { - //** increment deactivating unbound entry statistic + // increment deactivating unbound entry statistic + ++mDeactivatedUnboundEntries; } } diff --git a/mozilla/netwerk/cache/src/nsCacheService.h b/mozilla/netwerk/cache/src/nsCacheService.h index 70889ad5b0c..6da5467ee00 100644 --- a/mozilla/netwerk/cache/src/nsCacheService.h +++ b/mozilla/netwerk/cache/src/nsCacheService.h @@ -73,6 +73,8 @@ public: nsresult OnDataSizeChange(nsCacheEntry * entry, PRInt32 deltaSize); + nsresult ValidateEntry(nsCacheEntry * entry); + nsresult GetTransportForEntry(nsCacheEntry * entry, nsCacheAccessMode mode, nsITransport ** result); @@ -128,6 +130,10 @@ private: // nsCacheClientHashTable mClientIDs; nsCacheEntryHashTable mActiveEntries; PRCList mDoomedEntries; + + // Unexpected error totals + PRUint32 mDeactivateFailures; + PRUint32 mDeactivatedUnboundEntries; }; diff --git a/mozilla/netwerk/cache/src/nsMemoryCacheDevice.cpp b/mozilla/netwerk/cache/src/nsMemoryCacheDevice.cpp index f6a2308359a..5a80e0f5ad7 100644 --- a/mozilla/netwerk/cache/src/nsMemoryCacheDevice.cpp +++ b/mozilla/netwerk/cache/src/nsMemoryCacheDevice.cpp @@ -43,7 +43,7 @@ nsMemoryCacheDevice::Init() { nsresult rv; - rv = mInactiveEntries.Init(); + rv = mMemCacheEntries.Init(); //** read user prefs for memory cache limits @@ -61,12 +61,14 @@ nsMemoryCacheDevice::GetDeviceID() nsCacheEntry * nsMemoryCacheDevice::FindEntry(nsCString * key) { - nsCacheEntry * entry = mInactiveEntries.GetEntry(key); + nsCacheEntry * entry = mMemCacheEntries.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 + + // move entry to the tail of the eviction list + PR_REMOVE_AND_INIT_LINK(entry->GetListNode()); + PR_APPEND_LINK(entry->GetListNode(), &mEvictionList); return entry;; } @@ -75,25 +77,39 @@ nsMemoryCacheDevice::FindEntry(nsCString * key) nsresult nsMemoryCacheDevice::DeactivateEntry(nsCacheEntry * entry) { - nsCString * key = entry->Key(); + if (entry->IsDoomed()) { +#if debug + //** verify we've removed it from mMemCacheEntries & eviction list +#endif + delete entry; + return NS_OK; + } - nsCacheEntry * ourEntry = mInactiveEntries.GetEntry(key); + nsCacheEntry * ourEntry = mMemCacheEntries.GetEntry(entry->Key()); NS_ASSERTION(ourEntry, "DeactivateEntry called for an entry we don't have!"); - if (!ourEntry) + NS_ASSERTION(entry == ourEntry, "entry doesn't match ourEntry"); + if (ourEntry != entry) return NS_ERROR_INVALID_POINTER; - //** need ourEntry->UpdateFrom(entry); - //** MarkInactive(); // to make it evictable again - return NS_ERROR_NOT_IMPLEMENTED; + entry->MarkInactive(); // to make it evictable again + return NS_OK; } nsresult nsMemoryCacheDevice::BindEntry(nsCacheEntry * entry) { - nsresult rv = mInactiveEntries.AddEntry(entry); - if (NS_FAILED(rv)) + NS_ASSERTION(PR_CLIST_IS_EMPTY(entry->GetListNode()),"entry is already on a list!"); + + // append entry to the eviction list + PR_APPEND_LINK(entry->GetListNode(), &mEvictionList); + + // add entry to hashtable of mem cache entries + nsresult rv = mMemCacheEntries.AddEntry(entry); + if (NS_FAILED(rv)) { + PR_REMOVE_AND_INIT_LINK(entry->GetListNode()); return rv; + } //** add size of entry to memory totals return NS_OK; @@ -103,7 +119,14 @@ nsMemoryCacheDevice::BindEntry(nsCacheEntry * entry) nsresult nsMemoryCacheDevice::DoomEntry(nsCacheEntry * entry) { - return NS_ERROR_NOT_IMPLEMENTED; + nsresult rv = mMemCacheEntries.RemoveEntry(entry); + NS_ASSERTION(NS_SUCCEEDED(rv), "dooming entry that we don't have"); + if (NS_FAILED(rv)) return rv; + + // remove entry from our eviction list + PR_REMOVE_AND_INIT_LINK(entry->GetListNode()); + + return NS_OK; } diff --git a/mozilla/netwerk/cache/src/nsMemoryCacheDevice.h b/mozilla/netwerk/cache/src/nsMemoryCacheDevice.h index 43ef80efdc3..d1bd526ecd3 100644 --- a/mozilla/netwerk/cache/src/nsMemoryCacheDevice.h +++ b/mozilla/netwerk/cache/src/nsMemoryCacheDevice.h @@ -51,10 +51,10 @@ public: virtual nsresult OnDataSizeChange( nsCacheEntry * entry, PRInt32 deltaSize ); private: - nsCacheEntryHashTable mInactiveEntries; + nsCacheEntryHashTable mMemCacheEntries; - PRUint32 mTemporaryMaxLimit; - PRUint32 mNormalMaxLimit; + PRUint32 mHardLimit; + PRUint32 mSoftLimit; PRUint32 mCurrentTotal; PRCList mEvictionList; @@ -62,49 +62,5 @@ private: //** what other stats do we want to keep? }; -#if 0 -class nsMemoryCacheEntry -{ -public: - - - nsMemoryCacheEntry(nsCacheEntry *entry) - { - PR_INIT_CLIST(&mListLink); - entry->GetKey(&mKey); - GetFetchCount(&mFetchCount); - GetLastFetched(&mLastFetched); - GetLastValidated(&mLastValidated); - GetExpirationTime(&mExpirationTime); - //** flags - GetDataSize(&mDataSize); - GetMetaDataSize(&mMetaSize); - GetData(getter_AddRefs(mData)); //** check about ownership - GetMetaData - } - - ~nsMemoryCacheEntry() {} - - PRCList * GetListNode(void) { return &mListLink; } - static nsMemoryCacheEntry * GetInstance(PRCList * qp) { - return (nsMemoryCacheEntry*)((char*)qp - - offsetof(nsMemoryCacheEntry, mListLink)); - } - - -private: - PRCList mListLink; // 8 - nsCString * mKey; // 4 //** ask scc about const'ness - PRUint32 mFetchCount; // 4 - PRTime mLastFetched; // 8 - PRTime mLastValidated; // 8 - PRTime mExpirationTime; // 8 - PRUint32 mFlags; // 4 - PRUint32 mDataSize; // 4 - PRUint32 mMetaSize; // 4 - nsCOMPtr mData; // 4 //** issues with updating/replacing - nsCacheMetaData * mMetaData; // 4 -}; -#endif #endif // _nsMemoryCacheDevice_h_