Added nsObjectHashtable (for automatically copying and destroying elements). Also nsSupportsHashtable for refcounted elements.

This commit is contained in:
warren%netscape.com 1999-07-28 07:56:28 +00:00
Родитель 4bcb36a368
Коммит f079935296
2 изменённых файлов: 178 добавлений и 3 удалений

Просмотреть файл

@ -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();
}
////////////////////////////////////////////////////////////////////////////////

Просмотреть файл

@ -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.