RefPtrHashMap.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. /*
  2. * Copyright (C) 2005, 2006, 2007, 2008, 2011 Apple Inc. All rights reserved.
  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. #ifndef RefPtrHashMap_h
  21. #define RefPtrHashMap_h
  22. namespace WTF {
  23. // This specialization is a copy of HashMap for use with RefPtr keys, with overloaded functions
  24. // to allow for lookup by pointer instead of RefPtr, avoiding ref-count churn.
  25. // FIXME: Find a way to do this with traits that doesn't require a copy of the HashMap template.
  26. template<typename T, typename MappedArg, typename HashArg, typename KeyTraitsArg, typename MappedTraitsArg, bool shared>
  27. class HashMap<RefPtr<T>, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg, shared> {
  28. WTF_MAKE_FAST_ALLOCATED;
  29. private:
  30. typedef KeyTraitsArg KeyTraits;
  31. typedef MappedTraitsArg MappedTraits;
  32. typedef KeyValuePairHashTraits<KeyTraits, MappedTraits, shared> ValueTraits;
  33. public:
  34. typedef typename KeyTraits::TraitType KeyType;
  35. typedef T* RawKeyType;
  36. typedef typename MappedTraits::TraitType MappedType;
  37. typedef typename ValueTraits::TraitType ValueType;
  38. private:
  39. typedef typename MappedTraits::PassInType MappedPassInType;
  40. typedef typename MappedTraits::PassOutType MappedPassOutType;
  41. typedef typename MappedTraits::PeekType MappedPeekType;
  42. typedef typename ReferenceTypeMaker<MappedPassInType>::ReferenceType MappedPassInReferenceType;
  43. typedef HashArg HashFunctions;
  44. typedef HashTable<KeyType, ValueType, KeyValuePairKeyExtractor<ValueType>,
  45. HashFunctions, ValueTraits, KeyTraits> HashTableType;
  46. typedef HashMapTranslator<ValueTraits, HashFunctions>
  47. Translator;
  48. public:
  49. typedef HashTableIteratorAdapter<HashTableType, ValueType> iterator;
  50. typedef HashTableConstIteratorAdapter<HashTableType, ValueType> const_iterator;
  51. typedef typename HashTableType::AddResult AddResult;
  52. void swap(HashMap&);
  53. int size() const;
  54. int capacity() const;
  55. bool isEmpty() const;
  56. // iterators iterate over pairs of keys and values
  57. iterator begin();
  58. iterator end();
  59. const_iterator begin() const;
  60. const_iterator end() const;
  61. iterator find(const KeyType&);
  62. iterator find(RawKeyType);
  63. const_iterator find(const KeyType&) const;
  64. const_iterator find(RawKeyType) const;
  65. bool contains(const KeyType&) const;
  66. bool contains(RawKeyType) const;
  67. MappedPeekType get(const KeyType&) const;
  68. MappedPeekType get(RawKeyType) const;
  69. MappedPeekType inlineGet(RawKeyType) const;
  70. // replaces value but not key if key is already present
  71. // return value is a pair of the iterator to the key location,
  72. // and a boolean that's true if a new value was actually added
  73. AddResult set(const KeyType&, MappedPassInType);
  74. AddResult set(RawKeyType, MappedPassInType);
  75. // does nothing if key is already present
  76. // return value is a pair of the iterator to the key location,
  77. // and a boolean that's true if a new value was actually added
  78. AddResult add(const KeyType&, MappedPassInType);
  79. AddResult add(RawKeyType, MappedPassInType);
  80. void remove(const KeyType&);
  81. void remove(RawKeyType);
  82. void remove(iterator);
  83. void clear();
  84. MappedPassOutType take(const KeyType&); // efficient combination of get with remove
  85. MappedPassOutType take(RawKeyType); // efficient combination of get with remove
  86. private:
  87. AddResult inlineAdd(const KeyType&, MappedPassInReferenceType);
  88. AddResult inlineAdd(RawKeyType, MappedPassInReferenceType);
  89. HashTableType m_impl;
  90. };
  91. template<typename T, typename U, typename V, typename W, typename X, bool shared>
  92. inline void HashMap<RefPtr<T>, U, V, W, X, shared>::swap(HashMap& other)
  93. {
  94. m_impl.swap(other.m_impl);
  95. }
  96. template<typename T, typename U, typename V, typename W, typename X, bool shared>
  97. inline int HashMap<RefPtr<T>, U, V, W, X, shared>::size() const
  98. {
  99. return m_impl.size();
  100. }
  101. template<typename T, typename U, typename V, typename W, typename X, bool shared>
  102. inline int HashMap<RefPtr<T>, U, V, W, X, shared>::capacity() const
  103. {
  104. return m_impl.capacity();
  105. }
  106. template<typename T, typename U, typename V, typename W, typename X, bool shared>
  107. inline bool HashMap<RefPtr<T>, U, V, W, X, shared>::isEmpty() const
  108. {
  109. return m_impl.isEmpty();
  110. }
  111. template<typename T, typename U, typename V, typename W, typename X, bool shared>
  112. inline typename HashMap<RefPtr<T>, U, V, W, X, shared>::iterator HashMap<RefPtr<T>, U, V, W, X, shared>::begin()
  113. {
  114. return m_impl.begin();
  115. }
  116. template<typename T, typename U, typename V, typename W, typename X, bool shared>
  117. inline typename HashMap<RefPtr<T>, U, V, W, X, shared>::iterator HashMap<RefPtr<T>, U, V, W, X, shared>::end()
  118. {
  119. return m_impl.end();
  120. }
  121. template<typename T, typename U, typename V, typename W, typename X, bool shared>
  122. inline typename HashMap<RefPtr<T>, U, V, W, X, shared>::const_iterator HashMap<RefPtr<T>, U, V, W, X, shared>::begin() const
  123. {
  124. return m_impl.begin();
  125. }
  126. template<typename T, typename U, typename V, typename W, typename X, bool shared>
  127. inline typename HashMap<RefPtr<T>, U, V, W, X, shared>::const_iterator HashMap<RefPtr<T>, U, V, W, X, shared>::end() const
  128. {
  129. return m_impl.end();
  130. }
  131. template<typename T, typename U, typename V, typename W, typename X, bool shared>
  132. inline typename HashMap<RefPtr<T>, U, V, W, X, shared>::iterator HashMap<RefPtr<T>, U, V, W, X, shared>::find(const KeyType& key)
  133. {
  134. return m_impl.find(key);
  135. }
  136. template<typename T, typename U, typename V, typename W, typename X, bool shared>
  137. inline typename HashMap<RefPtr<T>, U, V, W, X, shared>::iterator HashMap<RefPtr<T>, U, V, W, X, shared>::find(RawKeyType key)
  138. {
  139. return m_impl.template find<Translator>(key);
  140. }
  141. template<typename T, typename U, typename V, typename W, typename X, bool shared>
  142. inline typename HashMap<RefPtr<T>, U, V, W, X, shared>::const_iterator HashMap<RefPtr<T>, U, V, W, X, shared>::find(const KeyType& key) const
  143. {
  144. return m_impl.find(key);
  145. }
  146. template<typename T, typename U, typename V, typename W, typename X, bool shared>
  147. inline typename HashMap<RefPtr<T>, U, V, W, X, shared>::const_iterator HashMap<RefPtr<T>, U, V, W, X, shared>::find(RawKeyType key) const
  148. {
  149. return m_impl.template find<Translator>(key);
  150. }
  151. template<typename T, typename U, typename V, typename W, typename X, bool shared>
  152. inline bool HashMap<RefPtr<T>, U, V, W, X, shared>::contains(const KeyType& key) const
  153. {
  154. return m_impl.contains(key);
  155. }
  156. template<typename T, typename U, typename V, typename W, typename X, bool shared>
  157. inline bool HashMap<RefPtr<T>, U, V, W, X, shared>::contains(RawKeyType key) const
  158. {
  159. return m_impl.template contains<Translator>(key);
  160. }
  161. template<typename T, typename U, typename V, typename W, typename X, bool shared>
  162. inline typename HashMap<RefPtr<T>, U, V, W, X, shared>::AddResult
  163. HashMap<RefPtr<T>, U, V, W, X, shared>::inlineAdd(const KeyType& key, MappedPassInReferenceType mapped)
  164. {
  165. return m_impl.template add<Translator>(key, mapped);
  166. }
  167. template<typename T, typename U, typename V, typename W, typename X, bool shared>
  168. inline typename HashMap<RefPtr<T>, U, V, W, X, shared>::AddResult
  169. HashMap<RefPtr<T>, U, V, W, X, shared>::inlineAdd(RawKeyType key, MappedPassInReferenceType mapped)
  170. {
  171. return m_impl.template add<Translator>(key, mapped);
  172. }
  173. template<typename T, typename U, typename V, typename W, typename X, bool shared>
  174. typename HashMap<RefPtr<T>, U, V, W, X, shared>::AddResult
  175. HashMap<RefPtr<T>, U, V, W, X, shared>::set(const KeyType& key, MappedPassInType mapped)
  176. {
  177. AddResult result = inlineAdd(key, mapped);
  178. if (!result.isNewEntry) {
  179. // The inlineAdd call above found an existing hash table entry; we need to set the mapped value.
  180. MappedTraits::store(mapped, result.iterator->value);
  181. }
  182. return result;
  183. }
  184. template<typename T, typename U, typename V, typename W, typename X, bool shared>
  185. typename HashMap<RefPtr<T>, U, V, W, X, shared>::AddResult
  186. HashMap<RefPtr<T>, U, V, W, X, shared>::set(RawKeyType key, MappedPassInType mapped)
  187. {
  188. AddResult result = inlineAdd(key, mapped);
  189. if (!result.isNewEntry) {
  190. // The inlineAdd call above found an existing hash table entry; we need to set the mapped value.
  191. MappedTraits::store(mapped, result.iterator->value);
  192. }
  193. return result;
  194. }
  195. template<typename T, typename U, typename V, typename W, typename X, bool shared>
  196. typename HashMap<RefPtr<T>, U, V, W, X, shared>::AddResult
  197. HashMap<RefPtr<T>, U, V, W, X, shared>::add(const KeyType& key, MappedPassInType mapped)
  198. {
  199. return inlineAdd(key, mapped);
  200. }
  201. template<typename T, typename U, typename V, typename W, typename X, bool shared>
  202. typename HashMap<RefPtr<T>, U, V, W, X, shared>::AddResult
  203. HashMap<RefPtr<T>, U, V, W, X, shared>::add(RawKeyType key, MappedPassInType mapped)
  204. {
  205. return inlineAdd(key, mapped);
  206. }
  207. template<typename T, typename U, typename V, typename W, typename MappedTraits, bool shared>
  208. typename HashMap<RefPtr<T>, U, V, W, MappedTraits, shared>::MappedPeekType
  209. HashMap<RefPtr<T>, U, V, W, MappedTraits, shared>::get(const KeyType& key) const
  210. {
  211. ValueType* entry = const_cast<HashTableType&>(m_impl).lookup(key);
  212. if (!entry)
  213. return MappedTraits::peek(MappedTraits::emptyValue());
  214. return MappedTraits::peek(entry->value);
  215. }
  216. template<typename T, typename U, typename V, typename W, typename MappedTraits, bool shared>
  217. typename HashMap<RefPtr<T>, U, V, W, MappedTraits, shared>::MappedPeekType
  218. inline HashMap<RefPtr<T>, U, V, W, MappedTraits, shared>::inlineGet(RawKeyType key) const
  219. {
  220. ValueType* entry = const_cast<HashTableType&>(m_impl).template lookup<Translator>(key);
  221. if (!entry)
  222. return MappedTraits::peek(MappedTraits::emptyValue());
  223. return MappedTraits::peek(entry->value);
  224. }
  225. template<typename T, typename U, typename V, typename W, typename MappedTraits, bool shared>
  226. typename HashMap<RefPtr<T>, U, V, W, MappedTraits, shared>::MappedPeekType
  227. HashMap<RefPtr<T>, U, V, W, MappedTraits, shared>::get(RawKeyType key) const
  228. {
  229. return inlineGet(key);
  230. }
  231. template<typename T, typename U, typename V, typename W, typename X, bool shared>
  232. inline void HashMap<RefPtr<T>, U, V, W, X, shared>::remove(iterator it)
  233. {
  234. if (it.m_impl == m_impl.end())
  235. return;
  236. m_impl.internalCheckTableConsistency();
  237. m_impl.removeWithoutEntryConsistencyCheck(it.m_impl);
  238. }
  239. template<typename T, typename U, typename V, typename W, typename X, bool shared>
  240. inline void HashMap<RefPtr<T>, U, V, W, X, shared>::remove(const KeyType& key)
  241. {
  242. remove(find(key));
  243. }
  244. template<typename T, typename U, typename V, typename W, typename X, bool shared>
  245. inline void HashMap<RefPtr<T>, U, V, W, X, shared>::remove(RawKeyType key)
  246. {
  247. remove(find(key));
  248. }
  249. template<typename T, typename U, typename V, typename W, typename X, bool shared>
  250. inline void HashMap<RefPtr<T>, U, V, W, X, shared>::clear()
  251. {
  252. m_impl.clear();
  253. }
  254. template<typename T, typename U, typename V, typename W, typename MappedTraits, bool shared>
  255. typename HashMap<RefPtr<T>, U, V, W, MappedTraits, shared>::MappedPassOutType
  256. HashMap<RefPtr<T>, U, V, W, MappedTraits, shared>::take(const KeyType& key)
  257. {
  258. iterator it = find(key);
  259. if (it == end())
  260. return MappedTraits::passOut(MappedTraits::emptyValue());
  261. MappedPassOutType result = MappedTraits::passOut(it->value);
  262. remove(it);
  263. return result;
  264. }
  265. template<typename T, typename U, typename V, typename W, typename MappedTraits, bool shared>
  266. typename HashMap<RefPtr<T>, U, V, W, MappedTraits, shared>::MappedPassOutType
  267. HashMap<RefPtr<T>, U, V, W, MappedTraits, shared>::take(RawKeyType key)
  268. {
  269. iterator it = find(key);
  270. if (it == end())
  271. return MappedTraits::passOut(MappedTraits::emptyValue());
  272. MappedPassOutType result = MappedTraits::passOut(it->value);
  273. remove(it);
  274. return result;
  275. }
  276. } // namespace WTF
  277. #endif // RefPtrHashMap_h