| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2005, 2006, 2008 Apple Inc. All rights reserved. | 2 * Copyright (C) 2005, 2006, 2008 Apple Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * This library is free software; you can redistribute it and/or | 4 * This library is free software; you can redistribute it and/or |
| 5 * modify it under the terms of the GNU Library General Public | 5 * modify it under the terms of the GNU Library General Public |
| 6 * License as published by the Free Software Foundation; either | 6 * License as published by the Free Software Foundation; either |
| 7 * version 2 of the License, or (at your option) any later version. | 7 * version 2 of the License, or (at your option) any later version. |
| 8 * | 8 * |
| 9 * This library is distributed in the hope that it will be useful, | 9 * This library is distributed in the hope that it will be useful, |
| 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| (...skipping 12 matching lines...) Expand all Loading... |
| 23 | 23 |
| 24 #include "wtf/Assertions.h" | 24 #include "wtf/Assertions.h" |
| 25 #include "wtf/HashMap.h" | 25 #include "wtf/HashMap.h" |
| 26 #include "wtf/Vector.h" | 26 #include "wtf/Vector.h" |
| 27 | 27 |
| 28 namespace WTF { | 28 namespace WTF { |
| 29 | 29 |
| 30 // An unordered hash set that keeps track of how many times you added an item to | 30 // An unordered hash set that keeps track of how many times you added an item to |
| 31 // the set. The iterators have fields ->key and ->value that return the set | 31 // the set. The iterators have fields ->key and ->value that return the set |
| 32 // members and their counts, respectively. | 32 // members and their counts, respectively. |
| 33 template < | 33 template <typename Value, |
| 34 typename Value, | 34 typename HashFunctions = typename DefaultHash<Value>::Hash, |
| 35 typename HashFunctions = typename DefaultHash<Value>::Hash, | 35 typename Traits = HashTraits<Value>, |
| 36 typename Traits = HashTraits<Value>, | 36 typename Allocator = PartitionAllocator> |
| 37 typename Allocator = PartitionAllocator> | |
| 38 class HashCountedSet { | 37 class HashCountedSet { |
| 39 WTF_USE_ALLOCATOR(HashCountedSet, Allocator); | 38 WTF_USE_ALLOCATOR(HashCountedSet, Allocator); |
| 40 WTF_MAKE_NONCOPYABLE(HashCountedSet); | 39 WTF_MAKE_NONCOPYABLE(HashCountedSet); |
| 41 private: | |
| 42 typedef HashMap<Value, unsigned, HashFunctions, Traits, HashTraits<unsigned>
, Allocator> ImplType; | |
| 43 public: | |
| 44 typedef Value ValueType; | |
| 45 typedef typename ImplType::iterator iterator; | |
| 46 typedef typename ImplType::const_iterator const_iterator; | |
| 47 typedef typename ImplType::AddResult AddResult; | |
| 48 | 40 |
| 49 HashCountedSet() {} | 41 private: |
| 42 typedef HashMap<Value, |
| 43 unsigned, |
| 44 HashFunctions, |
| 45 Traits, |
| 46 HashTraits<unsigned>, |
| 47 Allocator> |
| 48 ImplType; |
| 50 | 49 |
| 51 void swap(HashCountedSet& other) { m_impl.swap(other.m_impl); } | 50 public: |
| 51 typedef Value ValueType; |
| 52 typedef typename ImplType::iterator iterator; |
| 53 typedef typename ImplType::const_iterator const_iterator; |
| 54 typedef typename ImplType::AddResult AddResult; |
| 52 | 55 |
| 53 unsigned size() const { return m_impl.size(); } | 56 HashCountedSet() {} |
| 54 unsigned capacity() const { return m_impl.capacity(); } | |
| 55 bool isEmpty() const { return m_impl.isEmpty(); } | |
| 56 | 57 |
| 57 // Iterators iterate over pairs of values (called key) and counts (called | 58 void swap(HashCountedSet& other) { m_impl.swap(other.m_impl); } |
| 58 // value). | |
| 59 iterator begin() { return m_impl.begin(); } | |
| 60 iterator end() { return m_impl.end(); } | |
| 61 const_iterator begin() const { return m_impl.begin(); } | |
| 62 const_iterator end() const { return m_impl.end(); } | |
| 63 | 59 |
| 64 iterator find(const ValueType& value) { return m_impl.find(value); } | 60 unsigned size() const { return m_impl.size(); } |
| 65 const_iterator find(const ValueType& value) const { return m_impl.find(value
); } | 61 unsigned capacity() const { return m_impl.capacity(); } |
| 66 bool contains(const ValueType& value ) const { return m_impl.contains(value)
; } | 62 bool isEmpty() const { return m_impl.isEmpty(); } |
| 67 unsigned count(const ValueType& value ) const { return m_impl.get(value); } | |
| 68 | 63 |
| 69 // Increases the count if an equal value is already present the return value | 64 // Iterators iterate over pairs of values (called key) and counts (called |
| 70 // is a pair of an iterator to the new value's location, and a bool that is | 65 // value). |
| 71 // true if an new entry was added. | 66 iterator begin() { return m_impl.begin(); } |
| 72 AddResult add(const ValueType&); | 67 iterator end() { return m_impl.end(); } |
| 68 const_iterator begin() const { return m_impl.begin(); } |
| 69 const_iterator end() const { return m_impl.end(); } |
| 73 | 70 |
| 74 // Reduces the count of the value, and removes it if count goes down to | 71 iterator find(const ValueType& value) { return m_impl.find(value); } |
| 75 // zero, returns true if the value is removed. | 72 const_iterator find(const ValueType& value) const { |
| 76 bool remove(const ValueType& value) { return remove(find(value)); } | 73 return m_impl.find(value); |
| 77 bool remove(iterator); | 74 } |
| 75 bool contains(const ValueType& value) const { return m_impl.contains(value); } |
| 76 unsigned count(const ValueType& value) const { return m_impl.get(value); } |
| 78 | 77 |
| 79 // Removes the value, regardless of its count. | 78 // Increases the count if an equal value is already present the return value |
| 80 void removeAll(const ValueType& value) { removeAll(find(value)); } | 79 // is a pair of an iterator to the new value's location, and a bool that is |
| 81 void removeAll(iterator); | 80 // true if an new entry was added. |
| 81 AddResult add(const ValueType&); |
| 82 | 82 |
| 83 // Clears the whole set. | 83 // Reduces the count of the value, and removes it if count goes down to |
| 84 void clear() { m_impl.clear(); } | 84 // zero, returns true if the value is removed. |
| 85 bool remove(const ValueType& value) { return remove(find(value)); } |
| 86 bool remove(iterator); |
| 85 | 87 |
| 86 template <typename VisitorDispatcher> | 88 // Removes the value, regardless of its count. |
| 87 void trace(VisitorDispatcher visitor) { m_impl.trace(visitor); } | 89 void removeAll(const ValueType& value) { removeAll(find(value)); } |
| 90 void removeAll(iterator); |
| 88 | 91 |
| 89 private: | 92 // Clears the whole set. |
| 90 ImplType m_impl; | 93 void clear() { m_impl.clear(); } |
| 94 |
| 95 template <typename VisitorDispatcher> |
| 96 void trace(VisitorDispatcher visitor) { |
| 97 m_impl.trace(visitor); |
| 98 } |
| 99 |
| 100 private: |
| 101 ImplType m_impl; |
| 91 }; | 102 }; |
| 92 | 103 |
| 93 template <typename T, typename U, typename V, typename W> | 104 template <typename T, typename U, typename V, typename W> |
| 94 inline typename HashCountedSet<T, U, V, W>::AddResult HashCountedSet<T, U, V, W>
::add(const ValueType& value) | 105 inline typename HashCountedSet<T, U, V, W>::AddResult |
| 95 { | 106 HashCountedSet<T, U, V, W>::add(const ValueType& value) { |
| 96 AddResult result = m_impl.add(value, 0); | 107 AddResult result = m_impl.add(value, 0); |
| 97 ++result.storedValue->value; | 108 ++result.storedValue->value; |
| 98 return result; | 109 return result; |
| 99 } | 110 } |
| 100 | 111 |
| 101 template <typename T, typename U, typename V, typename W> | 112 template <typename T, typename U, typename V, typename W> |
| 102 inline bool HashCountedSet<T, U, V, W>::remove(iterator it) | 113 inline bool HashCountedSet<T, U, V, W>::remove(iterator it) { |
| 103 { | 114 if (it == end()) |
| 104 if (it == end()) | 115 return false; |
| 105 return false; | |
| 106 | 116 |
| 107 unsigned oldVal = it->value; | 117 unsigned oldVal = it->value; |
| 108 ASSERT(oldVal); | 118 ASSERT(oldVal); |
| 109 unsigned newVal = oldVal - 1; | 119 unsigned newVal = oldVal - 1; |
| 110 if (newVal) { | 120 if (newVal) { |
| 111 it->value = newVal; | 121 it->value = newVal; |
| 112 return false; | 122 return false; |
| 113 } | 123 } |
| 114 | 124 |
| 115 m_impl.remove(it); | 125 m_impl.remove(it); |
| 116 return true; | 126 return true; |
| 117 } | 127 } |
| 118 | 128 |
| 119 template <typename T, typename U, typename V, typename W> | 129 template <typename T, typename U, typename V, typename W> |
| 120 inline void HashCountedSet<T, U, V, W>::removeAll(iterator it) | 130 inline void HashCountedSet<T, U, V, W>::removeAll(iterator it) { |
| 121 { | 131 if (it == end()) |
| 122 if (it == end()) | 132 return; |
| 123 return; | |
| 124 | 133 |
| 125 m_impl.remove(it); | 134 m_impl.remove(it); |
| 126 } | 135 } |
| 127 | 136 |
| 128 template <typename T, typename U, typename V, typename W, typename VectorType> | 137 template <typename T, typename U, typename V, typename W, typename VectorType> |
| 129 inline void copyToVector(const HashCountedSet<T, U, V, W>& collection, VectorTyp
e& vector) | 138 inline void copyToVector(const HashCountedSet<T, U, V, W>& collection, |
| 130 { | 139 VectorType& vector) { |
| 131 typedef typename HashCountedSet<T, U, V, W>::const_iterator iterator; | 140 typedef typename HashCountedSet<T, U, V, W>::const_iterator iterator; |
| 132 | 141 |
| 133 vector.resize(collection.size()); | 142 vector.resize(collection.size()); |
| 134 | 143 |
| 135 iterator it = collection.begin(); | 144 iterator it = collection.begin(); |
| 136 iterator end = collection.end(); | 145 iterator end = collection.end(); |
| 137 for (unsigned i = 0; it != end; ++it, ++i) | 146 for (unsigned i = 0; it != end; ++it, ++i) |
| 138 vector[i] = *it; | 147 vector[i] = *it; |
| 139 } | 148 } |
| 140 | 149 |
| 141 template <typename Value, typename HashFunctions, typename Traits, typename Allo
cator, size_t inlineCapacity, typename VectorAllocator> | 150 template <typename Value, |
| 142 inline void copyToVector(const HashCountedSet<Value, HashFunctions, Traits, Allo
cator>& collection, Vector<Value, inlineCapacity, VectorAllocator>& vector) | 151 typename HashFunctions, |
| 143 { | 152 typename Traits, |
| 144 typedef typename HashCountedSet<Value, HashFunctions, Traits, Allocator>::co
nst_iterator iterator; | 153 typename Allocator, |
| 154 size_t inlineCapacity, |
| 155 typename VectorAllocator> |
| 156 inline void copyToVector( |
| 157 const HashCountedSet<Value, HashFunctions, Traits, Allocator>& collection, |
| 158 Vector<Value, inlineCapacity, VectorAllocator>& vector) { |
| 159 typedef typename HashCountedSet<Value, HashFunctions, Traits, |
| 160 Allocator>::const_iterator iterator; |
| 145 | 161 |
| 146 vector.resize(collection.size()); | 162 vector.resize(collection.size()); |
| 147 | 163 |
| 148 iterator it = collection.begin(); | 164 iterator it = collection.begin(); |
| 149 iterator end = collection.end(); | 165 iterator end = collection.end(); |
| 150 for (unsigned i = 0; it != end; ++it, ++i) | 166 for (unsigned i = 0; it != end; ++it, ++i) |
| 151 vector[i] = (*it).key; | 167 vector[i] = (*it).key; |
| 152 } | 168 } |
| 153 | 169 |
| 154 #if !ENABLE(OILPAN) | 170 #if !ENABLE(OILPAN) |
| 155 template <typename T, typename U, typename V> | 171 template <typename T, typename U, typename V> |
| 156 struct NeedsTracing<HashCountedSet<T, U, V>> { | 172 struct NeedsTracing<HashCountedSet<T, U, V>> { |
| 157 static const bool value = false; | 173 static const bool value = false; |
| 158 }; | 174 }; |
| 159 #endif | 175 #endif |
| 160 | 176 |
| 161 } // namespace WTF | 177 } // namespace WTF |
| 162 | 178 |
| 163 using WTF::HashCountedSet; | 179 using WTF::HashCountedSet; |
| 164 | 180 |
| 165 #endif // WTF_HashCountedSet_h | 181 #endif // WTF_HashCountedSet_h |
| OLD | NEW |