]> git.saurik.com Git - apple/javascriptcore.git/blame - wtf/RefPtrHashMap.h
JavaScriptCore-521.tar.gz
[apple/javascriptcore.git] / wtf / RefPtrHashMap.h
CommitLineData
b37bf2e1 1/*
9dae56ea 2 * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
b37bf2e1
A
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public License
15 * along with this library; see the file COPYING.LIB. If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 *
19 */
20
21namespace WTF {
22
23 // This specialization is a direct copy of HashMap, with overloaded functions
24 // to allow for lookup by pointer instead of RefPtr, avoiding ref-count churn.
25
9dae56ea 26 // FIXME: Find a better way that doesn't require an entire copy of the HashMap template.
b37bf2e1 27
9dae56ea
A
28 template<typename RawKeyType, typename ValueType, typename ValueTraits, typename HashFunctions>
29 struct RefPtrHashMapRawKeyTranslator {
30 typedef typename ValueType::first_type KeyType;
31 typedef typename ValueType::second_type MappedType;
32 typedef typename ValueTraits::FirstTraits KeyTraits;
33 typedef typename ValueTraits::SecondTraits MappedTraits;
34
35 static unsigned hash(RawKeyType key) { return HashFunctions::hash(key); }
36 static bool equal(const KeyType& a, RawKeyType b) { return HashFunctions::equal(a, b); }
37 static void translate(ValueType& location, RawKeyType key, const MappedType& mapped)
38 {
39 location.first = key;
40 location.second = mapped;
41 }
42 };
43
b37bf2e1
A
44 template<typename T, typename MappedArg, typename HashArg, typename KeyTraitsArg, typename MappedTraitsArg>
45 class HashMap<RefPtr<T>, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg> {
46 private:
47 typedef KeyTraitsArg KeyTraits;
48 typedef MappedTraitsArg MappedTraits;
9dae56ea 49 typedef PairHashTraits<KeyTraits, MappedTraits> ValueTraits;
b37bf2e1
A
50
51 public:
52 typedef typename KeyTraits::TraitType KeyType;
53 typedef T* RawKeyType;
54 typedef typename MappedTraits::TraitType MappedType;
55 typedef typename ValueTraits::TraitType ValueType;
56
57 private:
58 typedef HashArg HashFunctions;
59
9dae56ea
A
60 typedef HashTable<KeyType, ValueType, PairFirstExtractor<ValueType>,
61 HashFunctions, ValueTraits, KeyTraits> HashTableType;
b37bf2e1 62
9dae56ea
A
63 typedef RefPtrHashMapRawKeyTranslator<RawKeyType, ValueType, ValueTraits, HashFunctions>
64 RawKeyTranslator;
b37bf2e1
A
65
66 public:
67 typedef HashTableIteratorAdapter<HashTableType, ValueType> iterator;
68 typedef HashTableConstIteratorAdapter<HashTableType, ValueType> const_iterator;
69
b37bf2e1
A
70 void swap(HashMap&);
71
72 int size() const;
73 int capacity() const;
74 bool isEmpty() const;
75
76 // iterators iterate over pairs of keys and values
77 iterator begin();
78 iterator end();
79 const_iterator begin() const;
80 const_iterator end() const;
81
82 iterator find(const KeyType&);
83 iterator find(RawKeyType);
84 const_iterator find(const KeyType&) const;
85 const_iterator find(RawKeyType) const;
86 bool contains(const KeyType&) const;
87 bool contains(RawKeyType) const;
88 MappedType get(const KeyType&) const;
89 MappedType get(RawKeyType) const;
9dae56ea 90 MappedType inlineGet(RawKeyType) const;
b37bf2e1
A
91
92 // replaces value but not key if key is already present
93 // return value is a pair of the iterator to the key location,
94 // and a boolean that's true if a new value was actually added
95 pair<iterator, bool> set(const KeyType&, const MappedType&);
96 pair<iterator, bool> set(RawKeyType, const MappedType&);
97
98 // does nothing if key is already present
99 // return value is a pair of the iterator to the key location,
100 // and a boolean that's true if a new value was actually added
101 pair<iterator, bool> add(const KeyType&, const MappedType&);
102 pair<iterator, bool> add(RawKeyType, const MappedType&);
103
104 void remove(const KeyType&);
105 void remove(RawKeyType);
106 void remove(iterator);
107 void clear();
108
109 MappedType take(const KeyType&); // efficient combination of get with remove
110 MappedType take(RawKeyType); // efficient combination of get with remove
111
112 private:
113 pair<iterator, bool> inlineAdd(const KeyType&, const MappedType&);
114 pair<iterator, bool> inlineAdd(RawKeyType, const MappedType&);
b37bf2e1
A
115
116 HashTableType m_impl;
117 };
118
b37bf2e1
A
119 template<typename T, typename U, typename V, typename W, typename X>
120 inline void HashMap<RefPtr<T>, U, V, W, X>::swap(HashMap& other)
121 {
122 m_impl.swap(other.m_impl);
123 }
124
b37bf2e1
A
125 template<typename T, typename U, typename V, typename W, typename X>
126 inline int HashMap<RefPtr<T>, U, V, W, X>::size() const
127 {
128 return m_impl.size();
129 }
130
131 template<typename T, typename U, typename V, typename W, typename X>
132 inline int HashMap<RefPtr<T>, U, V, W, X>::capacity() const
133 {
134 return m_impl.capacity();
135 }
136
137 template<typename T, typename U, typename V, typename W, typename X>
138 inline bool HashMap<RefPtr<T>, U, V, W, X>::isEmpty() const
139 {
140 return m_impl.isEmpty();
141 }
142
143 template<typename T, typename U, typename V, typename W, typename X>
144 inline typename HashMap<RefPtr<T>, U, V, W, X>::iterator HashMap<RefPtr<T>, U, V, W, X>::begin()
145 {
146 return m_impl.begin();
147 }
148
149 template<typename T, typename U, typename V, typename W, typename X>
150 inline typename HashMap<RefPtr<T>, U, V, W, X>::iterator HashMap<RefPtr<T>, U, V, W, X>::end()
151 {
152 return m_impl.end();
153 }
154
155 template<typename T, typename U, typename V, typename W, typename X>
156 inline typename HashMap<RefPtr<T>, U, V, W, X>::const_iterator HashMap<RefPtr<T>, U, V, W, X>::begin() const
157 {
158 return m_impl.begin();
159 }
160
161 template<typename T, typename U, typename V, typename W, typename X>
162 inline typename HashMap<RefPtr<T>, U, V, W, X>::const_iterator HashMap<RefPtr<T>, U, V, W, X>::end() const
163 {
164 return m_impl.end();
165 }
166
167 template<typename T, typename U, typename V, typename W, typename X>
168 inline typename HashMap<RefPtr<T>, U, V, W, X>::iterator HashMap<RefPtr<T>, U, V, W, X>::find(const KeyType& key)
169 {
9dae56ea 170 return m_impl.find(key);
b37bf2e1
A
171 }
172
173 template<typename T, typename U, typename V, typename W, typename X>
174 inline typename HashMap<RefPtr<T>, U, V, W, X>::iterator HashMap<RefPtr<T>, U, V, W, X>::find(RawKeyType key)
175 {
9dae56ea 176 return m_impl.template find<RawKeyType, RawKeyTranslator>(key);
b37bf2e1
A
177 }
178
179 template<typename T, typename U, typename V, typename W, typename X>
180 inline typename HashMap<RefPtr<T>, U, V, W, X>::const_iterator HashMap<RefPtr<T>, U, V, W, X>::find(const KeyType& key) const
181 {
9dae56ea 182 return m_impl.find(key);
b37bf2e1
A
183 }
184
185 template<typename T, typename U, typename V, typename W, typename X>
186 inline typename HashMap<RefPtr<T>, U, V, W, X>::const_iterator HashMap<RefPtr<T>, U, V, W, X>::find(RawKeyType key) const
187 {
9dae56ea 188 return m_impl.template find<RawKeyType, RawKeyTranslator>(key);
b37bf2e1
A
189 }
190
191 template<typename T, typename U, typename V, typename W, typename X>
192 inline bool HashMap<RefPtr<T>, U, V, W, X>::contains(const KeyType& key) const
193 {
9dae56ea 194 return m_impl.contains(key);
b37bf2e1
A
195 }
196
197 template<typename T, typename U, typename V, typename W, typename X>
198 inline bool HashMap<RefPtr<T>, U, V, W, X>::contains(RawKeyType key) const
199 {
9dae56ea 200 return m_impl.template contains<RawKeyType, RawKeyTranslator>(key);
b37bf2e1
A
201 }
202
203 template<typename T, typename U, typename V, typename W, typename X>
204 inline pair<typename HashMap<RefPtr<T>, U, V, W, X>::iterator, bool>
205 HashMap<RefPtr<T>, U, V, W, X>::inlineAdd(const KeyType& key, const MappedType& mapped)
206 {
9dae56ea 207 typedef HashMapTranslator<ValueType, ValueTraits, HashFunctions> TranslatorType;
b37bf2e1
A
208 return m_impl.template add<KeyType, MappedType, TranslatorType>(key, mapped);
209 }
210
211 template<typename T, typename U, typename V, typename W, typename X>
212 inline pair<typename HashMap<RefPtr<T>, U, V, W, X>::iterator, bool>
213 HashMap<RefPtr<T>, U, V, W, X>::inlineAdd(RawKeyType key, const MappedType& mapped)
214 {
9dae56ea 215 return m_impl.template add<RawKeyType, MappedType, RawKeyTranslator>(key, mapped);
b37bf2e1
A
216 }
217
218 template<typename T, typename U, typename V, typename W, typename X>
219 pair<typename HashMap<RefPtr<T>, U, V, W, X>::iterator, bool>
220 HashMap<RefPtr<T>, U, V, W, X>::set(const KeyType& key, const MappedType& mapped)
221 {
222 pair<iterator, bool> result = inlineAdd(key, mapped);
9dae56ea 223 if (!result.second) {
b37bf2e1
A
224 // add call above didn't change anything, so set the mapped value
225 result.first->second = mapped;
9dae56ea 226 }
b37bf2e1
A
227 return result;
228 }
229
230 template<typename T, typename U, typename V, typename W, typename X>
231 pair<typename HashMap<RefPtr<T>, U, V, W, X>::iterator, bool>
232 HashMap<RefPtr<T>, U, V, W, X>::set(RawKeyType key, const MappedType& mapped)
233 {
234 pair<iterator, bool> result = inlineAdd(key, mapped);
9dae56ea 235 if (!result.second) {
b37bf2e1
A
236 // add call above didn't change anything, so set the mapped value
237 result.first->second = mapped;
9dae56ea 238 }
b37bf2e1
A
239 return result;
240 }
241
242 template<typename T, typename U, typename V, typename W, typename X>
243 pair<typename HashMap<RefPtr<T>, U, V, W, X>::iterator, bool>
244 HashMap<RefPtr<T>, U, V, W, X>::add(const KeyType& key, const MappedType& mapped)
245 {
246 return inlineAdd(key, mapped);
247 }
248
249 template<typename T, typename U, typename V, typename W, typename X>
250 pair<typename HashMap<RefPtr<T>, U, V, W, X>::iterator, bool>
251 HashMap<RefPtr<T>, U, V, W, X>::add(RawKeyType key, const MappedType& mapped)
252 {
253 return inlineAdd(key, mapped);
254 }
255
256 template<typename T, typename U, typename V, typename W, typename MappedTraits>
257 typename HashMap<RefPtr<T>, U, V, W, MappedTraits>::MappedType
258 HashMap<RefPtr<T>, U, V, W, MappedTraits>::get(const KeyType& key) const
259 {
9dae56ea 260 ValueType* entry = const_cast<HashTableType&>(m_impl).lookup(key);
b37bf2e1
A
261 if (!entry)
262 return MappedTraits::emptyValue();
9dae56ea 263 return entry->second;
b37bf2e1
A
264 }
265
266 template<typename T, typename U, typename V, typename W, typename MappedTraits>
267 typename HashMap<RefPtr<T>, U, V, W, MappedTraits>::MappedType
9dae56ea 268 inline HashMap<RefPtr<T>, U, V, W, MappedTraits>::inlineGet(RawKeyType key) const
b37bf2e1 269 {
9dae56ea 270 ValueType* entry = const_cast<HashTableType&>(m_impl).template lookup<RawKeyType, RawKeyTranslator>(key);
b37bf2e1
A
271 if (!entry)
272 return MappedTraits::emptyValue();
9dae56ea
A
273 return entry->second;
274 }
275
276 template<typename T, typename U, typename V, typename W, typename MappedTraits>
277 typename HashMap<RefPtr<T>, U, V, W, MappedTraits>::MappedType
278 HashMap<RefPtr<T>, U, V, W, MappedTraits>::get(RawKeyType key) const
279 {
280 return inlineGet(key);
b37bf2e1
A
281 }
282
283 template<typename T, typename U, typename V, typename W, typename X>
284 inline void HashMap<RefPtr<T>, U, V, W, X>::remove(iterator it)
285 {
286 if (it.m_impl == m_impl.end())
287 return;
288 m_impl.checkTableConsistency();
b37bf2e1
A
289 m_impl.removeWithoutEntryConsistencyCheck(it.m_impl);
290 }
291
292 template<typename T, typename U, typename V, typename W, typename X>
293 inline void HashMap<RefPtr<T>, U, V, W, X>::remove(const KeyType& key)
294 {
295 remove(find(key));
296 }
297
298 template<typename T, typename U, typename V, typename W, typename X>
299 inline void HashMap<RefPtr<T>, U, V, W, X>::remove(RawKeyType key)
300 {
301 remove(find(key));
302 }
303
304 template<typename T, typename U, typename V, typename W, typename X>
305 inline void HashMap<RefPtr<T>, U, V, W, X>::clear()
306 {
b37bf2e1
A
307 m_impl.clear();
308 }
309
310 template<typename T, typename U, typename V, typename W, typename MappedTraits>
311 typename HashMap<RefPtr<T>, U, V, W, MappedTraits>::MappedType
312 HashMap<RefPtr<T>, U, V, W, MappedTraits>::take(const KeyType& key)
313 {
314 // This can probably be made more efficient to avoid ref/deref churn.
315 iterator it = find(key);
316 if (it == end())
317 return MappedTraits::emptyValue();
318 typename HashMap<RefPtr<T>, U, V, W, MappedTraits>::MappedType result = it->second;
319 remove(it);
320 return result;
321 }
322
323 template<typename T, typename U, typename V, typename W, typename MappedTraits>
324 typename HashMap<RefPtr<T>, U, V, W, MappedTraits>::MappedType
325 HashMap<RefPtr<T>, U, V, W, MappedTraits>::take(RawKeyType key)
326 {
327 // This can probably be made more efficient to avoid ref/deref churn.
328 iterator it = find(key);
329 if (it == end())
330 return MappedTraits::emptyValue();
331 typename HashMap<RefPtr<T>, U, V, W, MappedTraits>::MappedType result = it->second;
332 remove(it);
333 return result;
334 }
335
336} // namespace WTF