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

Last change on this file since 27402 was 27385, checked in by Darin Adler, 18 years ago

JavaScriptCore:

Reviewed by Maciej.

  • wtf/HashMap.h: Added take function. Simplistic implementation for now, but still does only one hash table lookup.
  • kjs/array_instance.cpp: (KJS::ArrayInstance::put): Use take rather than a find followed by a remove.

WebCore:

Reviewed by Maciej.

  • use the new HashMap::take function where appropriate
  • bindings/js/kjs_binding.cpp: (KJS::addWrapper): Made an inline rather than a macro; inlines good, macros bad. (KJS::removeWrapper): Ditto. (KJS::removeWrappers): Ditto. (KJS::ScriptInterpreter::putDOMObject): Use the inline instead of the macro. (KJS::ScriptInterpreter::forgetDOMObject): Ditto. This involves using take instead of remove -- in theory ever so slightly less efficient, but I think it's fine. (KJS::ScriptInterpreter::forgetDOMNodeForDocument): Ditto. (KJS::ScriptInterpreter::putDOMNodeForDocument): Use the inline instead of the macro. (KJS::ScriptInterpreter::forgetAllDOMNodesForDocument): Use take instead of find/remove. (KJS::ScriptInterpreter::updateDOMNodeDocument): Use the inlines instead of the macros.
  • bindings/js/kjs_window.cpp: (KJS::Window::clearTimeout): Use take instead of find/remove.
  • bridge/mac/AXObjectCacheMac.mm: (WebCore::AXObjectCache::remove): Ditto.
  • page/AnimationController.cpp: (WebCore::AnimationControllerPrivate::clear): Ditto.
  • rendering/RenderBlock.cpp: (WebCore::RenderBlock::~RenderBlock): Ditto. (WebCore::RenderBlock::setDesiredColumnCountAndWidth): Ditto.
  • rendering/RootInlineBox.cpp: Ditto.(WebCore::RootInlineBox::detachEllipsisBox): Ditto.
  • Property svn:eol-style set to native
File size: 16.0 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#include "Vector.h"
27
28namespace WTF {
29
30 template<typename PairType> struct PairFirstExtractor;
31
32 template<typename KeyArg, typename MappedArg, typename HashArg = typename DefaultHash<KeyArg>::Hash,
33 typename KeyTraitsArg = HashTraits<KeyArg>, typename MappedTraitsArg = HashTraits<MappedArg> >
34 class HashMap {
35 private:
36 typedef KeyTraitsArg KeyTraits;
37 typedef MappedTraitsArg MappedTraits;
38 typedef PairBaseHashTraits<KeyTraits, MappedTraits> ValueTraits;
39
40 public:
41 typedef typename KeyTraits::TraitType KeyType;
42 typedef typename MappedTraits::TraitType MappedType;
43 typedef typename ValueTraits::TraitType ValueType;
44
45 private:
46 typedef HashArg HashFunctions;
47
48 typedef typename HashKeyStorageTraits<HashFunctions, KeyTraits>::Hash StorageHashFunctions;
49
50 typedef typename HashKeyStorageTraits<HashFunctions, KeyTraits>::Traits KeyStorageTraits;
51 typedef typename MappedTraits::StorageTraits MappedStorageTraits;
52 typedef PairHashTraits<KeyStorageTraits, MappedStorageTraits> ValueStorageTraits;
53
54 typedef typename KeyStorageTraits::TraitType KeyStorageType;
55 typedef typename MappedStorageTraits::TraitType MappedStorageType;
56 typedef typename ValueStorageTraits::TraitType ValueStorageType;
57
58 typedef HashTable<KeyStorageType, ValueStorageType, PairFirstExtractor<ValueStorageType>,
59 StorageHashFunctions, ValueStorageTraits, KeyStorageTraits> HashTableType;
60
61 public:
62 typedef HashTableIteratorAdapter<HashTableType, ValueType> iterator;
63 typedef HashTableConstIteratorAdapter<HashTableType, ValueType> const_iterator;
64
65 HashMap();
66 HashMap(const HashMap&);
67 HashMap& operator=(const HashMap&);
68 ~HashMap();
69
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 const_iterator find(const KeyType&) const;
84 bool contains(const KeyType&) const;
85 MappedType get(const KeyType&) const;
86
87 // replaces value but not key if key is already present
88 // return value is a pair of the iterator to the key location,
89 // and a boolean that's true if a new value was actually added
90 pair<iterator, bool> set(const KeyType&, const MappedType&);
91
92 // does nothing 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> add(const KeyType&, const MappedType&);
96
97 void remove(const KeyType&);
98 void remove(iterator);
99 void clear();
100
101 MappedType take(const KeyType&); // efficient combination of get with remove
102
103 private:
104 pair<iterator, bool> inlineAdd(const KeyType&, const MappedType&);
105 void refAll();
106 void derefAll();
107
108 HashTableType m_impl;
109 };
110
111 template<typename PairType> struct PairFirstExtractor {
112 static const typename PairType::first_type& extract(const PairType& p) { return p.first; }
113 };
114
115 template<bool canReplaceDeletedKey, typename ValueType, typename ValueTraits, typename ValueStorageTraits, typename HashFunctions>
116 struct HashMapTranslator;
117
118 template<typename ValueType, typename ValueTraits, typename ValueStorageTraits, typename HashFunctions>
119 struct HashMapTranslator<true, ValueType, ValueTraits, ValueStorageTraits, HashFunctions> {
120 typedef typename ValueType::first_type KeyType;
121 typedef typename ValueType::second_type MappedType;
122 typedef typename ValueStorageTraits::TraitType ValueStorageType;
123 typedef typename ValueStorageTraits::FirstTraits KeyStorageTraits;
124 typedef typename KeyStorageTraits::TraitType KeyStorageType;
125 typedef typename ValueStorageTraits::SecondTraits MappedStorageTraits;
126 typedef typename MappedStorageTraits::TraitType MappedStorageType;
127 typedef typename ValueTraits::FirstTraits KeyTraits;
128 typedef typename ValueTraits::SecondTraits MappedTraits;
129
130 static unsigned hash(const KeyType& key) { return HashFunctions::hash(key); }
131 static bool equal(const KeyStorageType& a, const KeyType& b) { return HashFunctions::equal(*(KeyType*)&a, b); }
132 static void translate(ValueStorageType& location, const KeyType& key, const MappedType& mapped)
133 {
134 Assigner<KeyTraits::needsRef, KeyType, KeyStorageType, KeyTraits>::assign(key, location.first);
135 Assigner<MappedTraits::needsRef, MappedType, MappedStorageType, MappedTraits>::assign(mapped, location.second);
136 }
137 };
138
139 template<typename ValueType, typename ValueTraits, typename ValueStorageTraits, typename HashFunctions>
140 struct HashMapTranslator<false, ValueType, ValueTraits, ValueStorageTraits, HashFunctions> {
141 typedef typename ValueType::first_type KeyType;
142 typedef typename ValueType::second_type MappedType;
143 typedef typename ValueStorageTraits::TraitType ValueStorageType;
144 typedef typename ValueStorageTraits::FirstTraits KeyStorageTraits;
145 typedef typename KeyStorageTraits::TraitType KeyStorageType;
146 typedef typename ValueStorageTraits::SecondTraits MappedStorageTraits;
147 typedef typename MappedStorageTraits::TraitType MappedStorageType;
148 typedef typename ValueTraits::FirstTraits KeyTraits;
149 typedef typename ValueTraits::SecondTraits MappedTraits;
150
151 static unsigned hash(const KeyType& key) { return HashFunctions::hash(key); }
152 static bool equal(const KeyStorageType& a, const KeyType& b) { return HashFunctions::equal(*(KeyType*)&a, b); }
153 static void translate(ValueStorageType& location, const KeyType& key, const MappedType& mapped)
154 {
155 if (location.first == KeyStorageTraits::deletedValue())
156 location.first = KeyStorageTraits::emptyValue();
157 Assigner<KeyTraits::needsRef, KeyType, KeyStorageType, KeyTraits>::assign(key, location.first);
158 Assigner<MappedTraits::needsRef, MappedType, MappedStorageType, MappedTraits>::assign(mapped, location.second);
159 }
160 };
161
162 template<typename T, typename U, typename V, typename W, typename X>
163 inline void HashMap<T, U, V, W, X>::refAll()
164 {
165 HashTableRefCounter<HashTableType, ValueTraits>::refAll(m_impl);
166 }
167
168 template<typename T, typename U, typename V, typename W, typename X>
169 inline void HashMap<T, U, V, W, X>::derefAll()
170 {
171 HashTableRefCounter<HashTableType, ValueTraits>::derefAll(m_impl);
172 }
173
174 template<typename T, typename U, typename V, typename W, typename X>
175 inline HashMap<T, U, V, W, X>::HashMap()
176 {
177 }
178
179 template<typename T, typename U, typename V, typename W, typename X>
180 inline HashMap<T, U, V, W, X>::HashMap(const HashMap& other)
181 : m_impl(other.m_impl)
182 {
183 refAll();
184 }
185
186 template<typename T, typename U, typename V, typename W, typename X>
187 inline HashMap<T, U, V, W, X>& HashMap<T, U, V, W, X>::operator=(const HashMap& other)
188 {
189 HashMap tmp(other);
190 swap(tmp);
191 return *this;
192 }
193
194 template<typename T, typename U, typename V, typename W, typename X>
195 inline void HashMap<T, U, V, W, X>::swap(HashMap& other)
196 {
197 m_impl.swap(other.m_impl);
198 }
199
200 template<typename T, typename U, typename V, typename W, typename X>
201 inline HashMap<T, U, V, W, X>::~HashMap()
202 {
203 derefAll();
204 }
205
206 template<typename T, typename U, typename V, typename W, typename X>
207 inline int HashMap<T, U, V, W, X>::size() const
208 {
209 return m_impl.size();
210 }
211
212 template<typename T, typename U, typename V, typename W, typename X>
213 inline int HashMap<T, U, V, W, X>::capacity() const
214 {
215 return m_impl.capacity();
216 }
217
218 template<typename T, typename U, typename V, typename W, typename X>
219 inline bool HashMap<T, U, V, W, X>::isEmpty() const
220 {
221 return m_impl.isEmpty();
222 }
223
224 template<typename T, typename U, typename V, typename W, typename X>
225 inline typename HashMap<T, U, V, W, X>::iterator HashMap<T, U, V, W, X>::begin()
226 {
227 return m_impl.begin();
228 }
229
230 template<typename T, typename U, typename V, typename W, typename X>
231 inline typename HashMap<T, U, V, W, X>::iterator HashMap<T, U, V, W, X>::end()
232 {
233 return m_impl.end();
234 }
235
236 template<typename T, typename U, typename V, typename W, typename X>
237 inline typename HashMap<T, U, V, W, X>::const_iterator HashMap<T, U, V, W, X>::begin() const
238 {
239 return m_impl.begin();
240 }
241
242 template<typename T, typename U, typename V, typename W, typename X>
243 inline typename HashMap<T, U, V, W, X>::const_iterator HashMap<T, U, V, W, X>::end() const
244 {
245 return m_impl.end();
246 }
247
248 template<typename T, typename U, typename V, typename W, typename X>
249 inline typename HashMap<T, U, V, W, X>::iterator HashMap<T, U, V, W, X>::find(const KeyType& key)
250 {
251 return m_impl.find(*(const KeyStorageType*)&key);
252 }
253
254 template<typename T, typename U, typename V, typename W, typename X>
255 inline typename HashMap<T, U, V, W, X>::const_iterator HashMap<T, U, V, W, X>::find(const KeyType& key) const
256 {
257 return m_impl.find(*(const KeyStorageType*)&key);
258 }
259
260 template<typename T, typename U, typename V, typename W, typename X>
261 inline bool HashMap<T, U, V, W, X>::contains(const KeyType& key) const
262 {
263 return m_impl.contains(*(const KeyStorageType*)&key);
264 }
265
266 template<typename T, typename U, typename V, typename W, typename X>
267 inline pair<typename HashMap<T, U, V, W, X>::iterator, bool>
268 HashMap<T, U, V, W, X>::inlineAdd(const KeyType& key, const MappedType& mapped)
269 {
270 const bool canReplaceDeletedKey = !KeyTraits::needsDestruction || KeyStorageTraits::needsDestruction;
271 typedef HashMapTranslator<canReplaceDeletedKey, ValueType, ValueTraits, ValueStorageTraits, HashFunctions> TranslatorType;
272 return m_impl.template add<KeyType, MappedType, TranslatorType>(key, mapped);
273 }
274
275 template<typename T, typename U, typename V, typename W, typename X>
276 pair<typename HashMap<T, U, V, W, X>::iterator, bool>
277 HashMap<T, U, V, W, X>::set(const KeyType& key, const MappedType& mapped)
278 {
279 pair<iterator, bool> result = inlineAdd(key, mapped);
280 if (!result.second)
281 // add call above didn't change anything, so set the mapped value
282 result.first->second = mapped;
283 return result;
284 }
285
286 template<typename T, typename U, typename V, typename W, typename X>
287 pair<typename HashMap<T, U, V, W, X>::iterator, bool>
288 HashMap<T, U, V, W, X>::add(const KeyType& key, const MappedType& mapped)
289 {
290 return inlineAdd(key, mapped);
291 }
292
293 template<typename T, typename U, typename V, typename W, typename MappedTraits>
294 typename HashMap<T, U, V, W, MappedTraits>::MappedType
295 HashMap<T, U, V, W, MappedTraits>::get(const KeyType& key) const
296 {
297 if (m_impl.isEmpty())
298 return MappedTraits::emptyValue();
299 ValueStorageType* entry = const_cast<HashTableType&>(m_impl).lookup(*(const KeyStorageType*)&key);
300 if (!entry)
301 return MappedTraits::emptyValue();
302 return ((ValueType *)entry)->second;
303 }
304
305 template<typename T, typename U, typename V, typename W, typename X>
306 inline void HashMap<T, U, V, W, X>::remove(iterator it)
307 {
308 if (it.m_impl == m_impl.end())
309 return;
310 RefCounter<ValueTraits, ValueStorageTraits>::deref(*it.m_impl);
311 m_impl.remove(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>
396 inline void copyValuesToVector(const HashMap<T, U, V, W, X>& collection, Vector<U>& vector)
397 {
398 typedef typename HashMap<T, U, V, W, X>::const_iterator iterator;
399
400 vector.resize(collection.size());
401
402 iterator it = collection.begin();
403 iterator end = collection.end();
404 for (unsigned i = 0; it != end; ++it, ++i)
405 vector[i] = (*it).second;
406 }
407
408} // namespace WTF
409
410using WTF::HashMap;
411
412#endif /* WTF_HashMap_h */
Note: See TracBrowser for help on using the repository browser.