2 * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
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.
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.
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.
21 #ifndef RefPtrHashMap_h
22 #define RefPtrHashMap_h
26 // This specialization is a direct copy of HashMap, with overloaded functions
27 // to allow for lookup by pointer instead of RefPtr, avoiding ref-count churn.
29 // FIXME: Find a better way that doesn't require an entire copy of the HashMap template.
31 template<typename RawKeyType
, typename ValueType
, typename ValueTraits
, typename HashFunctions
>
32 struct RefPtrHashMapRawKeyTranslator
{
33 typedef typename
ValueType::first_type KeyType
;
34 typedef typename
ValueType::second_type MappedType
;
35 typedef typename
ValueTraits::FirstTraits KeyTraits
;
36 typedef typename
ValueTraits::SecondTraits MappedTraits
;
38 static unsigned hash(RawKeyType key
) { return HashFunctions::hash(key
); }
39 static bool equal(const KeyType
& a
, RawKeyType b
) { return HashFunctions::equal(a
, b
); }
40 static void translate(ValueType
& location
, RawKeyType key
, const MappedType
& mapped
)
43 location
.second
= mapped
;
47 template<typename T
, typename MappedArg
, typename HashArg
, typename KeyTraitsArg
, typename MappedTraitsArg
>
48 class HashMap
<RefPtr
<T
>, MappedArg
, HashArg
, KeyTraitsArg
, MappedTraitsArg
> {
49 WTF_MAKE_FAST_ALLOCATED
;
51 typedef KeyTraitsArg KeyTraits
;
52 typedef MappedTraitsArg MappedTraits
;
53 typedef PairHashTraits
<KeyTraits
, MappedTraits
> ValueTraits
;
56 typedef typename
KeyTraits::TraitType KeyType
;
57 typedef T
* RawKeyType
;
58 typedef typename
MappedTraits::TraitType MappedType
;
59 typedef typename
ValueTraits::TraitType ValueType
;
62 typedef HashArg HashFunctions
;
64 typedef HashTable
<KeyType
, ValueType
, PairFirstExtractor
<ValueType
>,
65 HashFunctions
, ValueTraits
, KeyTraits
> HashTableType
;
67 typedef RefPtrHashMapRawKeyTranslator
<RawKeyType
, ValueType
, ValueTraits
, HashFunctions
>
71 typedef HashTableIteratorAdapter
<HashTableType
, ValueType
> iterator
;
72 typedef HashTableConstIteratorAdapter
<HashTableType
, ValueType
> const_iterator
;
80 // iterators iterate over pairs of keys and values
83 const_iterator
begin() const;
84 const_iterator
end() const;
86 iterator
find(const KeyType
&);
87 iterator
find(RawKeyType
);
88 const_iterator
find(const KeyType
&) const;
89 const_iterator
find(RawKeyType
) const;
90 bool contains(const KeyType
&) const;
91 bool contains(RawKeyType
) const;
92 MappedType
get(const KeyType
&) const;
93 MappedType
get(RawKeyType
) const;
94 MappedType
inlineGet(RawKeyType
) const;
96 // replaces value but not key if key is already present
97 // return value is a pair of the iterator to the key location,
98 // and a boolean that's true if a new value was actually added
99 pair
<iterator
, bool> set(const KeyType
&, const MappedType
&);
100 pair
<iterator
, bool> set(RawKeyType
, const MappedType
&);
102 // does nothing if key is already present
103 // return value is a pair of the iterator to the key location,
104 // and a boolean that's true if a new value was actually added
105 pair
<iterator
, bool> add(const KeyType
&, const MappedType
&);
106 pair
<iterator
, bool> add(RawKeyType
, const MappedType
&);
108 void remove(const KeyType
&);
109 void remove(RawKeyType
);
110 void remove(iterator
);
113 MappedType
take(const KeyType
&); // efficient combination of get with remove
114 MappedType
take(RawKeyType
); // efficient combination of get with remove
117 pair
<iterator
, bool> inlineAdd(const KeyType
&, const MappedType
&);
118 pair
<iterator
, bool> inlineAdd(RawKeyType
, const MappedType
&);
120 HashTableType m_impl
;
123 template<typename T
, typename U
, typename V
, typename W
, typename X
>
124 inline void HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::swap(HashMap
& other
)
126 m_impl
.swap(other
.m_impl
);
129 template<typename T
, typename U
, typename V
, typename W
, typename X
>
130 inline int HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::size() const
132 return m_impl
.size();
135 template<typename T
, typename U
, typename V
, typename W
, typename X
>
136 inline int HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::capacity() const
138 return m_impl
.capacity();
141 template<typename T
, typename U
, typename V
, typename W
, typename X
>
142 inline bool HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::isEmpty() const
144 return m_impl
.isEmpty();
147 template<typename T
, typename U
, typename V
, typename W
, typename X
>
148 inline typename HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::iterator HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::begin()
150 return m_impl
.begin();
153 template<typename T
, typename U
, typename V
, typename W
, typename X
>
154 inline typename HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::iterator HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::end()
159 template<typename T
, typename U
, typename V
, typename W
, typename X
>
160 inline typename HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::const_iterator HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::begin() const
162 return m_impl
.begin();
165 template<typename T
, typename U
, typename V
, typename W
, typename X
>
166 inline typename HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::const_iterator HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::end() const
171 template<typename T
, typename U
, typename V
, typename W
, typename X
>
172 inline typename HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::iterator HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::find(const KeyType
& key
)
174 return m_impl
.find(key
);
177 template<typename T
, typename U
, typename V
, typename W
, typename X
>
178 inline typename HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::iterator HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::find(RawKeyType key
)
180 return m_impl
.template find
<RawKeyType
, RawKeyTranslator
>(key
);
183 template<typename T
, typename U
, typename V
, typename W
, typename X
>
184 inline typename HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::const_iterator HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::find(const KeyType
& key
) const
186 return m_impl
.find(key
);
189 template<typename T
, typename U
, typename V
, typename W
, typename X
>
190 inline typename HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::const_iterator HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::find(RawKeyType key
) const
192 return m_impl
.template find
<RawKeyType
, RawKeyTranslator
>(key
);
195 template<typename T
, typename U
, typename V
, typename W
, typename X
>
196 inline bool HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::contains(const KeyType
& key
) const
198 return m_impl
.contains(key
);
201 template<typename T
, typename U
, typename V
, typename W
, typename X
>
202 inline bool HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::contains(RawKeyType key
) const
204 return m_impl
.template contains
<RawKeyType
, RawKeyTranslator
>(key
);
207 template<typename T
, typename U
, typename V
, typename W
, typename X
>
208 inline pair
<typename HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::iterator
, bool>
209 HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::inlineAdd(const KeyType
& key
, const MappedType
& mapped
)
211 typedef HashMapTranslator
<ValueType
, ValueTraits
, HashFunctions
> TranslatorType
;
212 return m_impl
.template add
<KeyType
, MappedType
, TranslatorType
>(key
, mapped
);
215 template<typename T
, typename U
, typename V
, typename W
, typename X
>
216 inline pair
<typename HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::iterator
, bool>
217 HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::inlineAdd(RawKeyType key
, const MappedType
& mapped
)
219 return m_impl
.template add
<RawKeyType
, MappedType
, RawKeyTranslator
>(key
, mapped
);
222 template<typename T
, typename U
, typename V
, typename W
, typename X
>
223 pair
<typename HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::iterator
, bool>
224 HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::set(const KeyType
& key
, const MappedType
& mapped
)
226 pair
<iterator
, bool> result
= inlineAdd(key
, mapped
);
227 if (!result
.second
) {
228 // add call above didn't change anything, so set the mapped value
229 result
.first
->second
= mapped
;
234 template<typename T
, typename U
, typename V
, typename W
, typename X
>
235 pair
<typename HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::iterator
, bool>
236 HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::set(RawKeyType key
, const MappedType
& mapped
)
238 pair
<iterator
, bool> result
= inlineAdd(key
, mapped
);
239 if (!result
.second
) {
240 // add call above didn't change anything, so set the mapped value
241 result
.first
->second
= mapped
;
246 template<typename T
, typename U
, typename V
, typename W
, typename X
>
247 pair
<typename HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::iterator
, bool>
248 HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::add(const KeyType
& key
, const MappedType
& mapped
)
250 return inlineAdd(key
, mapped
);
253 template<typename T
, typename U
, typename V
, typename W
, typename X
>
254 pair
<typename HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::iterator
, bool>
255 HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::add(RawKeyType key
, const MappedType
& mapped
)
257 return inlineAdd(key
, mapped
);
260 template<typename T
, typename U
, typename V
, typename W
, typename MappedTraits
>
261 typename HashMap
<RefPtr
<T
>, U
, V
, W
, MappedTraits
>::MappedType
262 HashMap
<RefPtr
<T
>, U
, V
, W
, MappedTraits
>::get(const KeyType
& key
) const
264 ValueType
* entry
= const_cast<HashTableType
&>(m_impl
).lookup(key
);
266 return MappedTraits::emptyValue();
267 return entry
->second
;
270 template<typename T
, typename U
, typename V
, typename W
, typename MappedTraits
>
271 typename HashMap
<RefPtr
<T
>, U
, V
, W
, MappedTraits
>::MappedType
272 inline HashMap
<RefPtr
<T
>, U
, V
, W
, MappedTraits
>::inlineGet(RawKeyType key
) const
274 ValueType
* entry
= const_cast<HashTableType
&>(m_impl
).template lookup
<RawKeyType
, RawKeyTranslator
>(key
);
276 return MappedTraits::emptyValue();
277 return entry
->second
;
280 template<typename T
, typename U
, typename V
, typename W
, typename MappedTraits
>
281 typename HashMap
<RefPtr
<T
>, U
, V
, W
, MappedTraits
>::MappedType
282 HashMap
<RefPtr
<T
>, U
, V
, W
, MappedTraits
>::get(RawKeyType key
) const
284 return inlineGet(key
);
287 template<typename T
, typename U
, typename V
, typename W
, typename X
>
288 inline void HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::remove(iterator it
)
290 if (it
.m_impl
== m_impl
.end())
292 m_impl
.internalCheckTableConsistency();
293 m_impl
.removeWithoutEntryConsistencyCheck(it
.m_impl
);
296 template<typename T
, typename U
, typename V
, typename W
, typename X
>
297 inline void HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::remove(const KeyType
& key
)
302 template<typename T
, typename U
, typename V
, typename W
, typename X
>
303 inline void HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::remove(RawKeyType key
)
308 template<typename T
, typename U
, typename V
, typename W
, typename X
>
309 inline void HashMap
<RefPtr
<T
>, U
, V
, W
, X
>::clear()
314 template<typename T
, typename U
, typename V
, typename W
, typename MappedTraits
>
315 typename HashMap
<RefPtr
<T
>, U
, V
, W
, MappedTraits
>::MappedType
316 HashMap
<RefPtr
<T
>, U
, V
, W
, MappedTraits
>::take(const KeyType
& key
)
318 // This can probably be made more efficient to avoid ref/deref churn.
319 iterator it
= find(key
);
321 return MappedTraits::emptyValue();
322 typename HashMap
<RefPtr
<T
>, U
, V
, W
, MappedTraits
>::MappedType result
= it
->second
;
327 template<typename T
, typename U
, typename V
, typename W
, typename MappedTraits
>
328 typename HashMap
<RefPtr
<T
>, U
, V
, W
, MappedTraits
>::MappedType
329 HashMap
<RefPtr
<T
>, U
, V
, W
, MappedTraits
>::take(RawKeyType key
)
331 // This can probably be made more efficient to avoid ref/deref churn.
332 iterator it
= find(key
);
334 return MappedTraits::emptyValue();
335 typename HashMap
<RefPtr
<T
>, U
, V
, W
, MappedTraits
>::MappedType result
= it
->second
;
342 #endif // RefPtrHashMap_h