r=bz, sr=darin
Code from Alfred Kayser - optimization of nsCacheEntry


git-svn-id: svn://10.0.0.236/trunk@146777 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
mkaply%us.ibm.com 2003-09-11 16:57:40 +00:00
parent b3d24730a2
commit 4e97ecfcc7
4 changed files with 102 additions and 112 deletions

View File

@ -18,7 +18,7 @@
* Rights Reserved.
*
* Contributor(s):
* Gordon Sheridan, 22-February-2001
* Gordon Sheridan <gordon@netscape.com>
*/
@ -44,7 +44,6 @@ nsCacheEntry::nsCacheEntry(nsCString * key,
mExpirationTime(NO_EXPIRATION_TIME),
mFlags(0),
mDataSize(0),
mMetaSize(0),
mCacheDevice(nsnull),
mData(nsnull)
{
@ -130,30 +129,6 @@ nsCacheEntry::TouchData()
}
nsresult
nsCacheEntry::SetMetaDataElement( const char * key,
const char * value)
{
nsresult rv = mMetaData.SetElement(key, value);
if (NS_FAILED(rv))
return rv;
mMetaSize = mMetaData.Size(); // calc new meta data size
return rv;
}
nsresult
nsCacheEntry::UnflattenMetaData(char * buffer, PRUint32 bufSize)
{
NS_ASSERTION(mMetaData.IsEmpty(), "meta data not empty");
nsresult rv = mMetaData.UnflattenMetaData(buffer, bufSize);
if (NS_SUCCEEDED(rv))
mMetaSize = mMetaData.Size();
return rv;
}
void
nsCacheEntry::TouchMetaData()
{

View File

@ -18,7 +18,7 @@
* Rights Reserved.
*
* Contributor(s):
* Gordon Sheridan, 22-February-2001
* Gordon Sheridan <gordon@netscape.com>
*/
#ifndef _nsCacheEntry_h_
@ -63,33 +63,33 @@ public:
nsCString * Key() { return mKey; }
PRInt32 FetchCount() { return mFetchCount;}
void SetFetchCount( PRInt32 count) { mFetchCount = count;}
PRInt32 FetchCount() { return mFetchCount; }
void SetFetchCount( PRInt32 count) { mFetchCount = count; }
void Fetched();
PRUint32 LastFetched() { return mLastFetched;}
void SetLastFetched( PRUint32 lastFetched) { mLastFetched = lastFetched;}
PRUint32 LastFetched() { return mLastFetched; }
void SetLastFetched( PRUint32 lastFetched) { mLastFetched = lastFetched; }
PRUint32 LastModified() { return mLastModified;}
void SetLastModified( PRUint32 lastModified) { mLastModified = lastModified;}
PRUint32 LastModified() { return mLastModified; }
void SetLastModified( PRUint32 lastModified) { mLastModified = lastModified; }
PRUint32 ExpirationTime() { return mExpirationTime;}
void SetExpirationTime( PRUint32 expires) { mExpirationTime = expires;}
PRUint32 ExpirationTime() { return mExpirationTime; }
void SetExpirationTime( PRUint32 expires) { mExpirationTime = expires; }
PRUint32 Size() { return mDataSize + mMetaSize; }
PRUint32 Size() { return mDataSize + mMetaData.Size(); }
nsCacheDevice * CacheDevice() { return mCacheDevice;}
void SetCacheDevice( nsCacheDevice * device) { mCacheDevice = device;}
nsCacheDevice * CacheDevice() { return mCacheDevice; }
void SetCacheDevice( nsCacheDevice * device) { mCacheDevice = device; }
const char * GetDeviceID();
/**
* Data accessors
*/
nsresult GetData( nsISupports ** result);
void SetData( nsISupports * data) { mData = data;}
void SetData( nsISupports * data) { mData = data; }
PRUint32 DataSize() { return mDataSize;}
void SetDataSize( PRUint32 size) { mDataSize = size;}
PRUint32 DataSize() { return mDataSize; }
void SetDataSize( PRUint32 size) { mDataSize = size; }
void TouchData();
@ -100,14 +100,11 @@ public:
*/
const char * GetMetaDataElement( const char * key) { return mMetaData.GetElement(key); }
nsresult SetMetaDataElement( const char * key,
const char * value);
const char * value) { return mMetaData.SetElement(key, value); }
nsresult VisitMetaDataElements( nsICacheMetaDataVisitor * visitor) { return mMetaData.VisitElements(visitor); }
nsresult FlattenMetaData( char * buffer, PRUint32 bufSize) { return mMetaData.FlattenMetaData(buffer, bufSize); }
nsresult UnflattenMetaData( char * buffer, PRUint32 bufSize);
PRUint32 MetaDataSize() { return mMetaSize;}
nsresult FlattenMetaData(char * buffer, PRUint32 bufSize) { return mMetaData.FlattenMetaData(buffer, bufSize); }
nsresult UnflattenMetaData(char * buffer, PRUint32 bufSize) { return mMetaData.UnflattenMetaData(buffer, bufSize); }
PRUint32 MetaDataSize() { return mMetaData.Size(); }
void TouchMetaData();
@ -224,7 +221,6 @@ private:
PRUint32 mExpirationTime; // 4
PRUint32 mFlags; // 4
PRUint32 mDataSize; // 4
PRUint32 mMetaSize; // 4
nsCacheDevice * mCacheDevice; // 4
nsCOMPtr<nsISupports> mSecurityInfo; //
nsCOMPtr<nsISupports> mData; //

View File

@ -4,21 +4,21 @@
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
*
* The Original Code is nsCacheMetaData.cpp, released February 22, 2001.
*
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Gordon Sheridan, 22-February-2001
*
* Contributor(s):
* Gordon Sheridan <gordon@netscape.com>
*/
#include "nsCacheMetaData.h"
@ -27,15 +27,15 @@
#include "nsReadableUtils.h"
#include "plstr.h"
nsCacheMetaData::nsCacheMetaData()
: mData(nsnull)
: mData(nsnull), mMetaSize(0)
{
}
void
nsCacheMetaData::Clear()
{
mMetaSize = 0;
MetaElement * elem;
while (mData) {
elem = mData->mNext;
@ -70,15 +70,27 @@ nsCacheMetaData::SetElement(const char * key,
if (!keyAtom)
return NS_ERROR_OUT_OF_MEMORY;
// find and remove old meta data element
PRUint32 keySize = strlen(key);
PRUint32 valueSize = value ? strlen(value) : 0;
// find and remove or update old meta data element
MetaElement * elem = mData, * last = nsnull;
while (elem) {
if (elem->mKey == keyAtom) {
// Get length of old value
PRUint32 oldValueLen = strlen(elem->mValue);
if (valueSize == oldValueLen) {
// Just replace value
memcpy(elem->mValue, value, valueSize);
return NS_OK;
}
// remove elem
if (last)
last->mNext = elem->mNext;
else
mData = elem->mNext;
// 2 for the zero bytes of both strings
mMetaSize -= 2 + keySize + oldValueLen;
delete elem;
break;
}
@ -88,7 +100,7 @@ nsCacheMetaData::SetElement(const char * key,
// allocate new meta data element
if (value) {
elem = new (value) MetaElement;
elem = new (value, valueSize) MetaElement;
if (!elem)
return NS_ERROR_OUT_OF_MEMORY;
elem->mKey = keyAtom;
@ -102,80 +114,82 @@ nsCacheMetaData::SetElement(const char * key,
elem->mNext = mData;
mData = elem;
}
// Adjust CacheMetaData size, 2 for the zero bytes of both strings
mMetaSize += 2 + keySize + valueSize;
}
return NS_OK;
}
PRUint32
nsCacheMetaData::Size(void)
{
PRUint32 size = 0;
const char *key;
// XXX this should be computed in SetElement
MetaElement * elem = mData;
while (elem) {
elem->mKey->GetUTF8String(&key);
size += (2 + strlen(key) + strlen(elem->mValue));
elem = elem->mNext;
}
return size;
}
nsresult
nsCacheMetaData::FlattenMetaData(char * buffer, PRUint32 bufSize)
{
const char *key;
PRUint32 metaSize = 0;
if (mMetaSize > bufSize) {
NS_ERROR("buffer size too small for meta data.");
return NS_ERROR_OUT_OF_MEMORY;
}
MetaElement * elem = mData;
while (elem) {
elem->mKey->GetUTF8String(&key);
PRUint32 keySize = 1 + strlen(key);
PRUint32 valSize = 1 + strlen(elem->mValue);
if ((metaSize + keySize + valSize) > bufSize) {
// not enough space to copy key/value pair
NS_ERROR("buffer size too small for meta data.");
return NS_ERROR_OUT_OF_MEMORY;
}
memcpy(buffer, key, keySize);
buffer += keySize;
PRUint32 valSize = 1 + strlen(elem->mValue);
memcpy(buffer, elem->mValue, valSize);
buffer += valSize;
metaSize += keySize + valSize;
elem = elem->mNext;
}
return NS_OK;
}
nsresult
nsCacheMetaData::UnflattenMetaData(char * data, PRUint32 size)
{
if (size == 0) return NS_OK;
if (size == 0) return NS_OK;
nsresult rv = NS_ERROR_UNEXPECTED;
char* limit = data + size;
MetaElement * last = nsnull;
while (data < limit) {
const char* name = data;
PRUint32 nameSize = strlen(name);
data += 1 + nameSize;
const char* key = data;
PRUint32 keySize = strlen(key);
data += 1 + keySize;
if (data < limit) {
const char* value = data;
PRUint32 valueSize = strlen(value);
nsCOMPtr<nsIAtom> keyAtom = do_GetAtom(key);
if (!keyAtom)
return NS_ERROR_OUT_OF_MEMORY;
PRUint32 valueSize = strlen(data);
MetaElement *elem = new (data, valueSize) MetaElement;
if (!elem)
return NS_ERROR_OUT_OF_MEMORY;
elem->mKey = keyAtom;
// insert after last or as first element...
if (last) {
elem->mNext = last->mNext;
last->mNext = elem;
}
else {
elem->mNext = mData;
mData = elem;
}
last = elem;
data += 1 + valueSize;
rv = SetElement(name, value);
if (NS_FAILED(rv)) break;
// Adjust CacheMetaData size, 2 for the zero bytes of both strings
mMetaSize += 2 + keySize + valueSize;
}
}
return rv;
return NS_OK;
}
nsresult
@ -200,16 +214,18 @@ nsCacheMetaData::VisitElements(nsICacheMetaDataVisitor * visitor)
}
void *
nsCacheMetaData::MetaElement::operator new(size_t size, const char *value) CPP_THROW_NEW
nsCacheMetaData::MetaElement::operator new(size_t size,
const char *value,
PRUint32 valueSize) CPP_THROW_NEW
{
int len = strlen(value);
size += len;
size += valueSize;
MetaElement *elem = (MetaElement *) ::operator new(size);
if (!elem)
return nsnull;
memcpy(elem->mValue, value, len);
elem->mValue[len] = 0;
memcpy(elem->mValue, value, valueSize);
elem->mValue[valueSize] = 0;
return elem;
}

View File

@ -4,21 +4,21 @@
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
*
* The Original Code is nsCacheMetaData.h, released February 22, 2001.
*
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 2001 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Gordon Sheridan, 22-February-2001
*
* Contributor(s):
* Gordon Sheridan <gordon@netscape.com>
*/
#ifndef _nsCacheMetaData_h_
@ -44,10 +44,10 @@ public:
nsresult SetElement(const char * key,
const char * value);
PRUint32 Size(void);
PRUint32 Size(void) { return mMetaSize; }
nsresult FlattenMetaData(char * buffer, PRUint32 bufSize);
nsresult UnflattenMetaData(char * buffer, PRUint32 bufSize);
nsresult VisitElements(nsICacheMetaDataVisitor * visitor);
@ -61,10 +61,13 @@ private:
char mValue[1]; // actually, bigger than 1
// MetaElement and mValue are allocated together via:
void *operator new(size_t size, const char *value) CPP_THROW_NEW;
void *operator new(size_t size,
const char *value,
PRUint32 valueSize) CPP_THROW_NEW;
};
MetaElement * mData;
PRUint32 mMetaSize;
};
#endif // _nsCacheMetaData_h