Loading xpcom/glue/nsBaseHashtable.h +83 −13 Original line number Original line Diff line number Diff line Loading @@ -136,8 +136,6 @@ public: /** /** * function type provided by the application for enumeration. * 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 aKey the key being enumerated * @param aData data being enumerated * @param aData data being enumerated * @parm userArg passed unchanged from Enumerate * @parm userArg passed unchanged from Enumerate Loading @@ -147,7 +145,7 @@ public: */ */ typedef PLDHashOperator typedef PLDHashOperator (*PR_CALLBACK EnumReadFunction)(KeyType aKey, (*PR_CALLBACK EnumReadFunction)(KeyType aKey, DataType aData, UserDataType aData, void* userArg); void* userArg); /** /** Loading @@ -157,7 +155,31 @@ public: * @param enumFunc enumeration callback * @param enumFunc enumeration callback * @param userArg passed unchanged to the EnumReadFunction * @param userArg passed unchanged to the EnumReadFunction */ */ void EnumerateRead(EnumReadFunction enumFunc, void* userArg) const; PRUint32 EnumerateRead(EnumReadFunction enumFunc, void* userArg) const; /** * function type provided by the application for enumeration. * @param aKey the key being enumerated * @param aData Reference to data being enumerated, may be altered. e.g. for * nsInterfaceHashtable this is an nsCOMPtr reference... * @parm userArg passed unchanged from Enumerate * @return bitflag combination of * @link PLDHashOperator::PL_DHASH_REMOVE @endlink, * @link PLDHashOperator::PL_DHASH_NEXT PL_DHASH_NEXT @endlink, or * @link PLDHashOperator::PL_DHASH_STOP PL_DHASH_STOP @endlink */ typedef PLDHashOperator (*PR_CALLBACK EnumFunction)(KeyType aKey, DataType& aData, void* userArg); /** * enumerate entries in the hashtable, allowing changes. This * functions write-locks the hashtable. * @param enumFunc enumeration callback * @param userArg passed unchanged to the EnumFunction */ PRUint32 Enumerate(EnumFunction enumFunc, void* userArg); /** /** * reset the hashtable, removing all entries * reset the hashtable, removing all entries Loading @@ -182,6 +204,17 @@ protected: PLDHashEntryHdr *hdr, PLDHashEntryHdr *hdr, PRUint32 number, PRUint32 number, void *arg); void *arg); struct s_EnumArgs { EnumFunction func; void* userArg; }; static PLDHashOperator s_EnumStub(PLDHashTable *table, PLDHashEntryHdr *hdr, PRUint32 number, void *arg); }; }; // // Loading Loading @@ -251,7 +284,7 @@ nsBaseHashtable<KeyClass,DataType,UserDataType>::Get(KeyType aKey, if (mLock) if (mLock) PR_RWLock_Rlock(mLock); PR_RWLock_Rlock(mLock); EntryType* ent = GetEntry(KeyClass::KeyToPointer(aKey)); EntryType* ent = GetEntry(aKey); if (ent) if (ent) { { Loading @@ -278,7 +311,7 @@ nsBaseHashtable<KeyClass,DataType,UserDataType>::Put(KeyType aKey, if (mLock) if (mLock) PR_RWLock_Wlock(mLock); PR_RWLock_Wlock(mLock); EntryType* ent = PutEntry(KeyClass::KeyToPointer(aKey)); EntryType* ent = PutEntry(aKey); if (!ent) if (!ent) { { Loading @@ -303,14 +336,14 @@ nsBaseHashtable<KeyClass,DataType,UserDataType>::Remove(KeyType aKey) if (mLock) if (mLock) PR_RWLock_Wlock(mLock); PR_RWLock_Wlock(mLock); RemoveEntry(KeyClass::KeyToPointer(aKey)); RemoveEntry(aKey); if (mLock) if (mLock) PR_RWLock_Unlock(mLock); PR_RWLock_Unlock(mLock); } } template<class KeyClass,class DataType,class UserDataType> template<class KeyClass,class DataType,class UserDataType> void PRUint32 nsBaseHashtable<KeyClass,DataType,UserDataType>::EnumerateRead nsBaseHashtable<KeyClass,DataType,UserDataType>::EnumerateRead (EnumReadFunction fEnumCall, void* userArg) const (EnumReadFunction fEnumCall, void* userArg) const { { Loading @@ -321,12 +354,38 @@ nsBaseHashtable<KeyClass,DataType,UserDataType>::EnumerateRead PR_RWLock_Rlock(mLock); PR_RWLock_Rlock(mLock); s_EnumReadArgs enumData = { fEnumCall, userArg }; s_EnumReadArgs enumData = { fEnumCall, userArg }; PRUint32 count = PL_DHashTableEnumerate(NS_CONST_CAST(PLDHashTable*,&mTable), PL_DHashTableEnumerate(NS_CONST_CAST(PLDHashTable*,&mTable), s_EnumReadStub, &enumData); if (mLock) PR_RWLock_Unlock(mLock); return count; } template<class KeyClass,class DataType,class UserDataType> PRUint32 nsBaseHashtable<KeyClass,DataType,UserDataType>::Enumerate (EnumFunction fEnumCall, void* userArg) { NS_ASSERTION(mTable.entrySize, "nsBaseHashtable was not initialized properly."); if (mLock) PR_RWLock_Wlock(mLock); s_EnumArgs enumData = { fEnumCall, userArg }; PRUint32 count = PL_DHashTableEnumerate(&mTable, s_EnumStub, s_EnumStub, &enumData); &enumData); if (mLock) if (mLock) PR_RWLock_Unlock(mLock); PR_RWLock_Unlock(mLock); return count; } } template<class KeyClass,class DataType,class UserDataType> template<class KeyClass,class DataType,class UserDataType> Loading Loading @@ -360,4 +419,15 @@ nsBaseHashtable<KeyClass,DataType,UserDataType>::s_EnumReadStub return PL_DHASH_NEXT; return PL_DHASH_NEXT; } } template<class KeyClass,class DataType,class UserDataType> PLDHashOperator nsBaseHashtable<KeyClass,DataType,UserDataType>::s_EnumStub (PLDHashTable *table, PLDHashEntryHdr *hdr, PRUint32 number, void* arg) { EntryType* ent = NS_STATIC_CAST(EntryType*, hdr); s_EnumArgs* eargs = (s_EnumArgs*) arg; return (eargs->func)(ent->GetKey(), ent->mData, eargs->userArg); } #endif // nsBaseHashtable_h__ #endif // nsBaseHashtable_h__ xpcom/glue/nsClassHashtable.h +5 −3 Original line number Original line Diff line number Diff line Loading @@ -40,6 +40,7 @@ #include "nsBaseHashtable.h" #include "nsBaseHashtable.h" #include "nsHashKeys.h" #include "nsHashKeys.h" #include "nsAutoPtr.h" /** /** * templated hashtable class maps keys to C++ object pointers. * templated hashtable class maps keys to C++ object pointers. Loading @@ -55,7 +56,7 @@ class nsClassHashtable : { { public: public: typedef typename KeyClass::KeyType KeyType; typedef typename KeyClass::KeyType KeyType; typedef typename T* UserDataType; typedef T* UserDataType; /** /** * @copydoc nsBaseHashtable::nsBaseHashtable * @copydoc nsBaseHashtable::nsBaseHashtable Loading @@ -74,6 +75,7 @@ public: PRBool Get(KeyType aKey, UserDataType* pData) const; PRBool Get(KeyType aKey, UserDataType* pData) const; }; }; // // // nsClassHashtable definitions // nsClassHashtable definitions // // Loading @@ -86,7 +88,7 @@ nsClassHashtable<KeyClass,T>::Get(KeyType aKey, T** retVal) const PR_RWLock_Rlock(mLock); PR_RWLock_Rlock(mLock); typename nsBaseHashtable<KeyClass,nsAutoPtr<T>,T*>::EntryType* ent = typename nsBaseHashtable<KeyClass,nsAutoPtr<T>,T*>::EntryType* ent = GetEntry(KeyClass::KeyToPointer(aKey)); GetEntry(aKey); if (ent) if (ent) { { Loading xpcom/glue/nsHashKeys.h +10 −13 Original line number Original line Diff line number Diff line Loading @@ -49,19 +49,15 @@ #include NEW_H #include NEW_H /** @file nsHashKeys.h /** @file nsHashKeys.h * standard HashKey classes for nsDataHashtable and relatives. Each of these * standard HashKey classes for nsBaseHashtable and relatives. Each of these * classes follows the nsTHashtable::EntryType specification * classes follows the nsTHashtable::EntryType specification * * * Lightweight keytypes are provided here: * Lightweight keytypes provided here: * nsStringHashKey * nsStringHashKey * nsCStringHashKey * nsCStringHashKey * nsUint32HashKey * nsUint32HashKey * nsISupportsHashKey * nsISupportsHashKey * nsIDHashKey * nsIDHashKey * * Use these keytypes if possible; the templates are already instantiated * for them, and they can be dynamically linked and therefore reduce code * size! */ */ /** /** Loading Loading @@ -91,7 +87,7 @@ public: { { return HashString(*aKey); return HashString(*aKey); } } static PRBool AllowMemMove() { return PR_TRUE; } enum { ALLOW_MEMMOVE = PR_TRUE }; private: private: const nsString mStr; const nsString mStr; Loading Loading @@ -122,7 +118,7 @@ public: { { return HashString(*aKey); return HashString(*aKey); } } static PRBool AllowMemMove() { return PR_TRUE; } enum { ALLOW_MEMMOVE = PR_TRUE }; private: private: const nsCString mStr; const nsCString mStr; Loading @@ -149,7 +145,7 @@ public: static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; } static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; } static PLDHashNumber HashKey(KeyTypePointer aKey) { return *aKey; } static PLDHashNumber HashKey(KeyTypePointer aKey) { return *aKey; } static PRBool AllowMemMove() { return PR_TRUE; } enum { ALLOW_MEMMOVE = PR_TRUE }; private: private: const PRUint32 mValue; const PRUint32 mValue; Loading @@ -166,7 +162,8 @@ public: typedef nsISupports* KeyType; typedef nsISupports* KeyType; typedef const nsISupports* KeyTypePointer; typedef const nsISupports* KeyTypePointer; nsISupportsHashKey(nsISupports* key) : mSupports(key) { } nsISupportsHashKey(const nsISupports* key) : mSupports(NS_CONST_CAST(nsISupports*,key)) { } nsISupportsHashKey(const nsISupportsHashKey& toCopy) : nsISupportsHashKey(const nsISupportsHashKey& toCopy) : mSupports(toCopy.mSupports) { } mSupports(toCopy.mSupports) { } ~nsISupportsHashKey() { } ~nsISupportsHashKey() { } Loading @@ -181,10 +178,10 @@ public: { { return NS_PTR_TO_INT32(aKey) >>2; return NS_PTR_TO_INT32(aKey) >>2; } } static PRBool AllowMemMove() { return PR_TRUE; } enum { ALLOW_MEMMOVE = PR_TRUE }; private: private: const nsCOMPtr<nsISupports> mSupports; nsCOMPtr<nsISupports> mSupports; }; }; /** /** Loading @@ -208,7 +205,7 @@ public: static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; } static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; } static PLDHashNumber HashKey(KeyTypePointer aKey); static PLDHashNumber HashKey(KeyTypePointer aKey); static PRBool AllowMemMove() { return PR_TRUE; } enum { ALLOW_MEMMOVE = PR_TRUE }; private: private: const nsID mID; const nsID mID; Loading xpcom/glue/nsInterfaceHashtable.h +1 −1 Original line number Original line Diff line number Diff line Loading @@ -89,7 +89,7 @@ nsInterfaceHashtable<KeyClass,Interface>::Get PR_RWLock_Rlock(mLock); PR_RWLock_Rlock(mLock); typename nsBaseHashtable<KeyClass, nsCOMPtr<Interface>, Interface*>::EntryType* ent = typename nsBaseHashtable<KeyClass, nsCOMPtr<Interface>, Interface*>::EntryType* ent = GetEntry(KeyClass::KeyToPointer(aKey)); GetEntry(aKey); if (ent) if (ent) { { Loading xpcom/glue/nsTHashtable.h +71 −64 Original line number Original line Diff line number Diff line Loading @@ -53,7 +53,7 @@ * and <strong>must not declare any virtual functions or derive from classes * and <strong>must not declare any virtual functions or derive from classes * with virtual functions.</strong> Any vtable pointer would break the * with virtual functions.</strong> Any vtable pointer would break the * PLDHashTable code. * PLDHashTable code. *<pre> class EntryType : PLDHashEntryHdr *<pre> class EntryType : public PLDHashEntryHdr * { * { * public: or friend nsTHashtable<EntryType>; * public: or friend nsTHashtable<EntryType>; * // KeyType is what we use when Get()ing or Put()ing this entry * // KeyType is what we use when Get()ing or Put()ing this entry Loading Loading @@ -85,9 +85,9 @@ * // HashKey(): calculate the hash number * // HashKey(): calculate the hash number * static PLDHashNumber HashKey(KeyTypePointer aKey); * static PLDHashNumber HashKey(KeyTypePointer aKey); * * * // AllowMemMove(): can we move this class with memmove(), or do we have * // ALLOW_MEMMOVE can we move this class with memmove(), or do we have * // to use the copy constructor? * // to use the copy constructor? * static PRBool AllowMemMove(); * enum { ALLOW_MEMMOVE = PR_(TRUE or FALSE) }; * }</pre> * }</pre> * * * @see nsInterfaceHashtable * @see nsInterfaceHashtable Loading @@ -111,13 +111,19 @@ public: ~nsTHashtable(); ~nsTHashtable(); /** /** * Initialize the class. This function must be called before any other * Initialize the table. This function must be called before any other * class operations. This can fail due to OOM conditions. * class operations. This can fail due to OOM conditions. * @param initSize the initial number of buckets in the hashtable, default 16 * @param initSize the initial number of buckets in the hashtable, default 16 * @return PR_TRUE if the class was initialized properly. * @return PR_TRUE if the class was initialized properly. */ */ PRBool Init(PRUint32 initSize = PL_DHASH_MIN_SIZE); PRBool Init(PRUint32 initSize = PL_DHASH_MIN_SIZE); /** * Check whether the table has been initialized. This can be useful for static hashtables. * @return the initialization state of the class. */ PRBool IsInitialized() const { return mTable.entrySize; } /** /** * KeyType is typedef'ed for ease of use. * KeyType is typedef'ed for ease of use. */ */ Loading @@ -134,7 +140,18 @@ public: * @return pointer to the entry class, if the key exists; nsnull if the * @return pointer to the entry class, if the key exists; nsnull if the * key doesn't exist * key doesn't exist */ */ EntryType* GetEntry(KeyTypePointer aKey) const; EntryType* GetEntry(KeyType aKey) const { NS_ASSERTION(mTable.entrySize, "nsTHashtable was not initialized properly."); EntryType* entry = NS_REINTERPRET_CAST(EntryType*, PL_DHashTableOperate( NS_CONST_CAST(PLDHashTable*,&mTable), EntryType::KeyToPointer(aKey), PL_DHASH_LOOKUP)); return PL_DHASH_ENTRY_IS_BUSY(entry) ? entry : nsnull; } /** /** * Get the entry associated with a key, or create a new entry, * Get the entry associated with a key, or create a new entry, Loading @@ -142,13 +159,42 @@ public: * @return pointer to the entry class retreived; nsnull only if memory * @return pointer to the entry class retreived; nsnull only if memory can't be allocated can't be allocated */ */ EntryType* PutEntry(KeyTypePointer aKey); EntryType* PutEntry(KeyType aKey) { NS_ASSERTION(mTable.entrySize, "nsTHashtable was not initialized properly."); return NS_STATIC_CAST(EntryType*, PL_DHashTableOperate( &mTable, EntryType::KeyToPointer(aKey), PL_DHASH_ADD)); } /** /** * Remove the entry associated with a key. * Remove the entry associated with a key. * @param aKey of the entry to remove * @param aKey of the entry to remove */ */ void RemoveEntry(KeyTypePointer aKey); void RemoveEntry(KeyType aKey) { NS_ASSERTION(mTable.entrySize, "nsTHashtable was not initialized properly."); PL_DHashTableOperate(&mTable, EntryType::KeyToPointer(aKey), PL_DHASH_REMOVE); } /** * Remove the entry associated with a key, but don't resize the hashtable. * This is a low-level method, and is not recommended unless you know what * you're doing and you need the extra performance. This method can be used * during enumeration, while RemoveEntry() cannot. * @param aEntry the entry-pointer to remove (obtained from GetEntry or * the enumerator */ void RawRemoveEntry(EntryType* aEntry) { PL_DHashTableRawRemove(&mTable, aEntry); } /** /** * client must provide an <code>Enumerator</code> function for * client must provide an <code>Enumerator</code> function for Loading @@ -169,12 +215,23 @@ public: * <code>Enumerator</code> function * <code>Enumerator</code> function * @return the number of entries actually enumerated * @return the number of entries actually enumerated */ */ PRUint32 EnumerateEntries(Enumerator enumFunc, void* userArg); PRUint32 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); } /** /** * remove all entries, return hashtable to "pristine" state ;) * remove all entries, return hashtable to "pristine" state ;) */ */ void Clear(); void Clear() { NS_ASSERTION(mTable.entrySize, "nsTHashtable was not initialized properly."); PL_DHashTableEnumerate(&mTable, PL_DHashStubEnumRemove, nsnull); } protected: protected: PLDHashTable mTable; PLDHashTable mTable; Loading Loading @@ -254,9 +311,12 @@ nsTHashtable<EntryType>::Init(PRUint32 initSize) if (mTable.entrySize) if (mTable.entrySize) { { NS_ERROR("nsTHashtable::Init() should not be called twice."); NS_ERROR("nsTHashtable::Init() should not be called twice."); return PR_FALSE; return PR_TRUE; } } if (!EntryType::ALLOW_MEMMOVE) sOps.moveEntry = s_CopyEntry; if (!PL_DHashTableInit(&mTable, &sOps, nsnull, sizeof(EntryType), initSize)) if (!PL_DHashTableInit(&mTable, &sOps, nsnull, sizeof(EntryType), initSize)) { { // if failed, reset "flag" // if failed, reset "flag" Loading @@ -267,59 +327,6 @@ nsTHashtable<EntryType>::Init(PRUint32 initSize) return PR_TRUE; 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 // static definitions template<class EntryType> template<class EntryType> Loading @@ -331,7 +338,7 @@ nsTHashtable<EntryType>::sOps = s_GetKey, s_GetKey, s_HashKey, s_HashKey, s_MatchEntry, s_MatchEntry, EntryType::AllowMemMove() ? ::PL_DHashMoveEntryStub : s_CopyEntry, PL_DHashMoveEntryStub, s_ClearEntry, s_ClearEntry, ::PL_DHashFinalizeStub, ::PL_DHashFinalizeStub, s_InitEntry s_InitEntry Loading Loading
xpcom/glue/nsBaseHashtable.h +83 −13 Original line number Original line Diff line number Diff line Loading @@ -136,8 +136,6 @@ public: /** /** * function type provided by the application for enumeration. * 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 aKey the key being enumerated * @param aData data being enumerated * @param aData data being enumerated * @parm userArg passed unchanged from Enumerate * @parm userArg passed unchanged from Enumerate Loading @@ -147,7 +145,7 @@ public: */ */ typedef PLDHashOperator typedef PLDHashOperator (*PR_CALLBACK EnumReadFunction)(KeyType aKey, (*PR_CALLBACK EnumReadFunction)(KeyType aKey, DataType aData, UserDataType aData, void* userArg); void* userArg); /** /** Loading @@ -157,7 +155,31 @@ public: * @param enumFunc enumeration callback * @param enumFunc enumeration callback * @param userArg passed unchanged to the EnumReadFunction * @param userArg passed unchanged to the EnumReadFunction */ */ void EnumerateRead(EnumReadFunction enumFunc, void* userArg) const; PRUint32 EnumerateRead(EnumReadFunction enumFunc, void* userArg) const; /** * function type provided by the application for enumeration. * @param aKey the key being enumerated * @param aData Reference to data being enumerated, may be altered. e.g. for * nsInterfaceHashtable this is an nsCOMPtr reference... * @parm userArg passed unchanged from Enumerate * @return bitflag combination of * @link PLDHashOperator::PL_DHASH_REMOVE @endlink, * @link PLDHashOperator::PL_DHASH_NEXT PL_DHASH_NEXT @endlink, or * @link PLDHashOperator::PL_DHASH_STOP PL_DHASH_STOP @endlink */ typedef PLDHashOperator (*PR_CALLBACK EnumFunction)(KeyType aKey, DataType& aData, void* userArg); /** * enumerate entries in the hashtable, allowing changes. This * functions write-locks the hashtable. * @param enumFunc enumeration callback * @param userArg passed unchanged to the EnumFunction */ PRUint32 Enumerate(EnumFunction enumFunc, void* userArg); /** /** * reset the hashtable, removing all entries * reset the hashtable, removing all entries Loading @@ -182,6 +204,17 @@ protected: PLDHashEntryHdr *hdr, PLDHashEntryHdr *hdr, PRUint32 number, PRUint32 number, void *arg); void *arg); struct s_EnumArgs { EnumFunction func; void* userArg; }; static PLDHashOperator s_EnumStub(PLDHashTable *table, PLDHashEntryHdr *hdr, PRUint32 number, void *arg); }; }; // // Loading Loading @@ -251,7 +284,7 @@ nsBaseHashtable<KeyClass,DataType,UserDataType>::Get(KeyType aKey, if (mLock) if (mLock) PR_RWLock_Rlock(mLock); PR_RWLock_Rlock(mLock); EntryType* ent = GetEntry(KeyClass::KeyToPointer(aKey)); EntryType* ent = GetEntry(aKey); if (ent) if (ent) { { Loading @@ -278,7 +311,7 @@ nsBaseHashtable<KeyClass,DataType,UserDataType>::Put(KeyType aKey, if (mLock) if (mLock) PR_RWLock_Wlock(mLock); PR_RWLock_Wlock(mLock); EntryType* ent = PutEntry(KeyClass::KeyToPointer(aKey)); EntryType* ent = PutEntry(aKey); if (!ent) if (!ent) { { Loading @@ -303,14 +336,14 @@ nsBaseHashtable<KeyClass,DataType,UserDataType>::Remove(KeyType aKey) if (mLock) if (mLock) PR_RWLock_Wlock(mLock); PR_RWLock_Wlock(mLock); RemoveEntry(KeyClass::KeyToPointer(aKey)); RemoveEntry(aKey); if (mLock) if (mLock) PR_RWLock_Unlock(mLock); PR_RWLock_Unlock(mLock); } } template<class KeyClass,class DataType,class UserDataType> template<class KeyClass,class DataType,class UserDataType> void PRUint32 nsBaseHashtable<KeyClass,DataType,UserDataType>::EnumerateRead nsBaseHashtable<KeyClass,DataType,UserDataType>::EnumerateRead (EnumReadFunction fEnumCall, void* userArg) const (EnumReadFunction fEnumCall, void* userArg) const { { Loading @@ -321,12 +354,38 @@ nsBaseHashtable<KeyClass,DataType,UserDataType>::EnumerateRead PR_RWLock_Rlock(mLock); PR_RWLock_Rlock(mLock); s_EnumReadArgs enumData = { fEnumCall, userArg }; s_EnumReadArgs enumData = { fEnumCall, userArg }; PRUint32 count = PL_DHashTableEnumerate(NS_CONST_CAST(PLDHashTable*,&mTable), PL_DHashTableEnumerate(NS_CONST_CAST(PLDHashTable*,&mTable), s_EnumReadStub, &enumData); if (mLock) PR_RWLock_Unlock(mLock); return count; } template<class KeyClass,class DataType,class UserDataType> PRUint32 nsBaseHashtable<KeyClass,DataType,UserDataType>::Enumerate (EnumFunction fEnumCall, void* userArg) { NS_ASSERTION(mTable.entrySize, "nsBaseHashtable was not initialized properly."); if (mLock) PR_RWLock_Wlock(mLock); s_EnumArgs enumData = { fEnumCall, userArg }; PRUint32 count = PL_DHashTableEnumerate(&mTable, s_EnumStub, s_EnumStub, &enumData); &enumData); if (mLock) if (mLock) PR_RWLock_Unlock(mLock); PR_RWLock_Unlock(mLock); return count; } } template<class KeyClass,class DataType,class UserDataType> template<class KeyClass,class DataType,class UserDataType> Loading Loading @@ -360,4 +419,15 @@ nsBaseHashtable<KeyClass,DataType,UserDataType>::s_EnumReadStub return PL_DHASH_NEXT; return PL_DHASH_NEXT; } } template<class KeyClass,class DataType,class UserDataType> PLDHashOperator nsBaseHashtable<KeyClass,DataType,UserDataType>::s_EnumStub (PLDHashTable *table, PLDHashEntryHdr *hdr, PRUint32 number, void* arg) { EntryType* ent = NS_STATIC_CAST(EntryType*, hdr); s_EnumArgs* eargs = (s_EnumArgs*) arg; return (eargs->func)(ent->GetKey(), ent->mData, eargs->userArg); } #endif // nsBaseHashtable_h__ #endif // nsBaseHashtable_h__
xpcom/glue/nsClassHashtable.h +5 −3 Original line number Original line Diff line number Diff line Loading @@ -40,6 +40,7 @@ #include "nsBaseHashtable.h" #include "nsBaseHashtable.h" #include "nsHashKeys.h" #include "nsHashKeys.h" #include "nsAutoPtr.h" /** /** * templated hashtable class maps keys to C++ object pointers. * templated hashtable class maps keys to C++ object pointers. Loading @@ -55,7 +56,7 @@ class nsClassHashtable : { { public: public: typedef typename KeyClass::KeyType KeyType; typedef typename KeyClass::KeyType KeyType; typedef typename T* UserDataType; typedef T* UserDataType; /** /** * @copydoc nsBaseHashtable::nsBaseHashtable * @copydoc nsBaseHashtable::nsBaseHashtable Loading @@ -74,6 +75,7 @@ public: PRBool Get(KeyType aKey, UserDataType* pData) const; PRBool Get(KeyType aKey, UserDataType* pData) const; }; }; // // // nsClassHashtable definitions // nsClassHashtable definitions // // Loading @@ -86,7 +88,7 @@ nsClassHashtable<KeyClass,T>::Get(KeyType aKey, T** retVal) const PR_RWLock_Rlock(mLock); PR_RWLock_Rlock(mLock); typename nsBaseHashtable<KeyClass,nsAutoPtr<T>,T*>::EntryType* ent = typename nsBaseHashtable<KeyClass,nsAutoPtr<T>,T*>::EntryType* ent = GetEntry(KeyClass::KeyToPointer(aKey)); GetEntry(aKey); if (ent) if (ent) { { Loading
xpcom/glue/nsHashKeys.h +10 −13 Original line number Original line Diff line number Diff line Loading @@ -49,19 +49,15 @@ #include NEW_H #include NEW_H /** @file nsHashKeys.h /** @file nsHashKeys.h * standard HashKey classes for nsDataHashtable and relatives. Each of these * standard HashKey classes for nsBaseHashtable and relatives. Each of these * classes follows the nsTHashtable::EntryType specification * classes follows the nsTHashtable::EntryType specification * * * Lightweight keytypes are provided here: * Lightweight keytypes provided here: * nsStringHashKey * nsStringHashKey * nsCStringHashKey * nsCStringHashKey * nsUint32HashKey * nsUint32HashKey * nsISupportsHashKey * nsISupportsHashKey * nsIDHashKey * nsIDHashKey * * Use these keytypes if possible; the templates are already instantiated * for them, and they can be dynamically linked and therefore reduce code * size! */ */ /** /** Loading Loading @@ -91,7 +87,7 @@ public: { { return HashString(*aKey); return HashString(*aKey); } } static PRBool AllowMemMove() { return PR_TRUE; } enum { ALLOW_MEMMOVE = PR_TRUE }; private: private: const nsString mStr; const nsString mStr; Loading Loading @@ -122,7 +118,7 @@ public: { { return HashString(*aKey); return HashString(*aKey); } } static PRBool AllowMemMove() { return PR_TRUE; } enum { ALLOW_MEMMOVE = PR_TRUE }; private: private: const nsCString mStr; const nsCString mStr; Loading @@ -149,7 +145,7 @@ public: static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; } static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; } static PLDHashNumber HashKey(KeyTypePointer aKey) { return *aKey; } static PLDHashNumber HashKey(KeyTypePointer aKey) { return *aKey; } static PRBool AllowMemMove() { return PR_TRUE; } enum { ALLOW_MEMMOVE = PR_TRUE }; private: private: const PRUint32 mValue; const PRUint32 mValue; Loading @@ -166,7 +162,8 @@ public: typedef nsISupports* KeyType; typedef nsISupports* KeyType; typedef const nsISupports* KeyTypePointer; typedef const nsISupports* KeyTypePointer; nsISupportsHashKey(nsISupports* key) : mSupports(key) { } nsISupportsHashKey(const nsISupports* key) : mSupports(NS_CONST_CAST(nsISupports*,key)) { } nsISupportsHashKey(const nsISupportsHashKey& toCopy) : nsISupportsHashKey(const nsISupportsHashKey& toCopy) : mSupports(toCopy.mSupports) { } mSupports(toCopy.mSupports) { } ~nsISupportsHashKey() { } ~nsISupportsHashKey() { } Loading @@ -181,10 +178,10 @@ public: { { return NS_PTR_TO_INT32(aKey) >>2; return NS_PTR_TO_INT32(aKey) >>2; } } static PRBool AllowMemMove() { return PR_TRUE; } enum { ALLOW_MEMMOVE = PR_TRUE }; private: private: const nsCOMPtr<nsISupports> mSupports; nsCOMPtr<nsISupports> mSupports; }; }; /** /** Loading @@ -208,7 +205,7 @@ public: static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; } static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; } static PLDHashNumber HashKey(KeyTypePointer aKey); static PLDHashNumber HashKey(KeyTypePointer aKey); static PRBool AllowMemMove() { return PR_TRUE; } enum { ALLOW_MEMMOVE = PR_TRUE }; private: private: const nsID mID; const nsID mID; Loading
xpcom/glue/nsInterfaceHashtable.h +1 −1 Original line number Original line Diff line number Diff line Loading @@ -89,7 +89,7 @@ nsInterfaceHashtable<KeyClass,Interface>::Get PR_RWLock_Rlock(mLock); PR_RWLock_Rlock(mLock); typename nsBaseHashtable<KeyClass, nsCOMPtr<Interface>, Interface*>::EntryType* ent = typename nsBaseHashtable<KeyClass, nsCOMPtr<Interface>, Interface*>::EntryType* ent = GetEntry(KeyClass::KeyToPointer(aKey)); GetEntry(aKey); if (ent) if (ent) { { Loading
xpcom/glue/nsTHashtable.h +71 −64 Original line number Original line Diff line number Diff line Loading @@ -53,7 +53,7 @@ * and <strong>must not declare any virtual functions or derive from classes * and <strong>must not declare any virtual functions or derive from classes * with virtual functions.</strong> Any vtable pointer would break the * with virtual functions.</strong> Any vtable pointer would break the * PLDHashTable code. * PLDHashTable code. *<pre> class EntryType : PLDHashEntryHdr *<pre> class EntryType : public PLDHashEntryHdr * { * { * public: or friend nsTHashtable<EntryType>; * public: or friend nsTHashtable<EntryType>; * // KeyType is what we use when Get()ing or Put()ing this entry * // KeyType is what we use when Get()ing or Put()ing this entry Loading Loading @@ -85,9 +85,9 @@ * // HashKey(): calculate the hash number * // HashKey(): calculate the hash number * static PLDHashNumber HashKey(KeyTypePointer aKey); * static PLDHashNumber HashKey(KeyTypePointer aKey); * * * // AllowMemMove(): can we move this class with memmove(), or do we have * // ALLOW_MEMMOVE can we move this class with memmove(), or do we have * // to use the copy constructor? * // to use the copy constructor? * static PRBool AllowMemMove(); * enum { ALLOW_MEMMOVE = PR_(TRUE or FALSE) }; * }</pre> * }</pre> * * * @see nsInterfaceHashtable * @see nsInterfaceHashtable Loading @@ -111,13 +111,19 @@ public: ~nsTHashtable(); ~nsTHashtable(); /** /** * Initialize the class. This function must be called before any other * Initialize the table. This function must be called before any other * class operations. This can fail due to OOM conditions. * class operations. This can fail due to OOM conditions. * @param initSize the initial number of buckets in the hashtable, default 16 * @param initSize the initial number of buckets in the hashtable, default 16 * @return PR_TRUE if the class was initialized properly. * @return PR_TRUE if the class was initialized properly. */ */ PRBool Init(PRUint32 initSize = PL_DHASH_MIN_SIZE); PRBool Init(PRUint32 initSize = PL_DHASH_MIN_SIZE); /** * Check whether the table has been initialized. This can be useful for static hashtables. * @return the initialization state of the class. */ PRBool IsInitialized() const { return mTable.entrySize; } /** /** * KeyType is typedef'ed for ease of use. * KeyType is typedef'ed for ease of use. */ */ Loading @@ -134,7 +140,18 @@ public: * @return pointer to the entry class, if the key exists; nsnull if the * @return pointer to the entry class, if the key exists; nsnull if the * key doesn't exist * key doesn't exist */ */ EntryType* GetEntry(KeyTypePointer aKey) const; EntryType* GetEntry(KeyType aKey) const { NS_ASSERTION(mTable.entrySize, "nsTHashtable was not initialized properly."); EntryType* entry = NS_REINTERPRET_CAST(EntryType*, PL_DHashTableOperate( NS_CONST_CAST(PLDHashTable*,&mTable), EntryType::KeyToPointer(aKey), PL_DHASH_LOOKUP)); return PL_DHASH_ENTRY_IS_BUSY(entry) ? entry : nsnull; } /** /** * Get the entry associated with a key, or create a new entry, * Get the entry associated with a key, or create a new entry, Loading @@ -142,13 +159,42 @@ public: * @return pointer to the entry class retreived; nsnull only if memory * @return pointer to the entry class retreived; nsnull only if memory can't be allocated can't be allocated */ */ EntryType* PutEntry(KeyTypePointer aKey); EntryType* PutEntry(KeyType aKey) { NS_ASSERTION(mTable.entrySize, "nsTHashtable was not initialized properly."); return NS_STATIC_CAST(EntryType*, PL_DHashTableOperate( &mTable, EntryType::KeyToPointer(aKey), PL_DHASH_ADD)); } /** /** * Remove the entry associated with a key. * Remove the entry associated with a key. * @param aKey of the entry to remove * @param aKey of the entry to remove */ */ void RemoveEntry(KeyTypePointer aKey); void RemoveEntry(KeyType aKey) { NS_ASSERTION(mTable.entrySize, "nsTHashtable was not initialized properly."); PL_DHashTableOperate(&mTable, EntryType::KeyToPointer(aKey), PL_DHASH_REMOVE); } /** * Remove the entry associated with a key, but don't resize the hashtable. * This is a low-level method, and is not recommended unless you know what * you're doing and you need the extra performance. This method can be used * during enumeration, while RemoveEntry() cannot. * @param aEntry the entry-pointer to remove (obtained from GetEntry or * the enumerator */ void RawRemoveEntry(EntryType* aEntry) { PL_DHashTableRawRemove(&mTable, aEntry); } /** /** * client must provide an <code>Enumerator</code> function for * client must provide an <code>Enumerator</code> function for Loading @@ -169,12 +215,23 @@ public: * <code>Enumerator</code> function * <code>Enumerator</code> function * @return the number of entries actually enumerated * @return the number of entries actually enumerated */ */ PRUint32 EnumerateEntries(Enumerator enumFunc, void* userArg); PRUint32 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); } /** /** * remove all entries, return hashtable to "pristine" state ;) * remove all entries, return hashtable to "pristine" state ;) */ */ void Clear(); void Clear() { NS_ASSERTION(mTable.entrySize, "nsTHashtable was not initialized properly."); PL_DHashTableEnumerate(&mTable, PL_DHashStubEnumRemove, nsnull); } protected: protected: PLDHashTable mTable; PLDHashTable mTable; Loading Loading @@ -254,9 +311,12 @@ nsTHashtable<EntryType>::Init(PRUint32 initSize) if (mTable.entrySize) if (mTable.entrySize) { { NS_ERROR("nsTHashtable::Init() should not be called twice."); NS_ERROR("nsTHashtable::Init() should not be called twice."); return PR_FALSE; return PR_TRUE; } } if (!EntryType::ALLOW_MEMMOVE) sOps.moveEntry = s_CopyEntry; if (!PL_DHashTableInit(&mTable, &sOps, nsnull, sizeof(EntryType), initSize)) if (!PL_DHashTableInit(&mTable, &sOps, nsnull, sizeof(EntryType), initSize)) { { // if failed, reset "flag" // if failed, reset "flag" Loading @@ -267,59 +327,6 @@ nsTHashtable<EntryType>::Init(PRUint32 initSize) return PR_TRUE; 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 // static definitions template<class EntryType> template<class EntryType> Loading @@ -331,7 +338,7 @@ nsTHashtable<EntryType>::sOps = s_GetKey, s_GetKey, s_HashKey, s_HashKey, s_MatchEntry, s_MatchEntry, EntryType::AllowMemMove() ? ::PL_DHashMoveEntryStub : s_CopyEntry, PL_DHashMoveEntryStub, s_ClearEntry, s_ClearEntry, ::PL_DHashFinalizeStub, ::PL_DHashFinalizeStub, s_InitEntry s_InitEntry Loading