In support of bug #8305 (Cache implementation), added new type of hash-table
key, an array of opaque data, not owned by the key. r: dougt git-svn-id: svn://10.0.0.236/trunk@53609 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -454,3 +454,68 @@ nsSupportsHashtable::Reset()
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsOpaqueKey: Where keys are opaque byte array blobs
|
||||
//
|
||||
|
||||
// Note opaque keys are not copied by this constructor. If you want a private
|
||||
// copy in each hash key, you must create one and pass it in to this function.
|
||||
nsOpaqueKey::nsOpaqueKey(const char *aOpaqueKey, PRUint32 aKeyLength)
|
||||
{
|
||||
mOpaqueKey = aOpaqueKey;
|
||||
mKeyLength = aKeyLength;
|
||||
}
|
||||
|
||||
nsOpaqueKey::~nsOpaqueKey(void)
|
||||
{
|
||||
}
|
||||
|
||||
PRUint32
|
||||
nsOpaqueKey::HashValue(void) const
|
||||
{
|
||||
PRUint32 h, i, k;
|
||||
|
||||
h = 0;
|
||||
|
||||
// Same hashing technique as for java.lang.String.hashCode()
|
||||
if (mKeyLength <= 15) {
|
||||
// A short key; Use a dense sampling to compute the hash code
|
||||
for (i = 0; i < mKeyLength; i++)
|
||||
h += 37 * mOpaqueKey[i];
|
||||
} else {
|
||||
// A long key; Use a sparse sampling to compute the hash code
|
||||
k = mKeyLength >> 3;
|
||||
for (i = 0; i < mKeyLength; i += k)
|
||||
h += 39 * mOpaqueKey[i];
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsOpaqueKey::Equals(const nsHashKey* aKey) const
|
||||
{
|
||||
nsOpaqueKey *otherKey = (nsOpaqueKey*)aKey;
|
||||
if (mKeyLength != otherKey->mKeyLength)
|
||||
return PR_FALSE;
|
||||
return !(PRBool)memcmp(otherKey->mOpaqueKey, mOpaqueKey, mKeyLength);
|
||||
}
|
||||
|
||||
nsHashKey*
|
||||
nsOpaqueKey::Clone() const
|
||||
{
|
||||
return new nsOpaqueKey(mOpaqueKey, mKeyLength);
|
||||
}
|
||||
|
||||
PRUint32
|
||||
nsOpaqueKey::GetKeyLength() const
|
||||
{
|
||||
return mKeyLength;
|
||||
}
|
||||
|
||||
const char*
|
||||
nsOpaqueKey::GetKey() const
|
||||
{
|
||||
return mOpaqueKey;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@@ -218,5 +218,31 @@ public:
|
||||
const nsString& GetString() const;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsOpaqueKey: Where keys are opaque byte-array blobs
|
||||
|
||||
#include "nsString.h"
|
||||
|
||||
class NS_COM nsOpaqueKey : public nsHashKey {
|
||||
protected:
|
||||
const char* mOpaqueKey; // Byte array of opaque data
|
||||
PRUint32 mKeyLength; // Length, in bytes, of mOpaqueKey
|
||||
|
||||
public:
|
||||
// Note opaque keys are not copied by this constructor. If you want a private
|
||||
// copy in each hash key, you must create one and pass it in to this function.
|
||||
nsOpaqueKey(const char* aOpaqueKey, PRUint32 aKeyLength);
|
||||
|
||||
~nsOpaqueKey(void);
|
||||
|
||||
PRUint32 HashValue(void) const;
|
||||
PRBool Equals(const nsHashKey* aKey) const;
|
||||
nsHashKey* Clone() const;
|
||||
|
||||
// For when the owner of the hashtable wants to peek at the actual
|
||||
// opaque array in the key. No copy is made, so be careful.
|
||||
const char* GetKey() const;
|
||||
PRUint32 GetKeyLength() const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -63,7 +63,7 @@ struct nsHashEnumClosure
|
||||
void *Data;
|
||||
};
|
||||
|
||||
nsresult
|
||||
extern "C" NS_COM nsresult
|
||||
NS_NewHashtableEnumerator (nsHashtable *aHash,
|
||||
NS_HASH_ENUMERATOR_CONVERTER aConverter,
|
||||
void *aData, nsIEnumerator **retval)
|
||||
@@ -185,14 +185,13 @@ nsHashtableEnumerator::Last ()
|
||||
NS_IMETHODIMP
|
||||
nsHashtableEnumerator::Prev ()
|
||||
{
|
||||
if (!mElements || (mCount == 0) || (mCurrent == 0))
|
||||
if (!mElements || (mCount == 0) || (mCurrent == 0)) {
|
||||
mDoneFlag = PR_TRUE;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mCurrent--;
|
||||
if (mCurrent == 0)
|
||||
mDoneFlag = PR_TRUE;
|
||||
else
|
||||
mDoneFlag = PR_FALSE;
|
||||
mDoneFlag = PR_FALSE;
|
||||
|
||||
return NS_OK;
|
||||
|
||||
@@ -201,17 +200,15 @@ nsHashtableEnumerator::Prev ()
|
||||
NS_IMETHODIMP
|
||||
nsHashtableEnumerator::Next ()
|
||||
{
|
||||
if (!mElements || (mCount == 0) || (mCurrent == mCount - 1))
|
||||
if (!mElements || (mCount == 0) || (mCurrent == mCount - 1)) {
|
||||
mDoneFlag = PR_TRUE;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mCurrent++;
|
||||
if (mCurrent == mCount - 1)
|
||||
mDoneFlag = PR_TRUE;
|
||||
else
|
||||
mDoneFlag = PR_FALSE;
|
||||
mDoneFlag = PR_FALSE;
|
||||
|
||||
return NS_OK;
|
||||
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@@ -244,8 +241,7 @@ nsHashtableEnumerator::IsDone ()
|
||||
{
|
||||
|
||||
if ((!mElements) || (mCount == 0) || (mDoneFlag))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return NS_OK;
|
||||
return NS_OK;
|
||||
|
||||
return NS_COMFALSE;
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ typedef NS_CALLBACK(NS_HASH_ENUMERATOR_CONVERTER) (nsHashKey *key, void *data,
|
||||
void *convert_data,
|
||||
nsISupports **retval);
|
||||
|
||||
extern nsresult
|
||||
extern "C" NS_COM nsresult
|
||||
NS_NewHashtableEnumerator (nsHashtable *aHash,
|
||||
NS_HASH_ENUMERATOR_CONVERTER aConverter,
|
||||
void *aData, nsIEnumerator **retval);
|
||||
|
||||
Reference in New Issue
Block a user