|  | // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file | 
|  | // for details. All rights reserved. Use of this source code is governed by a | 
|  | // BSD-style license that can be found in the LICENSE file. | 
|  |  | 
|  | #ifndef RUNTIME_PLATFORM_HASHMAP_H_ | 
|  | #define RUNTIME_PLATFORM_HASHMAP_H_ | 
|  |  | 
|  | #include "platform/globals.h" | 
|  |  | 
|  | namespace dart { | 
|  |  | 
|  | class HashMap { | 
|  | public: | 
|  | typedef bool (*MatchFun)(void* key1, void* key2); | 
|  |  | 
|  | typedef void (*ClearFun)(void* value); | 
|  |  | 
|  | // initial_capacity is the size of the initial hash map; | 
|  | // it must be a power of 2 (and thus must not be 0). | 
|  | HashMap(MatchFun match, uint32_t initial_capacity); | 
|  |  | 
|  | ~HashMap(); | 
|  |  | 
|  | static bool SamePointerValue(void* key1, void* key2) { return key1 == key2; } | 
|  |  | 
|  | static uint32_t StringHash(char* key) { | 
|  | uint32_t hash_ = 0; | 
|  | if (key == NULL) return hash_; | 
|  | int len = strlen(key); | 
|  | for (int i = 0; i < len; i++) { | 
|  | hash_ += key[i]; | 
|  | hash_ += hash_ << 10; | 
|  | hash_ ^= hash_ >> 6; | 
|  | } | 
|  | hash_ += hash_ << 3; | 
|  | hash_ ^= hash_ >> 11; | 
|  | hash_ += hash_ << 15; | 
|  | return hash_ == 0 ? 1 : hash_; | 
|  | } | 
|  |  | 
|  | static bool SameStringValue(void* key1, void* key2) { | 
|  | return strcmp(reinterpret_cast<char*>(key1), | 
|  | reinterpret_cast<char*>(key2)) == 0; | 
|  | } | 
|  |  | 
|  | // HashMap entries are (key, value, hash) triplets. | 
|  | // Some clients may not need to use the value slot | 
|  | // (e.g. implementers of sets, where the key is the value). | 
|  | struct Entry { | 
|  | Entry() : key(NULL), value(NULL), hash(0) {} | 
|  | void* key; | 
|  | void* value; | 
|  | uint32_t hash;  // The full hash value for key. | 
|  | }; | 
|  |  | 
|  | // If an entry with matching key is found, Lookup() | 
|  | // returns that entry. If no matching entry is found, | 
|  | // but insert is set, a new entry is inserted with | 
|  | // corresponding key, key hash, and NULL value. | 
|  | // Otherwise, NULL is returned. | 
|  | Entry* Lookup(void* key, uint32_t hash, bool insert); | 
|  |  | 
|  | // Removes the entry with matching key. | 
|  | // | 
|  | // WARNING: This method cannot be called while iterating a `HashMap` | 
|  | // otherwise the iteration might step over elements! | 
|  | void Remove(void* key, uint32_t hash); | 
|  |  | 
|  | // Empties the hash map (occupancy() == 0), and calls the function 'clear' on | 
|  | // each of the values if given. | 
|  | void Clear(ClearFun clear = NULL); | 
|  |  | 
|  | // The number of entries stored in the table. | 
|  | intptr_t size() const { return occupancy_; } | 
|  |  | 
|  | // The capacity of the table. The implementation | 
|  | // makes sure that occupancy is at most 80% of | 
|  | // the table capacity. | 
|  | intptr_t capacity() const { return capacity_; } | 
|  |  | 
|  | // Iteration | 
|  | // | 
|  | // for (Entry* p = map.Start(); p != NULL; p = map.Next(p)) { | 
|  | //   ... | 
|  | // } | 
|  | // | 
|  | // If entries are inserted during iteration, the effect of | 
|  | // calling Next() is undefined. | 
|  | Entry* Start() const; | 
|  | Entry* Next(Entry* p) const; | 
|  |  | 
|  | private: | 
|  | MatchFun match_; | 
|  | Entry* map_; | 
|  | uint32_t capacity_; | 
|  | uint32_t occupancy_; | 
|  |  | 
|  | Entry* map_end() const { return map_ + capacity_; } | 
|  | Entry* Probe(void* key, uint32_t hash); | 
|  | void Initialize(uint32_t capacity); | 
|  | void Resize(); | 
|  |  | 
|  | friend class IntSet;  // From hashmap_test.cc | 
|  | DISALLOW_COPY_AND_ASSIGN(HashMap); | 
|  | }; | 
|  |  | 
|  | }  // namespace dart | 
|  |  | 
|  | #endif  // RUNTIME_PLATFORM_HASHMAP_H_ |