Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(317)

Side by Side Diff: runtime/vm/hash_map.h

Issue 2481873005: clang-format runtime/vm (Closed)
Patch Set: Merge Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/handles_impl.h ('k') | runtime/vm/hash_map_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 RUNTIME_VM_HASH_MAP_H_ 5 #ifndef RUNTIME_VM_HASH_MAP_H_
6 #define RUNTIME_VM_HASH_MAP_H_ 6 #define RUNTIME_VM_HASH_MAP_H_
7 7
8 #include "vm/growable_array.h" // For Malloc, EmptyBase 8 #include "vm/growable_array.h" // For Malloc, EmptyBase
9 #include "vm/zone.h" 9 #include "vm/zone.h"
10 10
11 namespace dart { 11 namespace dart {
12 12
13 template<typename KeyValueTrait, typename B, typename Allocator = Zone> 13 template <typename KeyValueTrait, typename B, typename Allocator = Zone>
14 class BaseDirectChainedHashMap : public B { 14 class BaseDirectChainedHashMap : public B {
15 public: 15 public:
16 explicit BaseDirectChainedHashMap(Allocator* allocator) 16 explicit BaseDirectChainedHashMap(Allocator* allocator)
17 : array_size_(0), 17 : array_size_(0),
18 lists_size_(0), 18 lists_size_(0),
19 count_(0), 19 count_(0),
20 array_(NULL), 20 array_(NULL),
21 lists_(NULL), 21 lists_(NULL),
22 free_list_head_(kNil), 22 free_list_head_(kNil),
23 allocator_(allocator) { 23 allocator_(allocator) {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
64 } 64 }
65 65
66 private: 66 private:
67 explicit Iterator(const BaseDirectChainedHashMap& map) 67 explicit Iterator(const BaseDirectChainedHashMap& map)
68 : map_(map), array_index_(0), list_index_(kNil) {} 68 : map_(map), array_index_(0), list_index_(kNil) {}
69 69
70 const BaseDirectChainedHashMap& map_; 70 const BaseDirectChainedHashMap& map_;
71 intptr_t array_index_; 71 intptr_t array_index_;
72 intptr_t list_index_; 72 intptr_t list_index_;
73 73
74 template<typename T, typename Bs, typename A> 74 template <typename T, typename Bs, typename A>
75 friend class BaseDirectChainedHashMap; 75 friend class BaseDirectChainedHashMap;
76 }; 76 };
77 77
78 Iterator GetIterator() const { return Iterator(*this); } 78 Iterator GetIterator() const { return Iterator(*this); }
79 79
80 protected: 80 protected:
81 // A linked list of T values. Stored in arrays. 81 // A linked list of T values. Stored in arrays.
82 struct HashMapListElement { 82 struct HashMapListElement {
83 HashMapListElement() : kv(), next(kNil) { } 83 HashMapListElement() : kv(), next(kNil) {}
84 typename KeyValueTrait::Pair kv; 84 typename KeyValueTrait::Pair kv;
85 intptr_t next; // Index in the array of the next list element. 85 intptr_t next; // Index in the array of the next list element.
86 }; 86 };
87 static const intptr_t kNil = -1; // The end of a linked list 87 static const intptr_t kNil = -1; // The end of a linked list
88 88
89 static void InitArray(HashMapListElement* array, intptr_t size) { 89 static void InitArray(HashMapListElement* array, intptr_t size) {
90 for (intptr_t i = 0; i < size; ++i) { 90 for (intptr_t i = 0; i < size; ++i) {
91 array[i] = HashMapListElement(); 91 array[i] = HashMapListElement();
92 } 92 }
93 } 93 }
94 94
95 // Must be a power of 2. 95 // Must be a power of 2.
96 static const intptr_t kInitialSize = 16; 96 static const intptr_t kInitialSize = 16;
97 97
98 void Resize(intptr_t new_size); 98 void Resize(intptr_t new_size);
99 void ResizeLists(intptr_t new_size); 99 void ResizeLists(intptr_t new_size);
100 uword Bound(uword value) const { return value & (array_size_ - 1); } 100 uword Bound(uword value) const { return value & (array_size_ - 1); }
101 101
102 intptr_t array_size_; 102 intptr_t array_size_;
103 intptr_t lists_size_; 103 intptr_t lists_size_;
104 intptr_t count_; // The number of values stored in the HashMap. 104 intptr_t count_; // The number of values stored in the HashMap.
105 HashMapListElement* array_; // Primary store - contains the first value 105 HashMapListElement* array_; // Primary store - contains the first value
106 // with a given hash. Colliding elements are stored in linked lists. 106 // with a given hash. Colliding elements are stored in linked lists.
107 HashMapListElement* lists_; // The linked lists containing hash collisions. 107 HashMapListElement* lists_; // The linked lists containing hash collisions.
108 intptr_t free_list_head_; // Unused elements in lists_ are on the free list. 108 intptr_t free_list_head_; // Unused elements in lists_ are on the free list.
109 Allocator* allocator_; 109 Allocator* allocator_;
110 }; 110 };
111 111
112 112
113 template<typename KeyValueTrait, typename B, typename Allocator> 113 template <typename KeyValueTrait, typename B, typename Allocator>
114 BaseDirectChainedHashMap<KeyValueTrait, B, Allocator>:: 114 BaseDirectChainedHashMap<KeyValueTrait, B, Allocator>::BaseDirectChainedHashMap(
115 BaseDirectChainedHashMap(const BaseDirectChainedHashMap& other) 115 const BaseDirectChainedHashMap& other)
116 : B(), 116 : B(),
117 array_size_(other.array_size_), 117 array_size_(other.array_size_),
118 lists_size_(other.lists_size_), 118 lists_size_(other.lists_size_),
119 count_(other.count_), 119 count_(other.count_),
120 array_(other.allocator_->template Alloc<HashMapListElement>( 120 array_(other.allocator_->template Alloc<HashMapListElement>(
121 other.array_size_)), 121 other.array_size_)),
122 lists_(other.allocator_->template Alloc<HashMapListElement>( 122 lists_(other.allocator_->template Alloc<HashMapListElement>(
123 other.lists_size_)), 123 other.lists_size_)),
124 free_list_head_(other.free_list_head_), 124 free_list_head_(other.free_list_head_),
125 allocator_(other.allocator_) { 125 allocator_(other.allocator_) {
126 memmove(array_, other.array_, array_size_ * sizeof(HashMapListElement)); 126 memmove(array_, other.array_, array_size_ * sizeof(HashMapListElement));
127 memmove(lists_, other.lists_, lists_size_ * sizeof(HashMapListElement)); 127 memmove(lists_, other.lists_, lists_size_ * sizeof(HashMapListElement));
128 } 128 }
129 129
130 130
131 template<typename KeyValueTrait, typename B, typename Allocator> 131 template <typename KeyValueTrait, typename B, typename Allocator>
132 typename KeyValueTrait::Pair* 132 typename KeyValueTrait::Pair*
133 BaseDirectChainedHashMap<KeyValueTrait, B, Allocator>:: 133 BaseDirectChainedHashMap<KeyValueTrait, B, Allocator>::Lookup(
134 Lookup(typename KeyValueTrait::Key key) const { 134 typename KeyValueTrait::Key key) const {
135 const typename KeyValueTrait::Value kNoValue = 135 const typename KeyValueTrait::Value kNoValue =
136 KeyValueTrait::ValueOf(typename KeyValueTrait::Pair()); 136 KeyValueTrait::ValueOf(typename KeyValueTrait::Pair());
137 137
138 uword hash = static_cast<uword>(KeyValueTrait::Hashcode(key)); 138 uword hash = static_cast<uword>(KeyValueTrait::Hashcode(key));
139 uword pos = Bound(hash); 139 uword pos = Bound(hash);
140 if (KeyValueTrait::ValueOf(array_[pos].kv) != kNoValue) { 140 if (KeyValueTrait::ValueOf(array_[pos].kv) != kNoValue) {
141 if (KeyValueTrait::IsKeyEqual(array_[pos].kv, key)) { 141 if (KeyValueTrait::IsKeyEqual(array_[pos].kv, key)) {
142 return &array_[pos].kv; 142 return &array_[pos].kv;
143 } 143 }
144 144
145 intptr_t next = array_[pos].next; 145 intptr_t next = array_[pos].next;
146 while (next != kNil) { 146 while (next != kNil) {
147 if (KeyValueTrait::IsKeyEqual(lists_[next].kv, key)) { 147 if (KeyValueTrait::IsKeyEqual(lists_[next].kv, key)) {
148 return &lists_[next].kv; 148 return &lists_[next].kv;
149 } 149 }
150 next = lists_[next].next; 150 next = lists_[next].next;
151 } 151 }
152 } 152 }
153 return NULL; 153 return NULL;
154 } 154 }
155 155
156 156
157 template<typename KeyValueTrait, typename B, typename Allocator> 157 template <typename KeyValueTrait, typename B, typename Allocator>
158 typename KeyValueTrait::Value 158 typename KeyValueTrait::Value
159 BaseDirectChainedHashMap<KeyValueTrait, B, Allocator>:: 159 BaseDirectChainedHashMap<KeyValueTrait, B, Allocator>::LookupValue(
160 LookupValue(typename KeyValueTrait::Key key) const { 160 typename KeyValueTrait::Key key) const {
161 const typename KeyValueTrait::Value kNoValue = 161 const typename KeyValueTrait::Value kNoValue =
162 KeyValueTrait::ValueOf(typename KeyValueTrait::Pair()); 162 KeyValueTrait::ValueOf(typename KeyValueTrait::Pair());
163 typename KeyValueTrait::Pair* pair = Lookup(key); 163 typename KeyValueTrait::Pair* pair = Lookup(key);
164 return (pair == NULL) ? kNoValue : KeyValueTrait::ValueOf(*pair); 164 return (pair == NULL) ? kNoValue : KeyValueTrait::ValueOf(*pair);
165 } 165 }
166 166
167 167
168 template<typename KeyValueTrait, typename B, typename Allocator> 168 template <typename KeyValueTrait, typename B, typename Allocator>
169 typename KeyValueTrait::Pair* 169 typename KeyValueTrait::Pair*
170 BaseDirectChainedHashMap<KeyValueTrait, B, Allocator>::Iterator::Next() { 170 BaseDirectChainedHashMap<KeyValueTrait, B, Allocator>::Iterator::Next() {
171 const typename KeyValueTrait::Value kNoValue = 171 const typename KeyValueTrait::Value kNoValue =
172 KeyValueTrait::ValueOf(typename KeyValueTrait::Pair()); 172 KeyValueTrait::ValueOf(typename KeyValueTrait::Pair());
173 173
174 if (array_index_ < map_.array_size_) { 174 if (array_index_ < map_.array_size_) {
175 // If we're not in the middle of a list, find the next array slot. 175 // If we're not in the middle of a list, find the next array slot.
176 if (list_index_ == kNil) { 176 if (list_index_ == kNil) {
177 while (KeyValueTrait::ValueOf(map_.array_[array_index_].kv) == kNoValue && 177 while (KeyValueTrait::ValueOf(map_.array_[array_index_].kv) == kNoValue &&
178 array_index_ < map_.array_size_) { 178 array_index_ < map_.array_size_) {
179 array_index_++; 179 array_index_++;
180 } 180 }
(...skipping 12 matching lines...) Expand all
193 // Otherwise, return the current lists_ entry, advancing list_index_. 193 // Otherwise, return the current lists_ entry, advancing list_index_.
194 intptr_t current = list_index_; 194 intptr_t current = list_index_;
195 list_index_ = map_.lists_[current].next; 195 list_index_ = map_.lists_[current].next;
196 return &map_.lists_[current].kv; 196 return &map_.lists_[current].kv;
197 } 197 }
198 198
199 return NULL; 199 return NULL;
200 } 200 }
201 201
202 202
203 template<typename KeyValueTrait, typename B, typename Allocator> 203 template <typename KeyValueTrait, typename B, typename Allocator>
204 void BaseDirectChainedHashMap<KeyValueTrait, B, Allocator>::Resize( 204 void BaseDirectChainedHashMap<KeyValueTrait, B, Allocator>::Resize(
205 intptr_t new_size) { 205 intptr_t new_size) {
206 const typename KeyValueTrait::Value kNoValue = 206 const typename KeyValueTrait::Value kNoValue =
207 KeyValueTrait::ValueOf(typename KeyValueTrait::Pair()); 207 KeyValueTrait::ValueOf(typename KeyValueTrait::Pair());
208 208
209 ASSERT(new_size > count_); 209 ASSERT(new_size > count_);
210 // Hashing the values into the new array has no more collisions than in the 210 // Hashing the values into the new array has no more collisions than in the
211 // old hash map, so we can use the existing lists_ array, if we are careful. 211 // old hash map, so we can use the existing lists_ array, if we are careful.
212 212
213 // Make sure we have at least one free element. 213 // Make sure we have at least one free element.
(...skipping 29 matching lines...) Expand all
243 Insert(old_array[i].kv); 243 Insert(old_array[i].kv);
244 } 244 }
245 } 245 }
246 } 246 }
247 USE(old_count); 247 USE(old_count);
248 ASSERT(count_ == old_count); 248 ASSERT(count_ == old_count);
249 allocator_->template Free<HashMapListElement>(old_array, old_size); 249 allocator_->template Free<HashMapListElement>(old_array, old_size);
250 } 250 }
251 251
252 252
253 template<typename KeyValueTrait, typename B, typename Allocator> 253 template <typename KeyValueTrait, typename B, typename Allocator>
254 void BaseDirectChainedHashMap<KeyValueTrait, B, Allocator>::ResizeLists( 254 void BaseDirectChainedHashMap<KeyValueTrait, B, Allocator>::ResizeLists(
255 intptr_t new_size) { 255 intptr_t new_size) {
256 ASSERT(new_size > lists_size_); 256 ASSERT(new_size > lists_size_);
257 257
258 HashMapListElement* new_lists = 258 HashMapListElement* new_lists =
259 allocator_->template Alloc<HashMapListElement>(new_size); 259 allocator_->template Alloc<HashMapListElement>(new_size);
260 InitArray(new_lists, new_size); 260 InitArray(new_lists, new_size);
261 261
262 HashMapListElement* old_lists = lists_; 262 HashMapListElement* old_lists = lists_;
263 intptr_t old_size = lists_size_; 263 intptr_t old_size = lists_size_;
264 264
265 lists_size_ = new_size; 265 lists_size_ = new_size;
266 lists_ = new_lists; 266 lists_ = new_lists;
267 267
268 if (old_lists != NULL) { 268 if (old_lists != NULL) {
269 memmove(lists_, old_lists, old_size * sizeof(HashMapListElement)); 269 memmove(lists_, old_lists, old_size * sizeof(HashMapListElement));
270 } 270 }
271 for (intptr_t i = old_size; i < lists_size_; ++i) { 271 for (intptr_t i = old_size; i < lists_size_; ++i) {
272 lists_[i].next = free_list_head_; 272 lists_[i].next = free_list_head_;
273 free_list_head_ = i; 273 free_list_head_ = i;
274 } 274 }
275 allocator_->template Free<HashMapListElement>(old_lists, old_size); 275 allocator_->template Free<HashMapListElement>(old_lists, old_size);
276 } 276 }
277 277
278 278
279 template<typename KeyValueTrait, typename B, typename Allocator> 279 template <typename KeyValueTrait, typename B, typename Allocator>
280 void BaseDirectChainedHashMap<KeyValueTrait, B, Allocator>:: 280 void BaseDirectChainedHashMap<KeyValueTrait, B, Allocator>::Insert(
281 Insert(typename KeyValueTrait::Pair kv) { 281 typename KeyValueTrait::Pair kv) {
282 const typename KeyValueTrait::Value kNoValue = 282 const typename KeyValueTrait::Value kNoValue =
283 KeyValueTrait::ValueOf(typename KeyValueTrait::Pair()); 283 KeyValueTrait::ValueOf(typename KeyValueTrait::Pair());
284 284
285 ASSERT(KeyValueTrait::ValueOf(kv) != kNoValue); 285 ASSERT(KeyValueTrait::ValueOf(kv) != kNoValue);
286 // Resizing when half of the hashtable is filled up. 286 // Resizing when half of the hashtable is filled up.
287 if (count_ >= array_size_ >> 1) Resize(array_size_ << 1); 287 if (count_ >= array_size_ >> 1) Resize(array_size_ << 1);
288 ASSERT(count_ < array_size_); 288 ASSERT(count_ < array_size_);
289 count_++; 289 count_++;
290 uword pos = Bound( 290 uword pos = Bound(
291 static_cast<uword>(KeyValueTrait::Hashcode(KeyValueTrait::KeyOf(kv)))); 291 static_cast<uword>(KeyValueTrait::Hashcode(KeyValueTrait::KeyOf(kv))));
292 if (KeyValueTrait::ValueOf(array_[pos].kv) == kNoValue) { 292 if (KeyValueTrait::ValueOf(array_[pos].kv) == kNoValue) {
293 array_[pos].kv = kv; 293 array_[pos].kv = kv;
294 array_[pos].next = kNil; 294 array_[pos].next = kNil;
295 } else { 295 } else {
296 if (free_list_head_ == kNil) { 296 if (free_list_head_ == kNil) {
297 ResizeLists(lists_size_ << 1); 297 ResizeLists(lists_size_ << 1);
298 } 298 }
299 intptr_t new_element_pos = free_list_head_; 299 intptr_t new_element_pos = free_list_head_;
300 ASSERT(new_element_pos != kNil); 300 ASSERT(new_element_pos != kNil);
301 free_list_head_ = lists_[free_list_head_].next; 301 free_list_head_ = lists_[free_list_head_].next;
302 lists_[new_element_pos].kv = kv; 302 lists_[new_element_pos].kv = kv;
303 lists_[new_element_pos].next = array_[pos].next; 303 lists_[new_element_pos].next = array_[pos].next;
304 ASSERT(array_[pos].next == kNil || 304 ASSERT(array_[pos].next == kNil ||
305 KeyValueTrait::ValueOf(lists_[array_[pos].next].kv) != kNoValue); 305 KeyValueTrait::ValueOf(lists_[array_[pos].next].kv) != kNoValue);
306 array_[pos].next = new_element_pos; 306 array_[pos].next = new_element_pos;
307 } 307 }
308 } 308 }
309 309
310 310
311 template<typename KeyValueTrait> 311 template <typename KeyValueTrait>
312 class DirectChainedHashMap 312 class DirectChainedHashMap
313 : public BaseDirectChainedHashMap<KeyValueTrait, ValueObject> { 313 : public BaseDirectChainedHashMap<KeyValueTrait, ValueObject> {
314 public: 314 public:
315 DirectChainedHashMap() : BaseDirectChainedHashMap<KeyValueTrait, ValueObject>( 315 DirectChainedHashMap()
316 ASSERT_NOTNULL(Thread::Current()->zone())) {} 316 : BaseDirectChainedHashMap<KeyValueTrait, ValueObject>(
317 ASSERT_NOTNULL(Thread::Current()->zone())) {}
317 }; 318 };
318 319
319 320
320 template<typename KeyValueTrait> 321 template <typename KeyValueTrait>
321 class MallocDirectChainedHashMap 322 class MallocDirectChainedHashMap
322 : public BaseDirectChainedHashMap<KeyValueTrait, EmptyBase, Malloc> { 323 : public BaseDirectChainedHashMap<KeyValueTrait, EmptyBase, Malloc> {
323 public: 324 public:
324 MallocDirectChainedHashMap() 325 MallocDirectChainedHashMap()
325 : BaseDirectChainedHashMap<KeyValueTrait, EmptyBase, Malloc>(NULL) {} 326 : BaseDirectChainedHashMap<KeyValueTrait, EmptyBase, Malloc>(NULL) {}
326 }; 327 };
327 328
328 329
329 template<typename T> 330 template <typename T>
330 class PointerKeyValueTrait { 331 class PointerKeyValueTrait {
331 public: 332 public:
332 typedef T* Value; 333 typedef T* Value;
333 typedef T* Key; 334 typedef T* Key;
334 typedef T* Pair; 335 typedef T* Pair;
335 336
336 static Key KeyOf(Pair kv) { 337 static Key KeyOf(Pair kv) { return kv; }
337 return kv;
338 }
339 338
340 static Value ValueOf(Pair kv) { 339 static Value ValueOf(Pair kv) { return kv; }
341 return kv;
342 }
343 340
344 static inline intptr_t Hashcode(Key key) { 341 static inline intptr_t Hashcode(Key key) { return key->Hashcode(); }
345 return key->Hashcode();
346 }
347 342
348 static inline bool IsKeyEqual(Pair kv, Key key) { 343 static inline bool IsKeyEqual(Pair kv, Key key) { return kv->Equals(key); }
349 return kv->Equals(key);
350 }
351 }; 344 };
352 345
353 346
354 template<typename T> 347 template <typename T>
355 class NumbersKeyValueTrait { 348 class NumbersKeyValueTrait {
356 public: 349 public:
357 typedef T Value; 350 typedef T Value;
358 typedef intptr_t Key; 351 typedef intptr_t Key;
359 typedef T Pair; 352 typedef T Pair;
360 353
361 static intptr_t KeyOf(Pair kv) { return kv.first(); } 354 static intptr_t KeyOf(Pair kv) { return kv.first(); }
362 static T ValueOf(Pair kv) { return kv; } 355 static T ValueOf(Pair kv) { return kv; }
363 static inline intptr_t Hashcode(Key key) { return key; } 356 static inline intptr_t Hashcode(Key key) { return key; }
364 static inline bool IsKeyEqual(Pair kv, Key key) { return kv.first() == key; } 357 static inline bool IsKeyEqual(Pair kv, Key key) { return kv.first() == key; }
365 }; 358 };
366 359
367 360
368 template<typename K, typename V> 361 template <typename K, typename V>
369 class RawPointerKeyValueTrait { 362 class RawPointerKeyValueTrait {
370 public: 363 public:
371 typedef K* Key; 364 typedef K* Key;
372 typedef V Value; 365 typedef V Value;
373 366
374 struct Pair { 367 struct Pair {
375 Key key; 368 Key key;
376 Value value; 369 Value value;
377 Pair() : key(NULL), value() {} 370 Pair() : key(NULL), value() {}
378 Pair(const Key key, const Value& value) : key(key), value(value) {} 371 Pair(const Key key, const Value& value) : key(key), value(value) {}
379 Pair(const Pair& other) : key(other.key), value(other.value) {} 372 Pair(const Pair& other) : key(other.key), value(other.value) {}
380 }; 373 };
381 374
382 static Key KeyOf(Pair kv) { return kv.key; } 375 static Key KeyOf(Pair kv) { return kv.key; }
383 static Value ValueOf(Pair kv) { return kv.value; } 376 static Value ValueOf(Pair kv) { return kv.value; }
384 static intptr_t Hashcode(Key key) { return reinterpret_cast<intptr_t>(key); } 377 static intptr_t Hashcode(Key key) { return reinterpret_cast<intptr_t>(key); }
385 static bool IsKeyEqual(Pair kv, Key key) { return kv.key == key; } 378 static bool IsKeyEqual(Pair kv, Key key) { return kv.key == key; }
386 }; 379 };
387 380
388 } // namespace dart 381 } // namespace dart
389 382
390 #endif // RUNTIME_VM_HASH_MAP_H_ 383 #endif // RUNTIME_VM_HASH_MAP_H_
OLDNEW
« no previous file with comments | « runtime/vm/handles_impl.h ('k') | runtime/vm/hash_map_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698