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
4 : *
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/
9 : *
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.
14 : *
15 : * The Original Code is C++ hashtable templates.
16 : *
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.
21 : *
22 : * Contributor(s):
23 : * Neil Rashbrook <neil@parkwaycc.co.uk>
24 : *
25 : * Alternatively, the contents of this file may be used under the terms of
26 : * either the GNU General Public License Version 2 or later (the "GPL"), or
27 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 : * in which case the provisions of the GPL or the LGPL are applicable instead
29 : * of those above. If you wish to allow use of your version of this file only
30 : * under the terms of either the GPL or the LGPL, and not to allow others to
31 : * use your version of this file under the terms of the MPL, indicate your
32 : * decision by deleting the provisions above and replace them with the notice
33 : * and other provisions required by the GPL or the LGPL. If you do not delete
34 : * the provisions above, a recipient may use your version of this file under
35 : * the terms of any one of the MPL, the GPL or the LGPL.
36 : *
37 : * ***** END LICENSE BLOCK ***** */
38 :
39 : #ifndef nsRefPtrHashtable_h__
40 : #define nsRefPtrHashtable_h__
41 :
42 : #include "nsBaseHashtable.h"
43 : #include "nsHashKeys.h"
44 : #include "nsAutoPtr.h"
45 :
46 : /**
47 : * templated hashtable class maps keys to reference pointers.
48 : * See nsBaseHashtable for complete declaration.
49 : * @param KeyClass a wrapper-class for the hashtable key, see nsHashKeys.h
50 : * for a complete specification.
51 : * @param RefPtr the reference-type being wrapped
52 : * @see nsDataHashtable, nsClassHashtable
53 : */
54 : template<class KeyClass, class RefPtr>
55 : class nsRefPtrHashtable :
56 : public nsBaseHashtable< KeyClass, nsRefPtr<RefPtr> , RefPtr* >
57 23411 : {
58 : public:
59 : typedef typename KeyClass::KeyType KeyType;
60 : typedef RefPtr* UserDataType;
61 : typedef nsBaseHashtable< KeyClass, nsRefPtr<RefPtr> , RefPtr* > base_type;
62 :
63 : /**
64 : * @copydoc nsBaseHashtable::Get
65 : * @param pData This is an XPCOM getter, so pData is already_addrefed.
66 : * If the key doesn't exist, pData will be set to nsnull.
67 : */
68 : bool Get(KeyType aKey, UserDataType* pData) const;
69 :
70 : /**
71 : * Gets a weak reference to the hashtable entry.
72 : * @param aFound If not nsnull, will be set to true if the entry is found,
73 : * to false otherwise.
74 : * @return The entry, or nsnull if not found. Do not release this pointer!
75 : */
76 : RefPtr* GetWeak(KeyType aKey, bool* aFound = nsnull) const;
77 : };
78 :
79 : /**
80 : * Thread-safe version of nsRefPtrHashtable
81 : * @param KeyClass a wrapper-class for the hashtable key, see nsHashKeys.h
82 : * for a complete specification.
83 : * @param RefPtr the reference-type being wrapped
84 : */
85 : template<class KeyClass, class RefPtr>
86 : class nsRefPtrHashtableMT :
87 : public nsBaseHashtableMT< KeyClass, nsRefPtr<RefPtr> , RefPtr* >
88 : {
89 : public:
90 : typedef typename KeyClass::KeyType KeyType;
91 : typedef RefPtr* UserDataType;
92 : typedef nsBaseHashtableMT< KeyClass, nsRefPtr<RefPtr> , RefPtr* > base_type;
93 :
94 : /**
95 : * @copydoc nsBaseHashtable::Get
96 : * @param pData This is an XPCOM getter, so pData is already_addrefed.
97 : * If the key doesn't exist, pData will be set to nsnull.
98 : */
99 : bool Get(KeyType aKey, UserDataType* pData) const;
100 :
101 : // GetWeak does not make sense on a multi-threaded hashtable, where another
102 : // thread may remove the entry (and hence release it) as soon as GetWeak
103 : // returns
104 : };
105 :
106 :
107 : //
108 : // nsRefPtrHashtable definitions
109 : //
110 :
111 : template<class KeyClass, class RefPtr>
112 : bool
113 52295 : nsRefPtrHashtable<KeyClass,RefPtr>::Get
114 : (KeyType aKey, UserDataType* pRefPtr) const
115 : {
116 52295 : typename base_type::EntryType* ent = this->GetEntry(aKey);
117 :
118 52295 : if (ent)
119 : {
120 2010 : if (pRefPtr)
121 : {
122 1419 : *pRefPtr = ent->mData;
123 :
124 1419 : NS_IF_ADDREF(*pRefPtr);
125 : }
126 :
127 2010 : return true;
128 : }
129 :
130 : // if the key doesn't exist, set *pRefPtr to null
131 : // so that it is a valid XPCOM getter
132 50285 : if (pRefPtr)
133 49930 : *pRefPtr = nsnull;
134 :
135 50285 : return false;
136 : }
137 :
138 : template<class KeyClass, class RefPtr>
139 : RefPtr*
140 1724 : nsRefPtrHashtable<KeyClass,RefPtr>::GetWeak
141 : (KeyType aKey, bool* aFound) const
142 : {
143 1724 : typename base_type::EntryType* ent = this->GetEntry(aKey);
144 :
145 1724 : if (ent)
146 : {
147 780 : if (aFound)
148 0 : *aFound = true;
149 :
150 780 : return ent->mData;
151 : }
152 :
153 : // Key does not exist, return nsnull and set aFound to false
154 944 : if (aFound)
155 0 : *aFound = false;
156 944 : return nsnull;
157 : }
158 :
159 : //
160 : // nsRefPtrHashtableMT definitions
161 : //
162 :
163 : template<class KeyClass, class RefPtr>
164 : bool
165 : nsRefPtrHashtableMT<KeyClass,RefPtr>::Get
166 : (KeyType aKey, UserDataType* pRefPtr) const
167 : {
168 : PR_Lock(this->mLock);
169 :
170 : typename base_type::EntryType* ent = this->GetEntry(aKey);
171 :
172 : if (ent)
173 : {
174 : if (pRefPtr)
175 : {
176 : *pRefPtr = ent->mData;
177 :
178 : NS_IF_ADDREF(*pRefPtr);
179 : }
180 :
181 : PR_Unlock(this->mLock);
182 :
183 : return true;
184 : }
185 :
186 : // if the key doesn't exist, set *pRefPtr to null
187 : // so that it is a valid XPCOM getter
188 : if (pRefPtr)
189 : *pRefPtr = nsnull;
190 :
191 : PR_Unlock(this->mLock);
192 :
193 : return false;
194 : }
195 :
196 : #endif // nsRefPtrHashtable_h__
|