OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #ifndef VM_HASH_TABLE_H_ | 5 #ifndef VM_HASH_TABLE_H_ |
6 #define VM_HASH_TABLE_H_ | 6 #define VM_HASH_TABLE_H_ |
7 | 7 |
8 // Temporarily used when sorting the indices in EnumIndexHashTable. | 8 // Temporarily used when sorting the indices in EnumIndexHashTable. |
9 // TODO(koda): Remove these dependencies before using in production. | 9 // TODO(koda): Remove these dependencies before using in production. |
10 #include <map> | 10 #include <map> |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
144 | 144 |
145 // Returns whether 'key' matches any key in the table. | 145 // Returns whether 'key' matches any key in the table. |
146 template<typename Key> | 146 template<typename Key> |
147 bool ContainsKey(const Key& key) const { | 147 bool ContainsKey(const Key& key) const { |
148 return FindKey(key) != -1; | 148 return FindKey(key) != -1; |
149 } | 149 } |
150 | 150 |
151 // Returns the entry that matches 'key', or -1 if none exists. | 151 // Returns the entry that matches 'key', or -1 if none exists. |
152 template<typename Key> | 152 template<typename Key> |
153 intptr_t FindKey(const Key& key) const { | 153 intptr_t FindKey(const Key& key) const { |
154 ASSERT(NumOccupied() < NumEntries()); | 154 const intptr_t num_entries = NumEntries(); |
| 155 ASSERT(NumOccupied() < num_entries); |
155 // TODO(koda): Add salt. | 156 // TODO(koda): Add salt. |
156 intptr_t probe = static_cast<uword>(KeyTraits::Hash(key)) % NumEntries(); | 157 uword hash = KeyTraits::Hash(key); |
| 158 intptr_t probe = hash % num_entries; |
157 // TODO(koda): Consider quadratic probing. | 159 // TODO(koda): Consider quadratic probing. |
158 for (; ; probe = (probe + 1) % NumEntries()) { | 160 while (true) { |
159 if (IsUnused(probe)) { | 161 if (IsUnused(probe)) { |
160 return -1; | 162 return -1; |
161 } else if (IsDeleted(probe)) { | 163 } else if (!IsDeleted(probe)) { |
162 continue; | |
163 } else { | |
164 key_handle_ = GetKey(probe); | 164 key_handle_ = GetKey(probe); |
165 if (KeyTraits::IsMatch(key, key_handle_)) { | 165 if (KeyTraits::IsMatch(key, key_handle_)) { |
166 return probe; | 166 return probe; |
167 } | 167 } |
168 } | 168 } |
| 169 // Advance probe. |
| 170 probe++; |
| 171 probe = (probe == num_entries) ? 0 : probe; |
169 } | 172 } |
170 UNREACHABLE(); | 173 UNREACHABLE(); |
171 return -1; | 174 return -1; |
172 } | 175 } |
173 | 176 |
174 // Sets *entry to either: | 177 // Sets *entry to either: |
175 // - an occupied entry matching 'key', and returns true, or | 178 // - an occupied entry matching 'key', and returns true, or |
176 // - an unused/deleted entry where a matching key may be inserted, | 179 // - an unused/deleted entry where a matching key may be inserted, |
177 // and returns false. | 180 // and returns false. |
178 template<typename Key> | 181 template<typename Key> |
179 bool FindKeyOrDeletedOrUnused(const Key& key, intptr_t* entry) const { | 182 bool FindKeyOrDeletedOrUnused(const Key& key, intptr_t* entry) const { |
| 183 const intptr_t num_entries = NumEntries(); |
180 ASSERT(entry != NULL); | 184 ASSERT(entry != NULL); |
181 ASSERT(NumOccupied() < NumEntries()); | 185 ASSERT(NumOccupied() < num_entries); |
182 intptr_t probe = static_cast<uword>(KeyTraits::Hash(key)) % NumEntries(); | 186 uword hash = KeyTraits::Hash(key); |
| 187 intptr_t probe = hash % num_entries; |
183 intptr_t deleted = -1; | 188 intptr_t deleted = -1; |
184 // TODO(koda): Consider quadratic probing. | 189 // TODO(koda): Consider quadratic probing. |
185 for (; ; probe = (probe + 1) % NumEntries()) { | 190 while (true) { |
186 if (IsUnused(probe)) { | 191 if (IsUnused(probe)) { |
187 *entry = (deleted != -1) ? deleted : probe; | 192 *entry = (deleted != -1) ? deleted : probe; |
188 return false; | 193 return false; |
189 } else if (IsDeleted(probe)) { | 194 } else if (IsDeleted(probe)) { |
190 if (deleted == -1) { | 195 if (deleted == -1) { |
191 deleted = probe; | 196 deleted = probe; |
192 } | 197 } |
193 } else { | 198 } else { |
194 key_handle_ = GetKey(probe); | 199 key_handle_ = GetKey(probe); |
195 if (KeyTraits::IsMatch(key, key_handle_)) { | 200 if (KeyTraits::IsMatch(key, key_handle_)) { |
196 *entry = probe; | 201 *entry = probe; |
197 return true; | 202 return true; |
198 } | 203 } |
199 } | 204 } |
| 205 // Advance probe. |
| 206 probe++; |
| 207 probe = (probe == num_entries) ? 0 : probe; |
200 } | 208 } |
201 UNREACHABLE(); | 209 UNREACHABLE(); |
202 return false; | 210 return false; |
203 } | 211 } |
204 | 212 |
205 // Sets the key of a previously unoccupied entry. This must not be the last | 213 // Sets the key of a previously unoccupied entry. This must not be the last |
206 // unoccupied entry. | 214 // unoccupied entry. |
207 void InsertKey(intptr_t entry, const Object& key) const { | 215 void InsertKey(intptr_t entry, const Object& key) const { |
208 ASSERT(!IsOccupied(entry)); | 216 ASSERT(!IsOccupied(entry)); |
209 AdjustSmiValueAt(kOccupiedEntriesIndex, 1); | 217 AdjustSmiValueAt(kOccupiedEntriesIndex, 1); |
(...skipping 493 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
703 class EnumIndexHashSet : public HashSet<EnumIndexHashTable<KeyTraits, 0> > { | 711 class EnumIndexHashSet : public HashSet<EnumIndexHashTable<KeyTraits, 0> > { |
704 public: | 712 public: |
705 typedef HashSet<EnumIndexHashTable<KeyTraits, 0> > BaseSet; | 713 typedef HashSet<EnumIndexHashTable<KeyTraits, 0> > BaseSet; |
706 explicit EnumIndexHashSet(RawArray* data) : BaseSet(data) {} | 714 explicit EnumIndexHashSet(RawArray* data) : BaseSet(data) {} |
707 EnumIndexHashSet(Zone* zone, RawArray* data) : BaseSet(zone, data) {} | 715 EnumIndexHashSet(Zone* zone, RawArray* data) : BaseSet(zone, data) {} |
708 }; | 716 }; |
709 | 717 |
710 } // namespace dart | 718 } // namespace dart |
711 | 719 |
712 #endif // VM_HASH_TABLE_H_ | 720 #endif // VM_HASH_TABLE_H_ |
OLD | NEW |