From 3295a722e93ea44be94336d0d09eb971aaadd2fa Mon Sep 17 00:00:00 2001 From: "warren%netscape.com" Date: Wed, 28 Jul 1999 07:56:28 +0000 Subject: [PATCH] Added nsObjectHashtable (for automatically copying and destroying elements). Also nsSupportsHashtable for refcounted elements. git-svn-id: svn://10.0.0.236/trunk@41449 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/xpcom/ds/nsHashtable.cpp | 138 ++++++++++++++++++++++++++++++- mozilla/xpcom/ds/nsHashtable.h | 43 ++++++++++ 2 files changed, 178 insertions(+), 3 deletions(-) diff --git a/mozilla/xpcom/ds/nsHashtable.cpp b/mozilla/xpcom/ds/nsHashtable.cpp index 8cde7daa6b0..9dafd771b60 100644 --- a/mozilla/xpcom/ds/nsHashtable.cpp +++ b/mozilla/xpcom/ds/nsHashtable.cpp @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * The contents of this file are subject to the Netscape Public License * Version 1.0 (the "NPL"); you may not use this file except in @@ -187,7 +187,10 @@ void *nsHashtable::Remove(nsHashKey *aKey) { return res; } -static PR_CALLBACK PRIntn _hashEnumerateCopy(PLHashEntry *he, PRIntn i, void *arg) +// XXX This method was called _hashEnumerateCopy, but it didn't copy the element! +// I don't know how this was supposed to work since the elements are neither copied +// nor refcounted. +static PR_CALLBACK PRIntn _hashEnumerateShare(PLHashEntry *he, PRIntn i, void *arg) { nsHashtable *newHashtable = (nsHashtable *)arg; newHashtable->Put((nsHashKey *) he->key, he->value); @@ -200,7 +203,7 @@ nsHashtable * nsHashtable::Clone() { threadSafe = PR_TRUE; nsHashtable *newHashTable = new nsHashtable(hashtable->nentries, threadSafe); - PL_HashTableEnumerateEntries(hashtable, _hashEnumerateCopy, newHashTable); + PL_HashTableEnumerateEntries(hashtable, _hashEnumerateShare, newHashTable); return newHashTable; } @@ -279,3 +282,132 @@ nsHashKey* nsStringKey::Clone() const } //////////////////////////////////////////////////////////////////////////////// +// nsObjectHashtable: an nsHashtable where the elements are C++ objects to be +// deleted + +nsObjectHashtable::nsObjectHashtable(nsHashtableCloneElementFunc cloneElementFun, + void* cloneElementClosure, + nsHashtableEnumFunc destroyElementFun, + void* destroyElementClosure, + PRUint32 aSize, PRBool threadSafe) + : nsHashtable(aSize, threadSafe), + mCloneElementFun(cloneElementFun), + mCloneElementClosure(cloneElementClosure), + mDestroyElementFun(destroyElementFun), + mDestroyElementClosure(destroyElementClosure) +{ +} + +nsObjectHashtable::~nsObjectHashtable() +{ + Enumerate(mDestroyElementFun, mDestroyElementClosure); +} + +PR_CALLBACK PRIntn +nsObjectHashtable::CopyElement(PLHashEntry *he, PRIntn i, void *arg) +{ + nsObjectHashtable *newHashtable = (nsObjectHashtable *)arg; + void* newElement = + newHashtable->mCloneElementFun((nsHashKey*)he->key, he->value, + newHashtable->mCloneElementClosure); + if (newElement == nsnull) + return HT_ENUMERATE_STOP; + newHashtable->Put((nsHashKey*)he->key, newElement); + return HT_ENUMERATE_NEXT; +} + +nsHashtable* +nsObjectHashtable::Clone() +{ + PRBool threadSafe = PR_FALSE; + if (mLock) + threadSafe = PR_TRUE; + nsObjectHashtable* newHashTable = + new nsObjectHashtable(mCloneElementFun, mCloneElementClosure, + mDestroyElementFun, mDestroyElementClosure, + hashtable->nentries, threadSafe); + + PL_HashTableEnumerateEntries(hashtable, CopyElement, newHashTable); + return newHashTable; +} + +void +nsObjectHashtable::Reset() +{ + Enumerate(mDestroyElementFun, mDestroyElementClosure); + nsHashtable::Reset(); +} + +//////////////////////////////////////////////////////////////////////////////// +// nsSupportsHashtable: an nsHashtable where the elements are nsISupports* + +static PR_CALLBACK PRBool +_ReleaseElement(nsHashKey *aKey, void *aData, void* closure) +{ + nsISupports* element = NS_STATIC_CAST(nsISupports*, aData); + NS_RELEASE(element); + return PR_TRUE; +} + +nsSupportsHashtable::~nsSupportsHashtable() +{ + Enumerate(_ReleaseElement, nsnull); +} + +void* +nsSupportsHashtable::Put(nsHashKey *aKey, void *aData) +{ + nsISupports* element = NS_STATIC_CAST(nsISupports*, aData); + NS_ADDREF(element); + return nsHashtable::Put(aKey, aData); +} + +void* +nsSupportsHashtable::Get(nsHashKey *aKey) +{ + void* data = nsHashtable::Get(aKey); + nsISupports* element = NS_STATIC_CAST(nsISupports*, data); + NS_ADDREF(element); + return data; +} + +void* +nsSupportsHashtable::Remove(nsHashKey *aKey) +{ + void* data = nsHashtable::Remove(aKey); + nsISupports* element = NS_STATIC_CAST(nsISupports*, data); + NS_RELEASE(element); + return data; +} + +static PR_CALLBACK PRIntn +_hashEnumerateCopy(PLHashEntry *he, PRIntn i, void *arg) +{ + nsHashtable *newHashtable = (nsHashtable *)arg; + nsISupports* element = NS_STATIC_CAST(nsISupports*, he->value); + NS_ADDREF(element); + newHashtable->Put((nsHashKey*)he->key, he->value); + return HT_ENUMERATE_NEXT; +} + +nsHashtable* +nsSupportsHashtable::Clone() +{ + PRBool threadSafe = PR_FALSE; + if (mLock) + threadSafe = PR_TRUE; + nsSupportsHashtable* newHashTable = + new nsSupportsHashtable(hashtable->nentries, threadSafe); + + PL_HashTableEnumerateEntries(hashtable, _hashEnumerateCopy, newHashTable); + return newHashTable; +} + +void +nsSupportsHashtable::Reset() +{ + Enumerate(_ReleaseElement, nsnull); + nsHashtable::Reset(); +} + +//////////////////////////////////////////////////////////////////////////////// diff --git a/mozilla/xpcom/ds/nsHashtable.h b/mozilla/xpcom/ds/nsHashtable.h index cf6d78aa6c3..f6bee941ad9 100644 --- a/mozilla/xpcom/ds/nsHashtable.h +++ b/mozilla/xpcom/ds/nsHashtable.h @@ -57,6 +57,49 @@ public: void Reset(); }; +//////////////////////////////////////////////////////////////////////////////// +// nsObjectHashtable: an nsHashtable where the elements are C++ objects to be +// deleted + +typedef void* (*nsHashtableCloneElementFunc)(nsHashKey *aKey, void *aData, void* closure); + +class NS_COM nsObjectHashtable : public nsHashtable { +public: + nsObjectHashtable(nsHashtableCloneElementFunc cloneElementFun, + void* cloneElementClosure, + nsHashtableEnumFunc destroyElementFun, + void* destroyElementClosure, + PRUint32 aSize = 256, PRBool threadSafe = PR_FALSE); + ~nsObjectHashtable(); + + nsHashtable *Clone(); + void Reset(); + +protected: + static PR_CALLBACK PRIntn CopyElement(PLHashEntry *he, PRIntn i, void *arg); + + nsHashtableCloneElementFunc mCloneElementFun; + void* mCloneElementClosure; + nsHashtableEnumFunc mDestroyElementFun; + void* mDestroyElementClosure; +}; + +//////////////////////////////////////////////////////////////////////////////// +// nsSupportsHashtable: an nsHashtable where the elements are nsISupports* + +class NS_COM nsSupportsHashtable : public nsHashtable { +public: + nsSupportsHashtable(PRUint32 aSize = 256, PRBool threadSafe = PR_FALSE) + : nsHashtable(aSize, threadSafe) {} + ~nsSupportsHashtable(); + + void *Put(nsHashKey *aKey, void *aData); + void *Get(nsHashKey *aKey); + void *Remove(nsHashKey *aKey); + nsHashtable *Clone(); + void Reset(); +}; + //////////////////////////////////////////////////////////////////////////////// // nsISupportsKey: Where keys are nsISupports objects that get refcounted.