On x86 compilers without fastcall, simulate it when invoking traces and un-simulate...
[wine-gecko.git] / xpcom / glue / nsBaseHashtable.h
blob48e9fd8f3b2925232a7e60733c2e6f6690eefed6
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
15 * The Original Code is C++ hashtable templates.
17 * The Initial Developer of the Original Code is
18 * Benjamin Smedberg.
19 * Portions created by the Initial Developer are Copyright (C) 2002
20 * the Initial Developer. All Rights Reserved.
22 * Contributor(s):
24 * Alternatively, the contents of this file may be used under the terms of
25 * either the GNU General Public License Version 2 or later (the "GPL"), or
26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
38 #ifndef nsBaseHashtable_h__
39 #define nsBaseHashtable_h__
41 #include "nsTHashtable.h"
42 #include "prlock.h"
43 #include "nsDebug.h"
45 template<class KeyClass,class DataType,class UserDataType>
46 class nsBaseHashtable; // forward declaration
48 /**
49 * the private nsTHashtable::EntryType class used by nsBaseHashtable
50 * @see nsTHashtable for the specification of this class
51 * @see nsBaseHashtable for template parameters
53 template<class KeyClass,class DataType>
54 class nsBaseHashtableET : public KeyClass
56 public:
57 DataType mData;
58 friend class nsTHashtable< nsBaseHashtableET<KeyClass,DataType> >;
60 private:
61 typedef typename KeyClass::KeyType KeyType;
62 typedef typename KeyClass::KeyTypePointer KeyTypePointer;
64 nsBaseHashtableET(KeyTypePointer aKey);
65 nsBaseHashtableET(nsBaseHashtableET<KeyClass,DataType>& toCopy);
66 ~nsBaseHashtableET();
69 /**
70 * templated hashtable for simple data types
71 * This class manages simple data types that do not need construction or
72 * destruction.
74 * @param KeyClass a wrapper-class for the hashtable key, see nsHashKeys.h
75 * for a complete specification.
76 * @param DataType the datatype stored in the hashtable,
77 * for example, PRUint32 or nsCOMPtr. If UserDataType is not the same,
78 * DataType must implicitly cast to UserDataType
79 * @param UserDataType the user sees, for example PRUint32 or nsISupports*
81 template<class KeyClass,class DataType,class UserDataType>
82 class nsBaseHashtable :
83 protected nsTHashtable< nsBaseHashtableET<KeyClass,DataType> >
85 public:
86 typedef typename KeyClass::KeyType KeyType;
87 typedef nsBaseHashtableET<KeyClass,DataType> EntryType;
89 // default constructor+destructor are fine
91 /**
92 * Initialize the object.
93 * @param initSize the initial number of buckets in the hashtable,
94 * default 16
95 * locking on all class methods
96 * @return PR_TRUE if the object was initialized properly.
98 PRBool Init(PRUint32 initSize = PL_DHASH_MIN_SIZE)
99 { return nsTHashtable<EntryType>::Init(initSize); }
102 * Check whether the table has been initialized.
103 * This function is especially useful for static hashtables.
104 * @return PR_TRUE if the table has been initialized.
106 PRBool IsInitialized() const { return !!this->mTable.entrySize; }
109 * Return the number of entries in the table.
110 * @return number of entries
112 PRUint32 Count() const
113 { return nsTHashtable<EntryType>::Count(); }
116 * retrieve the value for a key.
117 * @param aKey the key to retreive
118 * @param pData data associated with this key will be placed at this
119 * pointer. If you only need to check if the key exists, pData
120 * may be null.
121 * @return PR_TRUE if the key exists. If key does not exist, pData is not
122 * modified.
124 PRBool Get(KeyType aKey, UserDataType* pData) const
126 EntryType* ent = GetEntry(aKey);
128 if (!ent)
129 return PR_FALSE;
131 if (pData)
132 *pData = ent->mData;
134 return PR_TRUE;
138 * put a new value for the associated key
139 * @param aKey the key to put
140 * @param aData the new data
141 * @return always PR_TRUE, unless memory allocation failed
143 PRBool Put(KeyType aKey, UserDataType aData)
145 EntryType* ent = PutEntry(aKey);
147 if (!ent)
148 return PR_FALSE;
150 ent->mData = aData;
152 return PR_TRUE;
156 * remove the data for the associated key
157 * @param aKey the key to remove from the hashtable
159 void Remove(KeyType aKey) { RemoveEntry(aKey); }
162 * function type provided by the application for enumeration.
163 * @param aKey the key being enumerated
164 * @param aData data being enumerated
165 * @parm userArg passed unchanged from Enumerate
166 * @return either
167 * @link PLDHashOperator::PL_DHASH_NEXT PL_DHASH_NEXT @endlink or
168 * @link PLDHashOperator::PL_DHASH_STOP PL_DHASH_STOP @endlink
170 typedef PLDHashOperator
171 (*PR_CALLBACK EnumReadFunction)(KeyType aKey,
172 UserDataType aData,
173 void* userArg);
176 * enumerate entries in the hashtable, without allowing changes
177 * @param enumFunc enumeration callback
178 * @param userArg passed unchanged to the EnumReadFunction
180 PRUint32 EnumerateRead(EnumReadFunction enumFunc, void* userArg) const
182 NS_ASSERTION(this->mTable.entrySize,
183 "nsBaseHashtable was not initialized properly.");
185 s_EnumReadArgs enumData = { enumFunc, userArg };
186 return PL_DHashTableEnumerate(const_cast<PLDHashTable*>(&this->mTable),
187 s_EnumReadStub,
188 &enumData);
192 * function type provided by the application for enumeration.
193 * @param aKey the key being enumerated
194 * @param aData Reference to data being enumerated, may be altered. e.g. for
195 * nsInterfaceHashtable this is an nsCOMPtr reference...
196 * @parm userArg passed unchanged from Enumerate
197 * @return bitflag combination of
198 * @link PLDHashOperator::PL_DHASH_REMOVE @endlink,
199 * @link PLDHashOperator::PL_DHASH_NEXT PL_DHASH_NEXT @endlink, or
200 * @link PLDHashOperator::PL_DHASH_STOP PL_DHASH_STOP @endlink
202 typedef PLDHashOperator
203 (*PR_CALLBACK EnumFunction)(KeyType aKey,
204 DataType& aData,
205 void* userArg);
208 * enumerate entries in the hashtable, allowing changes. This
209 * functions write-locks the hashtable.
210 * @param enumFunc enumeration callback
211 * @param userArg passed unchanged to the EnumFunction
213 PRUint32 Enumerate(EnumFunction enumFunc, void* userArg)
215 NS_ASSERTION(this->mTable.entrySize,
216 "nsBaseHashtable was not initialized properly.");
218 s_EnumArgs enumData = { enumFunc, userArg };
219 return PL_DHashTableEnumerate(&this->mTable,
220 s_EnumStub,
221 &enumData);
225 * reset the hashtable, removing all entries
227 void Clear() { nsTHashtable<EntryType>::Clear(); }
229 protected:
231 * used internally during EnumerateRead. Allocated on the stack.
232 * @param func the enumerator passed to EnumerateRead
233 * @param userArg the userArg passed to EnumerateRead
235 struct s_EnumReadArgs
237 EnumReadFunction func;
238 void* userArg;
241 static PLDHashOperator s_EnumReadStub(PLDHashTable *table,
242 PLDHashEntryHdr *hdr,
243 PRUint32 number,
244 void *arg);
246 struct s_EnumArgs
248 EnumFunction func;
249 void* userArg;
252 static PLDHashOperator s_EnumStub(PLDHashTable *table,
253 PLDHashEntryHdr *hdr,
254 PRUint32 number,
255 void *arg);
259 * This class is a thread-safe version of nsBaseHashtable.
261 template<class KeyClass,class DataType,class UserDataType>
262 class nsBaseHashtableMT :
263 protected nsBaseHashtable<KeyClass,DataType,UserDataType>
265 public:
266 typedef typename
267 nsBaseHashtable<KeyClass,DataType,UserDataType>::EntryType EntryType;
268 typedef typename
269 nsBaseHashtable<KeyClass,DataType,UserDataType>::KeyType KeyType;
270 typedef typename
271 nsBaseHashtable<KeyClass,DataType,UserDataType>::EnumFunction EnumFunction;
272 typedef typename
273 nsBaseHashtable<KeyClass,DataType,UserDataType>::EnumReadFunction EnumReadFunction;
275 nsBaseHashtableMT() : mLock(nsnull) { }
276 ~nsBaseHashtableMT();
278 PRBool Init(PRUint32 initSize = PL_DHASH_MIN_SIZE);
279 PRBool IsInitialized() const { return mLock != nsnull; }
280 PRUint32 Count() const;
281 PRBool Get(KeyType aKey, UserDataType* pData) const;
282 PRBool Put(KeyType aKey, UserDataType aData);
283 void Remove(KeyType aKey);
285 PRUint32 EnumerateRead(EnumReadFunction enumFunc, void* userArg) const;
286 PRUint32 Enumerate(EnumFunction enumFunc, void* userArg);
287 void Clear();
289 protected:
290 PRLock* mLock;
295 // nsBaseHashtableET definitions
298 template<class KeyClass,class DataType>
299 nsBaseHashtableET<KeyClass,DataType>::nsBaseHashtableET(KeyTypePointer aKey) :
300 KeyClass(aKey)
303 template<class KeyClass,class DataType>
304 nsBaseHashtableET<KeyClass,DataType>::nsBaseHashtableET
305 (nsBaseHashtableET<KeyClass,DataType>& toCopy) :
306 KeyClass(toCopy),
307 mData(toCopy.mData)
310 template<class KeyClass,class DataType>
311 nsBaseHashtableET<KeyClass,DataType>::~nsBaseHashtableET()
316 // nsBaseHashtable definitions
319 template<class KeyClass,class DataType,class UserDataType>
320 PLDHashOperator
321 nsBaseHashtable<KeyClass,DataType,UserDataType>::s_EnumReadStub
322 (PLDHashTable *table, PLDHashEntryHdr *hdr, PRUint32 number, void* arg)
324 EntryType* ent = static_cast<EntryType*>(hdr);
325 s_EnumReadArgs* eargs = (s_EnumReadArgs*) arg;
327 PLDHashOperator res = (eargs->func)(ent->GetKey(), ent->mData, eargs->userArg);
329 NS_ASSERTION( !(res & PL_DHASH_REMOVE ),
330 "PL_DHASH_REMOVE return during const enumeration; ignoring.");
332 if (res & PL_DHASH_STOP)
333 return PL_DHASH_STOP;
335 return PL_DHASH_NEXT;
338 template<class KeyClass,class DataType,class UserDataType>
339 PLDHashOperator
340 nsBaseHashtable<KeyClass,DataType,UserDataType>::s_EnumStub
341 (PLDHashTable *table, PLDHashEntryHdr *hdr, PRUint32 number, void* arg)
343 EntryType* ent = static_cast<EntryType*>(hdr);
344 s_EnumArgs* eargs = (s_EnumArgs*) arg;
346 return (eargs->func)(ent->GetKey(), ent->mData, eargs->userArg);
351 // nsBaseHashtableMT definitions
354 template<class KeyClass,class DataType,class UserDataType>
355 nsBaseHashtableMT<KeyClass,DataType,UserDataType>::~nsBaseHashtableMT()
357 if (this->mLock)
358 PR_DestroyLock(this->mLock);
361 template<class KeyClass,class DataType,class UserDataType>
362 PRBool
363 nsBaseHashtableMT<KeyClass,DataType,UserDataType>::Init(PRUint32 initSize)
365 if (!nsTHashtable<EntryType>::IsInitialized() && !nsTHashtable<EntryType>::Init(initSize))
366 return PR_FALSE;
368 this->mLock = PR_NewLock();
369 NS_ASSERTION(this->mLock, "Error creating lock during nsBaseHashtableL::Init()");
371 return (this->mLock != nsnull);
374 template<class KeyClass,class DataType,class UserDataType>
375 PRUint32
376 nsBaseHashtableMT<KeyClass,DataType,UserDataType>::Count() const
378 PR_Lock(this->mLock);
379 PRUint32 count = nsTHashtable<EntryType>::Count();
380 PR_Unlock(this->mLock);
382 return count;
385 template<class KeyClass,class DataType,class UserDataType>
386 PRBool
387 nsBaseHashtableMT<KeyClass,DataType,UserDataType>::Get(KeyType aKey,
388 UserDataType* pData) const
390 PR_Lock(this->mLock);
391 PRBool res =
392 nsBaseHashtable<KeyClass,DataType,UserDataType>::Get(aKey, pData);
393 PR_Unlock(this->mLock);
395 return res;
398 template<class KeyClass,class DataType,class UserDataType>
399 PRBool
400 nsBaseHashtableMT<KeyClass,DataType,UserDataType>::Put(KeyType aKey,
401 UserDataType aData)
403 PR_Lock(this->mLock);
404 PRBool res =
405 nsBaseHashtable<KeyClass,DataType,UserDataType>::Put(aKey, aData);
406 PR_Unlock(this->mLock);
408 return res;
411 template<class KeyClass,class DataType,class UserDataType>
412 void
413 nsBaseHashtableMT<KeyClass,DataType,UserDataType>::Remove(KeyType aKey)
415 PR_Lock(this->mLock);
416 nsBaseHashtable<KeyClass,DataType,UserDataType>::Remove(aKey);
417 PR_Unlock(this->mLock);
420 template<class KeyClass,class DataType,class UserDataType>
421 PRUint32
422 nsBaseHashtableMT<KeyClass,DataType,UserDataType>::EnumerateRead
423 (EnumReadFunction fEnumCall, void* userArg) const
425 PR_Lock(this->mLock);
426 PRUint32 count =
427 nsBaseHashtable<KeyClass,DataType,UserDataType>::EnumerateRead(fEnumCall, userArg);
428 PR_Unlock(this->mLock);
430 return count;
433 template<class KeyClass,class DataType,class UserDataType>
434 PRUint32
435 nsBaseHashtableMT<KeyClass,DataType,UserDataType>::Enumerate
436 (EnumFunction fEnumCall, void* userArg)
438 PR_Lock(this->mLock);
439 PRUint32 count =
440 nsBaseHashtable<KeyClass,DataType,UserDataType>::Enumerate(fEnumCall, userArg);
441 PR_Unlock(this->mLock);
443 return count;
446 template<class KeyClass,class DataType,class UserDataType>
447 void
448 nsBaseHashtableMT<KeyClass,DataType,UserDataType>::Clear()
450 PR_Lock(this->mLock);
451 nsBaseHashtable<KeyClass,DataType,UserDataType>::Clear();
452 PR_Unlock(this->mLock);
455 #endif // nsBaseHashtable_h__