source: webkit/trunk/JavaScriptCore/wtf/HashMap.h@ 31730

Last change on this file since 31730 was 28777, checked in by [email protected], 17 years ago

Reviewed by Darin Adler and Maciej Stachowiak.


More refactoring to support global variable optimization.


Changed SymbolTable to use RefPtr<UString::Rep> as its key instead of
UString::Rep*. With globals, the symbol table can outlast the
declaration node for any given symbol, so the symbol table needs to ref
its symbol names.


In support, specialized HashMaps with RefPtr keys to allow lookup
via raw pointer, avoiding refcount churn.


SunSpider reports a .6% speedup (prolly just noise).

  • kjs/JSVariableObject.cpp: (KJS::JSVariableObject::getPropertyNames): Symbol table keys are RefPtrs now.
  • kjs/SymbolTable.h: Modified key traits to match RefPtr. Added a static Rep* for null, which helps compute the deletedValue() trait.
  • wtf/HashMap.h: #include the RefPtr specialization so everyone can use it.
  • wtf/RefPtrHashMap.h: Copied from wtf/HashMap.h. Added overloaded versions of find(), contains(), get(), set(), add(), remove(), and take() that take raw pointers as keys.
  • Property svn:eol-style set to native
File size: 16.6 KB
Line 
1// -*- mode: c++; c-basic-offset: 4 -*-
2/*
3 * Copyright (C) 2005, 2006, 2007 Apple Inc. All rights reserved.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 *
20 */
21
22#ifndef WTF_HashMap_h
23#define WTF_HashMap_h
24
25#include "HashTable.h"
26
27namespace WTF {
28
29 template<typename PairType> struct PairFirstExtractor;
30
31 template<typename KeyArg, typename MappedArg, typename HashArg = typename DefaultHash<KeyArg>::Hash,
32 typename KeyTraitsArg = HashTraits<KeyArg>, typename MappedTraitsArg = HashTraits<MappedArg> >
33 class HashMap {
34 private:
35 typedef KeyTraitsArg KeyTraits;
36 typedef MappedTraitsArg MappedTraits;
37 typedef PairBaseHashTraits<KeyTraits, MappedTraits> ValueTraits;
38
39 public:
40 typedef typename KeyTraits::TraitType KeyType;
41 typedef typename MappedTraits::TraitType MappedType;
42 typedef typename ValueTraits::TraitType ValueType;
43
44 private:
45 typedef HashArg HashFunctions;
46
47 typedef typename HashKeyStorageTraits<HashFunctions, KeyTraits>::Hash StorageHashFunctions;
48
49 typedef typename HashKeyStorageTraits<HashFunctions, KeyTraits>::Traits KeyStorageTraits;
50 typedef typename MappedTraits::StorageTraits MappedStorageTraits;
51 typedef PairHashTraits<KeyStorageTraits, MappedStorageTraits> ValueStorageTraits;
52
53 typedef typename KeyStorageTraits::TraitType KeyStorageType;
54 typedef typename MappedStorageTraits::TraitType MappedStorageType;
55 typedef typename ValueStorageTraits::TraitType ValueStorageType;
56
57 typedef HashTable<KeyStorageType, ValueStorageType, PairFirstExtractor<ValueStorageType>,
58 StorageHashFunctions, ValueStorageTraits, KeyStorageTraits> HashTableType;
59
60 public:
61 typedef HashTableIteratorAdapter<HashTableType, ValueType> iterator;
62 typedef HashTableConstIteratorAdapter<HashTableType, ValueType> const_iterator;
63
64 HashMap();
65 HashMap(const HashMap&);
66 HashMap& operator=(const HashMap&);
67 ~HashMap();
68
69 void swap(HashMap&);
70
71 int size() const;
72 int capacity() const;
73 bool isEmpty() const;
74
75 // iterators iterate over pairs of keys and values
76 iterator begin();
77 iterator end();
78 const_iterator begin() const;
79 const_iterator end() const;
80
81 iterator find(const KeyType&);
82 const_iterator find(const KeyType&) const;
83 bool contains(const KeyType&) const;
84 MappedType get(const KeyType&) const;
85
86 // replaces value but not key if key is already present
87 // return value is a pair of the iterator to the key location,
88 // and a boolean that's true if a new value was actually added
89 pair<iterator, bool> set(const KeyType&, const MappedType&);
90
91 // does nothing if key is already present
92 // return value is a pair of the iterator to the key location,
93 // and a boolean that's true if a new value was actually added
94 pair<iterator, bool> add(const KeyType&, const MappedType&);
95
96 void remove(const KeyType&);
97 void remove(iterator);
98 void clear();
99
100 MappedType take(const KeyType&); // efficient combination of get with remove
101
102 private:
103 pair<iterator, bool> inlineAdd(const KeyType&, const MappedType&);
104 void refAll();
105 void derefAll();
106
107 HashTableType m_impl;
108 };
109
110 template<typename PairType> struct PairFirstExtractor {
111 static const typename PairType::first_type& extract(const PairType& p) { return p.first; }
112 };
113
114 template<bool canReplaceDeletedKey, typename ValueType, typename ValueTraits, typename ValueStorageTraits, typename HashFunctions>
115 struct HashMapTranslator;
116
117 template<typename ValueType, typename ValueTraits, typename ValueStorageTraits, typename HashFunctions>
118 struct HashMapTranslator<true, ValueType, ValueTraits, ValueStorageTraits, HashFunctions> {
119 typedef typename ValueType::first_type KeyType;
120 typedef typename ValueType::second_type MappedType;
121 typedef typename ValueStorageTraits::TraitType ValueStorageType;
122 typedef typename ValueStorageTraits::FirstTraits KeyStorageTraits;
123 typedef typename KeyStorageTraits::TraitType KeyStorageType;
124 typedef typename ValueStorageTraits::SecondTraits MappedStorageTraits;
125 typedef typename MappedStorageTraits::TraitType MappedStorageType;
126 typedef typename ValueTraits::FirstTraits KeyTraits;
127 typedef typename ValueTraits::SecondTraits MappedTraits;
128
129 static unsigned hash(const KeyType& key) { return HashFunctions::hash(key); }
130 static bool equal(const KeyStorageType& a, const KeyType& b) { return HashFunctions::equal(*(KeyType*)&a, b); }
131 static void translate(ValueStorageType& location, const KeyType& key, const MappedType& mapped)
132 {
133 Assigner<KeyTraits::needsRef, KeyType, KeyStorageType, KeyTraits>::assign(key, location.first);
134 Assigner<MappedTraits::needsRef, MappedType, MappedStorageType, MappedTraits>::assign(mapped, location.second);
135 }
136 };
137
138 template<typename ValueType, typename ValueTraits, typename ValueStorageTraits, typename HashFunctions>
139 struct HashMapTranslator<false, ValueType, ValueTraits, ValueStorageTraits, HashFunctions> {
140 typedef typename ValueType::first_type KeyType;
141 typedef typename ValueType::second_type MappedType;
142 typedef typename ValueStorageTraits::TraitType ValueStorageType;
143 typedef typename ValueStorageTraits::FirstTraits KeyStorageTraits;
144 typedef typename KeyStorageTraits::TraitType KeyStorageType;
145 typedef typename ValueStorageTraits::SecondTraits MappedStorageTraits;
146 typedef typename MappedStorageTraits::TraitType MappedStorageType;
147 typedef typename ValueTraits::FirstTraits KeyTraits;
148 typedef typename ValueTraits::SecondTraits MappedTraits;
149
150 static unsigned hash(const KeyType& key) { return HashFunctions::hash(key); }
151 static bool equal(const KeyStorageType& a, const KeyType& b) { return HashFunctions::equal(*(KeyType*)&a, b); }
152 static void translate(ValueStorageType& location, const KeyType& key, const MappedType& mapped)
153 {
154 if (location.first == KeyStorageTraits::deletedValue())
155 location.first = KeyStorageTraits::emptyValue();
156 Assigner<KeyTraits::needsRef, KeyType, KeyStorageType, KeyTraits>::assign(key, location.first);
157 Assigner<MappedTraits::needsRef, MappedType, MappedStorageType, MappedTraits>::assign(mapped, location.second);
158 }
159 };
160
161 template<typename T, typename U, typename V, typename W, typename X>
162 inline void HashMap<T, U, V, W, X>::refAll()
163 {
164 HashTableRefCounter<HashTableType, ValueTraits>::refAll(m_impl);
165 }
166
167 template<typename T, typename U, typename V, typename W, typename X>
168 inline void HashMap<T, U, V, W, X>::derefAll()
169 {
170 HashTableRefCounter<HashTableType, ValueTraits>::derefAll(m_impl);
171 }
172
173 template<typename T, typename U, typename V, typename W, typename X>
174 inline HashMap<T, U, V, W, X>::HashMap()
175 {
176 }
177
178 template<typename T, typename U, typename V, typename W, typename X>
179 inline HashMap<T, U, V, W, X>::HashMap(const HashMap& other)
180 : m_impl(other.m_impl)
181 {
182 refAll();
183 }
184
185 template<typename T, typename U, typename V, typename W, typename X>
186 inline HashMap<T, U, V, W, X>& HashMap<T, U, V, W, X>::operator=(const HashMap& other)
187 {
188 HashMap tmp(other);
189 swap(tmp);
190 return *this;
191 }
192
193 template<typename T, typename U, typename V, typename W, typename X>
194 inline void HashMap<T, U, V, W, X>::swap(HashMap& other)
195 {
196 m_impl.swap(other.m_impl);
197 }
198
199 template<typename T, typename U, typename V, typename W, typename X>
200 inline HashMap<T, U, V, W, X>::~HashMap()
201 {
202 derefAll();
203 }
204
205 template<typename T, typename U, typename V, typename W, typename X>
206 inline int HashMap<T, U, V, W, X>::size() const
207 {
208 return m_impl.size();
209 }
210
211 template<typename T, typename U, typename V, typename W, typename X>
212 inline int HashMap<T, U, V, W, X>::capacity() const
213 {
214 return m_impl.capacity();
215 }
216
217 template<typename T, typename U, typename V, typename W, typename X>
218 inline bool HashMap<T, U, V, W, X>::isEmpty() const
219 {
220 return m_impl.isEmpty();
221 }
222
223 template<typename T, typename U, typename V, typename W, typename X>
224 inline typename HashMap<T, U, V, W, X>::iterator HashMap<T, U, V, W, X>::begin()
225 {
226 return m_impl.begin();
227 }
228
229 template<typename T, typename U, typename V, typename W, typename X>
230 inline typename HashMap<T, U, V, W, X>::iterator HashMap<T, U, V, W, X>::end()
231 {
232 return m_impl.end();
233 }
234
235 template<typename T, typename U, typename V, typename W, typename X>
236 inline typename HashMap<T, U, V, W, X>::const_iterator HashMap<T, U, V, W, X>::begin() const
237 {
238 return m_impl.begin();
239 }
240
241 template<typename T, typename U, typename V, typename W, typename X>
242 inline typename HashMap<T, U, V, W, X>::const_iterator HashMap<T, U, V, W, X>::end() const
243 {
244 return m_impl.end();
245 }
246
247 template<typename T, typename U, typename V, typename W, typename X>
248 inline typename HashMap<T, U, V, W, X>::iterator HashMap<T, U, V, W, X>::find(const KeyType& key)
249 {
250 return m_impl.find(*(const KeyStorageType*)&key);
251 }
252
253 template<typename T, typename U, typename V, typename W, typename X>
254 inline typename HashMap<T, U, V, W, X>::const_iterator HashMap<T, U, V, W, X>::find(const KeyType& key) const
255 {
256 return m_impl.find(*(const KeyStorageType*)&key);
257 }
258
259 template<typename T, typename U, typename V, typename W, typename X>
260 inline bool HashMap<T, U, V, W, X>::contains(const KeyType& key) const
261 {
262 return m_impl.contains(*(const KeyStorageType*)&key);
263 }
264
265 template<typename T, typename U, typename V, typename W, typename X>
266 inline pair<typename HashMap<T, U, V, W, X>::iterator, bool>
267 HashMap<T, U, V, W, X>::inlineAdd(const KeyType& key, const MappedType& mapped)
268 {
269 const bool canReplaceDeletedKey = !KeyTraits::needsDestruction || KeyStorageTraits::needsDestruction;
270 typedef HashMapTranslator<canReplaceDeletedKey, ValueType, ValueTraits, ValueStorageTraits, HashFunctions> TranslatorType;
271 return m_impl.template add<KeyType, MappedType, TranslatorType>(key, mapped);
272 }
273
274 template<typename T, typename U, typename V, typename W, typename X>
275 pair<typename HashMap<T, U, V, W, X>::iterator, bool>
276 HashMap<T, U, V, W, X>::set(const KeyType& key, const MappedType& mapped)
277 {
278 pair<iterator, bool> result = inlineAdd(key, mapped);
279 if (!result.second)
280 // add call above didn't change anything, so set the mapped value
281 result.first->second = mapped;
282 return result;
283 }
284
285 template<typename T, typename U, typename V, typename W, typename X>
286 pair<typename HashMap<T, U, V, W, X>::iterator, bool>
287 HashMap<T, U, V, W, X>::add(const KeyType& key, const MappedType& mapped)
288 {
289 return inlineAdd(key, mapped);
290 }
291
292 template<typename T, typename U, typename V, typename W, typename MappedTraits>
293 typename HashMap<T, U, V, W, MappedTraits>::MappedType
294 HashMap<T, U, V, W, MappedTraits>::get(const KeyType& key) const
295 {
296 if (m_impl.isEmpty())
297 return MappedTraits::emptyValue();
298 ValueStorageType* entry = const_cast<HashTableType&>(m_impl).lookup(*(const KeyStorageType*)&key);
299 if (!entry)
300 return MappedTraits::emptyValue();
301 return ((ValueType *)entry)->second;
302 }
303
304 template<typename T, typename U, typename V, typename W, typename X>
305 inline void HashMap<T, U, V, W, X>::remove(iterator it)
306 {
307 if (it.m_impl == m_impl.end())
308 return;
309 m_impl.checkTableConsistency();
310 RefCounter<ValueTraits, ValueStorageTraits>::deref(*it.m_impl);
311 m_impl.removeWithoutEntryConsistencyCheck(it.m_impl);
312 }
313
314 template<typename T, typename U, typename V, typename W, typename X>
315 inline void HashMap<T, U, V, W, X>::remove(const KeyType& key)
316 {
317 remove(find(key));
318 }
319
320 template<typename T, typename U, typename V, typename W, typename X>
321 inline void HashMap<T, U, V, W, X>::clear()
322 {
323 derefAll();
324 m_impl.clear();
325 }
326
327 template<typename T, typename U, typename V, typename W, typename MappedTraits>
328 typename HashMap<T, U, V, W, MappedTraits>::MappedType
329 HashMap<T, U, V, W, MappedTraits>::take(const KeyType& key)
330 {
331 // This can probably be made more efficient to avoid ref/deref churn.
332 iterator it = find(key);
333 if (it == end())
334 return MappedTraits::emptyValue();
335 typename HashMap<T, U, V, W, MappedTraits>::MappedType result = it->second;
336 remove(it);
337 return result;
338 }
339
340 template<typename T, typename U, typename V, typename W, typename X>
341 bool operator==(const HashMap<T, U, V, W, X>& a, const HashMap<T, U, V, W, X>& b)
342 {
343 if (a.size() != b.size())
344 return false;
345
346 typedef typename HashMap<T, U, V, W, X>::const_iterator const_iterator;
347
348 const_iterator end = a.end();
349 const_iterator notFound = b.end();
350 for (const_iterator it = a.begin(); it != end; ++it) {
351 const_iterator bPos = b.find(it->first);
352 if (bPos == notFound || it->second != bPos->second)
353 return false;
354 }
355
356 return true;
357 }
358
359 template<typename T, typename U, typename V, typename W, typename X>
360 inline bool operator!=(const HashMap<T, U, V, W, X>& a, const HashMap<T, U, V, W, X>& b)
361 {
362 return !(a == b);
363 }
364
365 template<typename MappedType, typename HashTableType>
366 void deleteAllPairSeconds(HashTableType& collection)
367 {
368 typedef typename HashTableType::const_iterator iterator;
369 iterator end = collection.end();
370 for (iterator it = collection.begin(); it != end; ++it)
371 delete *(MappedType*)&it->second;
372 }
373
374 template<typename T, typename U, typename V, typename W, typename X>
375 inline void deleteAllValues(const HashMap<T, U, V, W, X>& collection)
376 {
377 deleteAllPairSeconds<typename HashMap<T, U, V, W, X>::MappedType>(collection);
378 }
379
380 template<typename KeyType, typename HashTableType>
381 void deleteAllPairFirsts(HashTableType& collection)
382 {
383 typedef typename HashTableType::const_iterator iterator;
384 iterator end = collection.end();
385 for (iterator it = collection.begin(); it != end; ++it)
386 delete *(KeyType*)&it->first;
387 }
388
389 template<typename T, typename U, typename V, typename W, typename X>
390 inline void deleteAllKeys(const HashMap<T, U, V, W, X>& collection)
391 {
392 deleteAllPairFirsts<typename HashMap<T, U, V, W, X>::KeyType>(collection);
393 }
394
395 template<typename T, typename U, typename V, typename W, typename X, typename Y>
396 inline void copyKeysToVector(const HashMap<T, U, V, W, X>& collection, Y& vector)
397 {
398 typedef typename HashMap<T, U, V, W, X>::const_iterator::Keys iterator;
399
400 vector.resize(collection.size());
401
402 iterator it = collection.begin().keys();
403 iterator end = collection.end().keys();
404 for (unsigned i = 0; it != end; ++it, ++i)
405 vector[i] = *it;
406 }
407
408 template<typename T, typename U, typename V, typename W, typename X, typename Y>
409 inline void copyValuesToVector(const HashMap<T, U, V, W, X>& collection, Y& vector)
410 {
411 typedef typename HashMap<T, U, V, W, X>::const_iterator::Values iterator;
412
413 vector.resize(collection.size());
414
415 iterator it = collection.begin().values();
416 iterator end = collection.end().values();
417 for (unsigned i = 0; it != end; ++it, ++i)
418 vector[i] = *it;
419 }
420
421} // namespace WTF
422
423using WTF::HashMap;
424
425#include "RefPtrHashMap.h"
426
427#endif /* WTF_HashMap_h */
Note: See TracBrowser for help on using the repository browser.