This commit is contained in:
jkeiser%netscape.com 2003-04-02 06:53:57 +00:00
parent 20f2f376c2
commit 57a1ab6f5c
16 changed files with 1616 additions and 1 deletions

View File

@ -84,6 +84,9 @@
#ifdef DEBUG
#include "pure.h"
#endif
#include "nsInterfaceHashtable.h"
#include "nsDataHashtable.h"
#include "nsHashKeys.h"
#include "pldhash.h"
#include "nsVariant.h"
#include "nsEscape.h"
@ -138,6 +141,8 @@ void XXXNeverCalled()
nsCWeakReferent(0);
NS_GetWeakReference(NULL);
nsCOMPtr<nsISupports> dummyFoo(do_GetInterface(nsnull));
nsInterfaceHashtable<nsStringHashKey,nsISupports>();
nsDataHashtable<nsUint32HashKey,PRInt32>();
NS_NewByteArrayInputStream(NULL, NULL, 0);
NS_NewStorageStream(0,0, nsnull);
nsString foo;

View File

@ -1,27 +1,37 @@
nsArray.h
nsArrayEnumerator.h
nsAtomService.h
nsBaseHashtable.h
nsBaseHashtableImpl.h
nsCppSharedAllocator.h
nsCOMArray.h
nsCRT.h
nsDataHashtable.h
nsDeque.h
nsDoubleHashtable.h
nsHashSets.h
nsCheapSets.h
nsClassHashtable.h
nsDataHashtable.h
nsEnumeratorUtils.h
nsFixedSizeAllocator.h
nsHashKeys.h
nsHashSets.h
nsHashtable.h
nsHashtableEnumerator.h
nsIArena.h
nsIByteBuffer.h
nsIUnicharBuffer.h
nsInt64.h
nsInterfaceHashtable.h
nsInterfaceHashtableImpl.h
nsObserverService.h
nsQuickSort.h
nsStaticNameTable.h
nsStatistics.h
nsSupportsArray.h
nsSupportsPrimitives.h
nsTHashtable.h
nsTHashtableImpl.h
nsTime.h
nsUnitConversion.h
nsValueArray.h

View File

@ -68,6 +68,7 @@ CPPSRCS = \
nsSupportsArray.cpp \
nsSupportsArrayEnumerator.cpp \
nsSupportsPrimitives.cpp \
nsTHashtable.cpp \
nsUnicharBuffer.cpp \
nsVariant.cpp \
nsVoidArray.cpp \
@ -81,20 +82,27 @@ CPPSRCS = \
EXPORTS = \
nsAtomService.h \
nsBaseHashtable.h \
nsBaseHashtableImpl.h \
nsCheapSets.h \
nsClassHashtable.h \
nsCppSharedAllocator.h \
nsCRT.h \
nsDataHashtable.h \
nsDeque.h \
nsDoubleHashtable.h \
nsEnumeratorUtils.h \
nsFixedSizeAllocator.h \
nsHashSets.h \
nsHashKeys.h \
nsHashtable.h \
nsHashtableEnumerator.h \
nsIArena.h \
nsIByteBuffer.h \
nsIUnicharBuffer.h \
nsInt64.h \
nsInterfaceHashtable.h \
nsInterfaceHashtableImpl.h \
nsObserverService.h \
nsQuickSort.h \
nsRecyclingAllocator.h \
@ -102,6 +110,8 @@ EXPORTS = \
nsStaticAtom.h \
nsSupportsArray.h \
nsSupportsPrimitives.h \
nsTHashtable.h \
nsTHashtableImpl.h \
nsTime.h \
nsUnitConversion.h \
nsVariant.h \

190
xpcom/ds/nsBaseHashtable.h Normal file
View File

@ -0,0 +1,190 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public 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 C++ hashtable templates.
*
* The Initial Developer of the Original Code is
* Benjamin Smedberg.
* Portions created by the Initial Developer are Copyright (C) 2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsBaseHashtable_h__
#define nsBaseHashtable_h__
#include "nsTHashtable.h"
#include NEW_H
typedef struct PRRWLock PRRWLock;
template<class KeyClass,class DataType,class UserDataType>
class nsBaseHashtable; // forward declaration
/**
* the private nsTHashtable::EntryType class used by nsBaseHashtable
* @see nsTHashtable for the specification of this class
* @see nsBaseHashtable for template parameters
*/
template<class KeyClass,class DataType>
class nsBaseHashtableET : public KeyClass
{
public:
DataType mData;
friend class nsTHashtable< nsBaseHashtableET<KeyClass,DataType> >;
private:
typedef typename KeyClass::KeyType KeyType;
typedef typename KeyClass::KeyTypePointer KeyTypePointer;
nsBaseHashtableET(KeyTypePointer aKey);
nsBaseHashtableET(const nsBaseHashtableET<KeyClass,DataType>& toCopy);
~nsBaseHashtableET();
};
/**
* templated hashtable for simple data types
* This class manages simple data types that do not need construction or
* destruction. Thread-safety is optional, via a flag in Init()
*
* @param KeyClass a wrapper-class for the hashtable key, see nsHashKeys.h
* for a complete specification.
* @param DataType the datatype stored in the hashtable,
* for example, PRUint32 or nsCOMPtr. If UserDataType is not the same,
* DataType must implicitly cast to UserDataType
* @param UserDataType the user sees, for example PRUint32 or nsISupports*
*/
template<class KeyClass,class DataType,class UserDataType>
class nsBaseHashtable :
protected nsTHashtable< nsBaseHashtableET<KeyClass,DataType> >
{
public:
typedef typename KeyClass::KeyType KeyType;
typedef nsBaseHashtableET<KeyClass,DataType> EntryType;
/**
* The constructor does not initialize, you must call Init() after
* construction.
*/
nsBaseHashtable();
/**
* destructor finalizes and deallocates hashtable
*/
~nsBaseHashtable();
/**
* Initialize the object.
* @param initSize the initial number of buckets in the hashtable,
default 16
* @param threadSafe whether to provide read/write
* locking on all class methods
* @return PR_TRUE if the object was initialized properly.
*/
PRBool Init(PRUint32 initSize = PL_DHASH_MIN_SIZE,
PRBool threadSafe = PR_FALSE);
/**
* retrieve the value for a key.
* @param aKey the key to retreive
* @param pData data associated with this key will be placed at this
* pointer. If you only need to check if the key exists, pData
* may be null.
* @return PR_TRUE if the key exists. If key does not exist, pData is not
* modified.
*/
PRBool Get(KeyType aKey, UserDataType* pData) const;
/**
* put a new value for the associated key
* @param aKey the key to put
* @param aData the new data
* @return always PR_TRUE, unless memory allocation failed
*/
PRBool Put(KeyType aKey, UserDataType aData);
/**
* remove the data for the associated key
* @param aKey the key to remove from the hashtable
*/
void Remove(KeyType aKey);
/**
* function type provided by the application for enumeration.
* currently, only "read" enumeration is supported. If you need to change
* or remove entries during enumeration, it might could be arranged.
* @param aKey the key being enumerated
* @param aData data being enumerated
* @parm userArg passed unchanged from Enumerate
* @return either
* @link PLDHashOperator::PL_DHASH_NEXT PL_DHASH_NEXT @endlink or
* @link PLDHashOperator::PL_DHASH_STOP PL_DHASH_STOP @endlink
*/
typedef PLDHashOperator
(*PR_CALLBACK EnumReadFunction)(KeyType aKey,
DataType aData,
void* userArg);
/**
* enumerate entries in the hashtable, without allowing changes
* this function read-locks the hashtable, so other threads may read keys
* at the same time in multi-thread environments.
* @param enumFunc enumeration callback
* @param userArg passed unchanged to the EnumReadFunction
*/
void EnumerateRead(EnumReadFunction enumFunc, void* userArg) const;
/**
* reset the hashtable, removing all entries
*/
void Clear();
protected:
PRRWLock* mLock;
/**
* used internally during EnumerateRead. Allocated on the stack.
* @param func the enumerator passed to EnumerateRead
* @param userArg the userArg passed to EnumerateRead
*/
struct s_EnumReadArgs
{
EnumReadFunction func;
void* userArg;
};
static PLDHashOperator s_EnumReadStub(PLDHashTable *table,
PLDHashEntryHdr *hdr,
PRUint32 number,
void *arg);
};
#ifndef HAVE_CPP_EXTERN_INSTANTIATION
#include "nsBaseHashtableImpl.h"
#endif
#endif // nsBaseHashtable_h__

View File

@ -0,0 +1,224 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public 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 C++ hashtable templates.
*
* The Initial Developer of the Original Code is
* Benjamin Smedberg.
* Portions created by the Initial Developer are Copyright (C) 2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsBaseHashtableImpl_h__
#define nsBaseHashtableImpl_h__
#ifndef nsBaseHashtable_h__
#include "nsBaseHashtable.h"
#endif
#ifndef nsTHashtableImpl_h__
#include "nsTHashtableImpl.h"
#endif
#include "prrwlock.h"
#include "nsDebug.h"
/* nsBaseHashtableET definitions */
template<class KeyClass,class DataType>
nsBaseHashtableET<KeyClass,DataType>::nsBaseHashtableET(KeyTypePointer aKey) :
KeyClass(aKey)
{ }
template<class KeyClass,class DataType>
nsBaseHashtableET<KeyClass,DataType>::nsBaseHashtableET
(const nsBaseHashtableET<KeyClass,DataType>& toCopy) :
KeyClass(toCopy),
mData(toCopy.mData)
{ }
template<class KeyClass,class DataType>
nsBaseHashtableET<KeyClass,DataType>::~nsBaseHashtableET()
{ }
/* nsBaseHashtable definitions */
template<class KeyClass,class DataType,class UserDataType>
nsBaseHashtable<KeyClass,DataType,UserDataType>::nsBaseHashtable()
{ }
template<class KeyClass,class DataType,class UserDataType>
nsBaseHashtable<KeyClass,DataType,UserDataType>::~nsBaseHashtable()
{
if (mLock)
PR_DestroyRWLock(mLock);
}
template<class KeyClass,class DataType,class UserDataType>
PRBool
nsBaseHashtable<KeyClass,DataType,UserDataType>::Init(PRUint32 initSize,
PRBool threadSafe)
{
if (!nsTHashtable<EntryType>::Init(initSize))
return PR_FALSE;
if (!threadSafe)
{
mLock = nsnull;
return PR_TRUE;
}
mLock = PR_NewRWLock(PR_RWLOCK_RANK_NONE, "nsBaseHashtable");
NS_WARN_IF_FALSE(mLock, "Error creating lock during nsBaseHashtable::Init()");
if (!mLock)
return PR_FALSE;
return PR_TRUE;
}
template<class KeyClass,class DataType,class UserDataType>
PRBool
nsBaseHashtable<KeyClass,DataType,UserDataType>::Get(KeyType aKey,
UserDataType* pData) const
{
if (mLock)
PR_RWLock_Rlock(mLock);
EntryType* ent = GetEntry(KeyClass::KeyToPointer(aKey));
if (ent)
{
if (pData)
*pData = ent->mData;
if (mLock)
PR_RWLock_Unlock(mLock);
return PR_TRUE;
}
if (mLock)
PR_RWLock_Unlock(mLock);
return PR_FALSE;
}
template<class KeyClass,class DataType,class UserDataType>
PRBool
nsBaseHashtable<KeyClass,DataType,UserDataType>::Put(KeyType aKey,
UserDataType aData)
{
if (mLock)
PR_RWLock_Wlock(mLock);
EntryType* ent = PutEntry(KeyClass::KeyToPointer(aKey));
if (!ent)
{
if (mLock)
PR_RWLock_Unlock(mLock);
return PR_FALSE;
}
ent->mData = aData;
if (mLock)
PR_RWLock_Unlock(mLock);
return PR_TRUE;
}
template<class KeyClass,class DataType,class UserDataType>
void
nsBaseHashtable<KeyClass,DataType,UserDataType>::Remove(KeyType aKey)
{
if (mLock)
PR_RWLock_Wlock(mLock);
RemoveEntry(KeyClass::KeyToPointer(aKey));
if (mLock)
PR_RWLock_Unlock(mLock);
}
template<class KeyClass,class DataType,class UserDataType>
void
nsBaseHashtable<KeyClass,DataType,UserDataType>::EnumerateRead
(EnumReadFunction fEnumCall, void* userArg) const
{
NS_ASSERTION(mTable.entrySize,
"nsBaseHashtable was not initialized properly.");
if (mLock)
PR_RWLock_Rlock(mLock);
s_EnumReadArgs enumData = { fEnumCall, userArg };
PL_DHashTableEnumerate(NS_CONST_CAST(PLDHashTable*,&mTable),
s_EnumStub,
&enumData);
if (mLock)
PR_RWLock_Unlock(mLock);
}
template<class KeyClass,class DataType,class UserDataType>
void nsBaseHashtable<KeyClass,DataType,UserDataType>::Clear()
{
if (mLock)
PR_RWLock_Wlock(mLock);
nsTHashtable<EntryType>::Clear();
if (mLock)
PR_RWLock_Unlock(mLock);
}
template<class KeyClass,class DataType,class UserDataType>
PLDHashOperator
nsBaseHashtable<KeyClass,DataType,UserDataType>::s_EnumReadStub
(PLDHashTable *table, PLDHashEntryHdr *hdr, PRUint32 number, void* arg)
{
EntryType* ent = (EntryType*) hdr;
s_EnumReadArgs* eargs = (s_EnumReadArgs*) arg;
PLDHashOperator res = (eargs->func)(ent->GetKey(), ent->mData, eargs->userArg);
NS_ASSERTION( !(res & PL_DHASH_REMOVE ),
"PL_DHASH_REMOVE return during const enumeration; ignoring.");
if (res & PL_DHASH_STOP)
return PL_DHASH_STOP;
return PL_DHASH_NEXT;
}
#endif // nsBaseHashtableImpl_h__

115
xpcom/ds/nsClassHashtable.h Normal file
View File

@ -0,0 +1,115 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public 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 C++ hashtable templates.
*
* The Initial Developer of the Original Code is
* Benjamin Smedberg.
* Portions created by the Initial Developer are Copyright (C) 2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsClassHashtable_h__
#define nsClassHashtable_h__
#include "nsBaseHashtable.h"
#include "nsHashKeys.h"
/**
* templated hashtable class maps keys to C++ object pointers.
* See nsBaseHashtable for complete declaration.
* @param KeyClass a wrapper-class for the hashtable key, see nsHashKeys.h
* for a complete specification.
* @param Class the class-type being wrapped
* @see nsInterfaceHashtable, nsClassHashtable
*/
template<class KeyClass,class T>
class nsClassHashtable :
public nsBaseHashtable<KeyClass,nsAutoPtr<T>,T*>
{
public:
typedef typename KeyClass::KeyType KeyType;
typedef typename T* UserDataType;
/**
* @copydoc nsBaseHashtable::nsBaseHashtable
*/
nsClassHashtable() { }
/**
* destructor, cleans up properly
*/
~nsClassHashtable() { }
/**
* @copydoc nsBaseHashtable::Get
* @param pData if the key doesn't exist, pData will be set to nsnull.
*/
PRBool Get(KeyType aKey, UserDataType* pData) const;
};
/*
* this class doesn't have any predefined instances; implementations are
* included here
*/
#ifndef nsTHashtableImpl_h__
#include "nsTHashtableImpl.h"
#endif
template<class KeyClass,class T>
PRBool
nsClassHashtable<KeyClass,T>::Get(KeyType aKey, T** retVal) const
{
if (mLock)
PR_RWLock_Rlock(mLock);
typename nsBaseHashtable<KeyClass,nsAutoPtr<T>,T*>::EntryType* ent =
GetEntry(KeyClass::KeyToPointer(aKey));
if (ent)
{
if (retVal)
*retVal = ent->mData;
if (mLock)
PR_RWLock_Unlock(mLock);
return PR_TRUE;
}
*retVal = nsnull;
if (mLock)
PR_RWLock_Unlock(mLock);
return PR_FALSE;
};
#endif // nsClassHashtable_h__

View File

@ -0,0 +1,78 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public 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 C++ hashtable templates.
*
* The Initial Developer of the Original Code is
* Benjamin Smedberg.
* Portions created by the Initial Developer are Copyright (C) 2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsDataHashtable_h__
#define nsDataHashtable_h__
#include "nsHashKeys.h"
#include "nsBaseHashtable.h"
/**
* templated hashtable class maps keys to simple datatypes.
* See nsBaseHashtable for complete declaration
* @param KeyClass a wrapper-class for the hashtable key, see nsHashKeys.h
* for a complete specification.
* @param DataType the simple datatype being wrapped
* @see nsInterfaceHashtable, nsClassHashtable
*/
template<class KeyClass,class DataType>
class nsDataHashtable :
public nsBaseHashtable<KeyClass,DataType,DataType>
{ };
/**
* declare shared-linkage for common usages of nsDataHashtable.
*
* To avoid including this code in multiple translation units, common usages
* are predeclared with external linkage. To add to this list, include the
* declarations here, definitions in nsTHashtable.cpp and dlldeps.cpp . This
* only works if the configure-test HAVE_CPP_EXTERN_INSTANTIATION succeeds.
*/
#ifndef HAVE_CPP_EXTERN_INSTANTIATION
#include "nsBaseHashtableImpl.h"
#else
#ifndef NO_THASHTABLE_EXTERN_DECL
extern template class NS_COM nsBaseHashtableET<nsUint32HashKey,PRInt32>;
extern template class NS_COM nsTHashtable< nsBaseHashtableET<nsUint32HashKey,PRInt32> >;
extern template class NS_COM nsBaseHashtable<nsUint32HashKey,PRInt32,PRInt32>;
extern template class NS_COM nsDataHashtable<nsUint32HashKey,PRInt32>;
#else
#include "nsBaseHashtableImpl.h"
#endif
#endif
#endif // nsDataHashtable_h__

View File

@ -36,6 +36,10 @@
*
* ***** END LICENSE BLOCK ***** */
/**
* nsDoubleHashtable.h is OBSOLETE. Use nsTHashtable or a derivative instead.
*/
#ifndef __nsDoubleHashtable_h__
#define __nsDoubleHashtable_h__

217
xpcom/ds/nsHashKeys.h Normal file
View File

@ -0,0 +1,217 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public 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 C++ hashtable templates.
*
* The Initial Developer of the Original Code is
* Benjamin Smedberg.
* Portions created by the Initial Developer are Copyright (C) 2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsTHashKeys_h__
#define nsTHashKeys_h__
#include "nsAString.h"
#include "nsString.h"
#include "nsID.h"
#include "nsCRT.h"
#include "nsReadableUtils.h"
#include "nsISupports.h"
#include "nsCOMPtr.h"
#include "pldhash.h"
#include NEW_H
/** @file nsHashKeys.h
* standard HashKey classes for nsDataHashtable and relatives. Each of these
* classes follows the nsTHashtable::EntryType specification
*
* Lightweight keytypes are provided here:
* nsStringHashKey
* nsCStringHashKey
* nsUint32HashKey
* nsISupportsHashKey
* nsIDHashKey
*
* Use these keytypes if possible; the templates are already instantiated
* for them, and they can be dynamically linked and therefore reduce code
* size!
*/
/**
* hashkey wrapper using nsAString KeyType
*
* @see nsTHashtable::EntryType for specification
*/
class NS_COM nsStringHashKey : protected PLDHashEntryHdr
{
public:
typedef const nsAString& KeyType;
typedef const nsAString* KeyTypePointer;
nsStringHashKey(KeyTypePointer aStr) : mStr(*aStr) { }
nsStringHashKey(const nsStringHashKey& toCopy) : mStr(toCopy.mStr) { }
~nsStringHashKey() { }
KeyType GetKey() const { return mStr; }
KeyTypePointer GetKeyPointer() const { return &mStr; }
PRBool KeyEquals(const KeyTypePointer aKey) const
{
return mStr.Equals(*aKey);
}
static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
static PLDHashNumber HashKey(const KeyTypePointer aKey)
{
return HashString(*aKey);
}
static PRBool AllowMemMove() { return PR_TRUE; }
private:
const nsString mStr;
};
/**
* hashkey wrapper using nsACString KeyType
*
* @see nsTHashtable::EntryType for specification
*/
class NS_COM nsCStringHashKey : protected PLDHashEntryHdr
{
public:
typedef const nsACString& KeyType;
typedef const nsACString* KeyTypePointer;
nsCStringHashKey(const nsACString* aStr) : mStr(*aStr) { }
nsCStringHashKey(const nsCStringHashKey& toCopy) : mStr(toCopy.mStr) { }
~nsCStringHashKey() { }
KeyType GetKey() const { return mStr; }
KeyTypePointer GetKeyPointer() const { return &mStr; }
PRBool KeyEquals(KeyTypePointer aKey) const { return mStr.Equals(*aKey); }
static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
static PLDHashNumber HashKey(KeyTypePointer aKey)
{
return HashString(*aKey);
}
static PRBool AllowMemMove() { return PR_TRUE; }
private:
const nsCString mStr;
};
/**
* hashkey wrapper using PRUint32 KeyType
*
* @see nsTHashtable::EntryType for specification
*/
class NS_COM nsUint32HashKey : protected PLDHashEntryHdr
{
public:
typedef PRUint32 KeyType;
typedef const PRUint32* KeyTypePointer;
nsUint32HashKey(KeyTypePointer aKey) : mValue(*aKey) { }
nsUint32HashKey(const nsUint32HashKey& toCopy) : mValue(toCopy.mValue) { }
~nsUint32HashKey() { }
KeyType GetKey() const { return mValue; }
KeyTypePointer GetKeyPointer() const { return &mValue; }
PRBool KeyEquals(KeyTypePointer aKey) const { return *aKey == mValue; }
static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
static PLDHashNumber HashKey(KeyTypePointer aKey) { return *aKey; }
static PRBool AllowMemMove() { return PR_TRUE; }
private:
const PRUint32 mValue;
};
/**
* hashkey wrapper using nsISupports* KeyType
*
* @see nsTHashtable::EntryType for specification
*/
class NS_COM nsISupportsHashKey : protected PLDHashEntryHdr
{
public:
typedef nsISupports* KeyType;
typedef const nsISupports* KeyTypePointer;
nsISupportsHashKey(nsISupports* key) : mSupports(key) { }
nsISupportsHashKey(const nsISupportsHashKey& toCopy) :
mSupports(toCopy.mSupports) { }
~nsISupportsHashKey() { }
KeyType GetKey() const { return mSupports; }
KeyTypePointer GetKeyPointer() const { return mSupports; }
PRBool KeyEquals(KeyTypePointer aKey) const { return aKey == mSupports; }
static KeyTypePointer KeyToPointer(KeyType aKey) { return aKey; }
static PLDHashNumber HashKey(KeyTypePointer aKey)
{
return NS_PTR_TO_INT32(aKey) >>2;
}
static PRBool AllowMemMove() { return PR_TRUE; }
private:
const nsCOMPtr<nsISupports> mSupports;
};
/**
* hashkey wrapper using nsID KeyType
*
* @see nsTHashtable::EntryType for specification
*/
class NS_COM nsIDHashKey : protected PLDHashEntryHdr
{
public:
typedef const nsID& KeyType;
typedef const nsID* KeyTypePointer;
nsIDHashKey(const nsID* id) : mID(*id) { }
nsIDHashKey(const nsIDHashKey& toCopy) : mID(toCopy.mID) { }
~nsIDHashKey() { }
KeyType GetKey() const { return mID; }
KeyTypePointer GetKeyPointer() const { return &mID; }
PRBool operator==(KeyTypePointer aKey) const { return aKey->Equals(mID); }
static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
static PLDHashNumber HashKey(KeyTypePointer aKey);
static PRBool AllowMemMove() { return PR_TRUE; }
private:
const nsID mID;
};
#endif // nsTHashKeys_h__

View File

@ -30,6 +30,10 @@
* 04/20/2000 IBM Corp. Added PR_CALLBACK for Optlink use in OS2
*/
/**
* nsHashtable is OBSOLETE. Use nsTHashtable or a derivative instead.
*/
#ifndef nsHashtable_h__
#define nsHashtable_h__

View File

@ -0,0 +1,99 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public 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 C++ hashtable templates.
*
* The Initial Developer of the Original Code is
* Benjamin Smedberg.
* Portions created by the Initial Developer are Copyright (C) 2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsInterfaceHashtable_h__
#define nsInterfaceHashtable_h__
#include "nsBaseHashtable.h"
#include "nsHashKeys.h"
#include "nsCOMPtr.h"
/**
* templated hashtable class maps keys to interface pointers.
* See nsBaseHashtable for complete declaration.
* @param KeyClass a wrapper-class for the hashtable key, see nsHashKeys.h
* for a complete specification.
* @param Interface the interface-type being wrapped
* @see nsDataHashtable, nsClassHashtable
*/
template<class KeyClass,class Interface>
class nsInterfaceHashtable :
public nsBaseHashtable< KeyClass, nsCOMPtr<Interface> , Interface* >
{
public:
typedef typename KeyClass::KeyType KeyType;
typedef Interface* UserDataType;
/**
* @copydoc nsBaseHashtable::nsBaseHashtable
*/
nsInterfaceHashtable() { }
/**
* destructor, cleans up properly
*/
~nsInterfaceHashtable() { }
/**
* @copydoc nsBaseHashtable::Get
* @param pData This is an XPCOM getter, so pData is already_addrefed.
* If the key doesn't exist, pData will be set to nsnull.
*/
PRBool Get(KeyType aKey, UserDataType* pData) const;
};
/**
* declare shared-linkage for common usages of nsDataHashtable.
*
* To avoid including this code in multiple translation units, common usages
* are predeclared with external linkage. To add to this list, include the
* declarations here, definitions in nsTHashtable.cpp and dlldeps.cpp . This
* only works if the configure-test HAVE_CPP_EXTERN_INSTANTIATION succeeds.
*/
#ifndef HAVE_CPP_EXTERN_INSTANTIATION
#include "nsInterfaceHashtableImpl.h"
#else
#ifndef NO_THASHTABLE_EXTERN_DECL
extern template class NS_COM nsBaseHashtableET<nsStringHashKey, nsCOMPtr<nsISupports> >;
extern template class NS_COM nsTHashtable< nsBaseHashtableET<nsStringHashKey,nsCOMPtr<nsISupports> > >;
extern template class NS_COM nsBaseHashtable<nsStringHashKey, nsCOMPtr<nsISupports>, nsISupports*>;
extern template class NS_COM nsInterfaceHashtable<nsStringHashKey, nsISupports>;
#else
#include "nsInterfaceHashtableImpl.h"
#endif
#endif
#endif // nsInterfaceHashtable_h__

View File

@ -0,0 +1,88 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public 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 C++ hashtable templates.
*
* The Initial Developer of the Original Code is
* Benjamin Smedberg.
* Portions created by the Initial Developer are Copyright (C) 2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsInterfaceHashtableImpl_h__
#define nsInterfaceHashtableImpl_h__
#ifndef nsInterfaceHashtable_h__
#include "nsInterfaceHashtable.h"
#endif
#ifndef nsBaseHashtableImpl_h__
#include "nsBaseHashtableImpl.h"
#endif
/* nsInterfaceHashtable definitions */
template<class KeyClass,class Interface>
PRBool
nsInterfaceHashtable<KeyClass,Interface>::Get
(KeyType aKey, UserDataType* pInterface) const
{
if (mLock)
PR_RWLock_Rlock(mLock);
typename nsBaseHashtable<KeyClass, nsCOMPtr<Interface>, Interface*>::EntryType* ent =
GetEntry(KeyClass::KeyToPointer(aKey));
if (ent)
{
if (pInterface)
{
*pInterface = ent->mData;
NS_IF_ADDREF(*pInterface);
}
if (mLock)
PR_RWLock_Unlock(mLock);
return PR_TRUE;
}
// if the key doesn't exist, set *pInterface to null
// so that it is a valid XPCOM getter
if (pInterface)
*pInterface = nsnull;
if (mLock)
PR_RWLock_Unlock(mLock);
return PR_FALSE;
}
#endif // nsInterfaceHashtableImpl_h__

82
xpcom/ds/nsTHashtable.cpp Normal file
View File

@ -0,0 +1,82 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public 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 C++ hashtable templates.
*
* The Initial Developer of the Original Code is
* Benjamin Smedberg.
* Portions created by the Initial Developer are Copyright (C) 2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#define NO_THASHTABLE_EXTERN_DECL
#include "nsTHashtable.h"
#include "nsTHashtableImpl.h"
#include "nsInterfaceHashtable.h"
#include "nsInterfaceHashtableImpl.h"
#include "nsDataHashtable.h"
#include "nsHashKeys.h"
PLDHashOperator PL_DHashStubEnumRemove(PLDHashTable *table,
PLDHashEntryHdr *entry,
PRUint32 ordinal,
void *userarg)
{
return PL_DHASH_REMOVE;
}
PRUint32 nsIDHashKey::HashKey(const nsID* id)
{
PRUint32 h = id->m0;
PRUint32 i;
h = (h>>28) ^ (h<<4) ^ id->m1;
h = (h>>28) ^ (h<<4) ^ id->m2;
for (i = 0; i < 8; i++)
h = (h>>28) ^ (h<<4) ^ id->m3[i];
return h;
}
// explicit instantiation of templates
#ifdef HAVE_CPP_EXTERN_INSTANTIATION
/* instantiate common nsInterfaceHashtable uses */
template class NS_EXPORT nsBaseHashtableET<nsStringHashKey,nsCOMPtr<nsISupports> >;
template class NS_EXPORT nsTHashtable< nsBaseHashtableET<nsStringHashKey,nsCOMPtr<nsISupports> > >;
template class NS_EXPORT nsBaseHashtable<nsStringHashKey,nsCOMPtr<nsISupports>,nsISupports*>;
template class NS_EXPORT nsInterfaceHashtable<nsStringHashKey,nsISupports>;
/* instantiate common nsDataHashtable uses */
template class NS_EXPORT nsBaseHashtableET<nsUint32HashKey,PRInt32>;
template class NS_EXPORT nsTHashtable< nsBaseHashtableET<nsUint32HashKey,PRInt32> >;
template class NS_EXPORT nsBaseHashtable<nsUint32HashKey,PRInt32,PRInt32>;
template class NS_EXPORT nsDataHashtable<nsUint32HashKey,PRInt32>;
#endif // HAVE_CPP_EXTERN_INSTANTIATION

241
xpcom/ds/nsTHashtable.h Normal file
View File

@ -0,0 +1,241 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public 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 C++ hashtable templates.
*
* The Initial Developer of the Original Code is
* Benjamin Smedberg.
* Portions created by the Initial Developer are Copyright (C) 2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsTHashtable_h__
#define nsTHashtable_h__
#include "nscore.h"
#include "pldhash.h"
#ifdef _MSC_VER
#pragma warning( disable: 4231 ) // 'extern template' nonstandard C++ extension
#endif
/**
* a base class for templated hashtables.
*
* Clients will rarely need to use this class directly. Check the derived
* classes first, to see if they will meet your needs.
*
* @param EntryType the templated entry-type class that is managed by the
* hashtable. <code>EntryType</code> must extend the following declaration,
* and <strong>must not declare any virtual functions or derive from classes
* with virtual functions.</strong> Any vtable pointer would break the
* PLDHashTable code.
*<pre> class EntryType : PLDHashEntryHdr
* {
* public: or friend nsTHashtable<EntryType>;
* // KeyType is what we use when Get()ing or Put()ing this entry
* // this should either be a simple datatype (PRUint32, nsISupports*) or
* // a const reference (const nsAString&)
* typedef something KeyType;
* // KeyTypePointer is the pointer-version of KeyType, because pldhash.h
* // requires keys to cast to <code>const void*</code>
* typedef const something* KeyTypePointer;
*
* EntryType(KeyTypePointer aKey);
*
* // the copy constructor must be defined, even if AllowMemMove() == true
* // or you will cause link errors!
* EntryType(const EntryType& aEnt);
*
* // the destructor must be defined... or you will cause link errors!
* ~EntryType();
*
* // return the key of this entry
* const KeyTypePointer GetKeyPointer() const;
*
* // KeyEquals(): does this entry match this key?
* PRBool KeyEquals(KeyTypePointer aKey) const;
*
* // KeyToPointer(): Convert KeyType to KeyTypePointer
* static KeyTypePointer KeyToPointer(KeyType aKey);
*
* // HashKey(): calculate the hash number
* static PLDHashNumber HashKey(KeyTypePointer aKey);
*
* // AllowMemMove(): can we move this class with memmove(), or do we have
* // to use the copy constructor?
* static PRBool AllowMemMove();
* }</pre>
*
* @see nsInterfaceHashtable
* @see nsDataHashtable
* @see nsClassHashtable
* @author "Benjamin Smedberg <bsmedberg@covad.net>"
*/
template<class EntryType>
class nsTHashtable
{
public:
/**
* A dummy constructor; you must call Init() before using this class.
*/
nsTHashtable();
/**
* destructor, cleans up and deallocates
*/
~nsTHashtable();
/**
* Initialize the class. This function must be called before any other
* class operations. This can fail due to OOM conditions.
* @param initSize the initial number of buckets in the hashtable, default 16
* @return PR_TRUE if the class was initialized properly.
*/
PRBool Init(PRUint32 initSize = PL_DHASH_MIN_SIZE);
/**
* KeyType is typedef'ed for ease of use.
*/
typedef typename EntryType::KeyType KeyType;
/**
* KeyTypePointer is typedef'ed for ease of use.
*/
typedef typename EntryType::KeyTypePointer KeyTypePointer;
/**
* Get the entry associated with a key.
* @param aKey the key to retrieve
* @return pointer to the entry class, if the key exists; nsnull if the
* key doesn't exist
*/
EntryType* GetEntry(KeyTypePointer aKey) const;
/**
* Get the entry associated with a key, or create a new entry,
* @param aKey the key to retrieve
* @return pointer to the entry class retreived; nsnull only if memory
can't be allocated
*/
EntryType* PutEntry(KeyTypePointer aKey);
/**
* Remove the entry associated with a key.
* @param aKey of the entry to remove
*/
void RemoveEntry(KeyTypePointer aKey);
/**
* client must provide an <code>Enumerator</code> function for
* EnumerateEntries
* @param aEntry the entry being enumerated
* @param userArg passed unchanged from <code>EnumerateEntries</code>
* @return combination of flags
* @link PLDHashOperator::PL_DHASH_NEXT PL_DHASH_NEXT @endlink ,
* @link PLDHashOperator::PL_DHASH_STOP PL_DHASH_STOP @endlink ,
* @link PLDHashOperator::PL_DHASH_REMOVE PL_DHASH_REMOVE @endlink
*/
typedef PLDHashOperator (*Enumerator)(EntryType* aEntry, void* userArg);
/**
* Enumerate all the entries of the function.
* @param enumFunc the <code>Enumerator</code> function to call
* @param userArg a pointer to pass to the
* <code>Enumerator</code> function
* @return the number of entries actually enumerated
*/
PRUint32 EnumerateEntries(Enumerator enumFunc, void* userArg);
/**
* remove all entries, return hashtable to "pristine" state ;)
*/
void Clear();
protected:
PLDHashTable mTable;
static PLDHashTableOps sOps;
static const void* s_GetKey(PLDHashTable *table,
PLDHashEntryHdr *entry);
static PLDHashNumber s_HashKey(PLDHashTable *table,
const void *key);
static PRBool s_MatchEntry(PLDHashTable *table,
const PLDHashEntryHdr *entry,
const void *key);
static void s_CopyEntry(PLDHashTable *table,
const PLDHashEntryHdr *from,
PLDHashEntryHdr *to);
static void s_ClearEntry(PLDHashTable *table,
PLDHashEntryHdr *entry);
static void s_InitEntry(PLDHashTable *table,
PLDHashEntryHdr *entry,
const void *key);
/**
* passed internally during enumeration. Allocated on the stack.
*
* @param userFunc the Enumerator function passed to
* EnumerateEntries by the client
* @param userArg the userArg passed unaltered
*/
struct s_EnumArgs
{
Enumerator userFunc;
void* userArg;
};
static PLDHashOperator s_EnumStub(PLDHashTable *table,
PLDHashEntryHdr *entry,
PRUint32 number,
void *arg);
};
// helper function for Reset()
PLDHashOperator PL_DHashStubEnumRemove(PLDHashTable *table,
PLDHashEntryHdr *entry,
PRUint32 ordinal,
void *userArg);
/**
* if we can't declare external linkage for templates, we need to include the
* implementation header.
*/
#ifndef HAVE_CPP_EXTERN_INSTANTIATION
#include "nsTHashtableImpl.h"
#endif
#endif // nsTHashtable_h__

218
xpcom/ds/nsTHashtableImpl.h Normal file
View File

@ -0,0 +1,218 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public 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 C++ hashtable templates.
*
* The Initial Developer of the Original Code is
* Benjamin Smedberg.
* Portions created by the Initial Developer are Copyright (C) 2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsTHashtableImpl_h__
#define nsTHashtableImpl_h__
#ifndef nsTHashtable_h__
#include "nsTHashtable.h"
#endif
#include "nsDebug.h"
template<class EntryType>
nsTHashtable<EntryType>::nsTHashtable()
{
// entrySize is our "I'm initialized" indicator
mTable.entrySize = 0;
}
template<class EntryType>
nsTHashtable<EntryType>::~nsTHashtable()
{
if (mTable.entrySize)
PL_DHashTableFinish(&mTable);
}
template<class EntryType>
PRBool
nsTHashtable<EntryType>::Init(PRUint32 initSize)
{
if (mTable.entrySize)
{
NS_ERROR("nsTHashtable::Init() should not be called twice.");
return PR_FALSE;
}
if (!PL_DHashTableInit(&mTable, &sOps, nsnull, sizeof(EntryType), initSize))
{
// if failed, reset "flag"
mTable.entrySize = 0;
return PR_FALSE;
}
return PR_TRUE;
}
template<class EntryType>
EntryType*
nsTHashtable<EntryType>::GetEntry(KeyTypePointer aKey) const
{
NS_ASSERTION(mTable.entrySize, "nsTHashtable was not initialized properly.");
return NS_REINTERPRET_CAST(EntryType*,
PL_DHashTableOperate(
NS_CONST_CAST(PLDHashTable*,&mTable),
aKey,
PL_DHASH_LOOKUP));
}
template<class EntryType>
EntryType*
nsTHashtable<EntryType>::PutEntry(KeyTypePointer aKey)
{
NS_ASSERTION(mTable.entrySize, "nsTHashtable was not initialized properly.");
return (EntryType*) PL_DHashTableOperate(&mTable, aKey, PL_DHASH_ADD);
}
template<class EntryType>
void
nsTHashtable<EntryType>::RemoveEntry(KeyTypePointer aKey)
{
NS_ASSERTION(mTable.entrySize, "nsTHashtable was not initialized properly.");
PL_DHashTableOperate(&mTable, aKey, PL_DHASH_REMOVE);
return;
}
template<class EntryType>
PRUint32
nsTHashtable<EntryType>::EnumerateEntries(Enumerator enumFunc, void* userArg)
{
NS_ASSERTION(mTable.entrySize, "nsTHashtable was not initialized properly.");
s_EnumArgs args = { enumFunc, userArg };
return PL_DHashTableEnumerate(&mTable, s_EnumStub, &args);
}
template<class EntryType>
void
nsTHashtable<EntryType>::Clear()
{
NS_ASSERTION(mTable.entrySize, "nsTHashtable was not initialized properly.");
PL_DHashTableEnumerate(&mTable, PL_DHashStubEnumRemove, nsnull);
}
// static definitions
template<class EntryType>
PLDHashTableOps
nsTHashtable<EntryType>::sOps =
{
::PL_DHashAllocTable,
::PL_DHashFreeTable,
s_GetKey,
s_HashKey,
s_MatchEntry,
EntryType::AllowMemMove() ? ::PL_DHashMoveEntryStub : s_CopyEntry,
s_ClearEntry,
::PL_DHashFinalizeStub,
s_InitEntry
};
template<class EntryType>
const void*
nsTHashtable<EntryType>::s_GetKey(PLDHashTable *table,
PLDHashEntryHdr *entry)
{
return ((EntryType*) entry)->GetKeyPointer();
}
template<class EntryType>
PLDHashNumber
nsTHashtable<EntryType>::s_HashKey(PLDHashTable *table,
const void *key)
{
return EntryType::HashKey(NS_REINTERPRET_CAST(const KeyTypePointer, key));
}
template<class EntryType>
PRBool
nsTHashtable<EntryType>::s_MatchEntry(PLDHashTable *table,
const PLDHashEntryHdr *entry,
const void *key)
{
return ((const EntryType*) entry)->KeyEquals(
NS_REINTERPRET_CAST(const KeyTypePointer, key));
}
template<class EntryType>
void
nsTHashtable<EntryType>::s_CopyEntry(PLDHashTable *table,
const PLDHashEntryHdr *from,
PLDHashEntryHdr *to)
{
new(to) EntryType(* NS_REINTERPRET_CAST(const EntryType*,from));
NS_CONST_CAST(EntryType*,NS_REINTERPRET_CAST(const EntryType*,from))->~EntryType();
}
template<class EntryType>
void
nsTHashtable<EntryType>::s_ClearEntry(PLDHashTable *table,
PLDHashEntryHdr *entry)
{
NS_REINTERPRET_CAST(EntryType*,entry)->~EntryType();
}
template<class EntryType>
void
nsTHashtable<EntryType>::s_InitEntry(PLDHashTable *table,
PLDHashEntryHdr *entry,
const void *key)
{
new(entry) EntryType(NS_REINTERPRET_CAST(KeyTypePointer,key));
}
template<class EntryType>
PLDHashOperator
nsTHashtable<EntryType>::s_EnumStub(PLDHashTable *table,
PLDHashEntryHdr *entry,
PRUint32 number,
void *arg)
{
// dereferences the function-pointer to the user's enumeration function
return (* NS_REINTERPRET_CAST(s_EnumArgs*,arg)->userFunc)(
NS_REINTERPRET_CAST(EntryType*,entry),
NS_REINTERPRET_CAST(s_EnumArgs*,arg)->userArg);
}
#endif // nsTHashtableImpl_h__

View File

@ -1044,6 +1044,13 @@
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsTHashtable.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsDebug.cpp</PATH>
@ -1941,6 +1948,11 @@
<PATH>nsHashtable.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsTHashtable.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsDebug.cpp</PATH>
@ -3549,6 +3561,13 @@
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsTHashtable.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsDebug.cpp</PATH>
@ -4458,6 +4477,11 @@
<PATH>nsHashtable.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsTHashtable.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsDebug.cpp</PATH>
@ -5320,6 +5344,12 @@
<PATH>nsHashtable.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<TARGETNAME>xpcom.shlb</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsTHashtable.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<TARGETNAME>xpcom.shlb</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>