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

Unified Diff: runtime/vm/hash_map.h

Issue 2083103002: Remove some uses of STL map. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 6 months 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/freelist.cc ('k') | runtime/vm/hash_map_test.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/hash_map.h
diff --git a/runtime/vm/hash_map.h b/runtime/vm/hash_map.h
index f2caa9e627d2ff68033af10773c7a9c544b3ba09..372ff7f38c94607ea90ca4e63ad7c66323e7479c 100644
--- a/runtime/vm/hash_map.h
+++ b/runtime/vm/hash_map.h
@@ -5,28 +5,39 @@
#ifndef VM_HASH_MAP_H_
#define VM_HASH_MAP_H_
+#include "vm/growable_array.h" // For Malloc, EmptyBase
#include "vm/zone.h"
namespace dart {
-template <typename KeyValueTrait>
-class DirectChainedHashMap: public ValueObject {
+template<typename KeyValueTrait, typename B, typename Allocator = Zone>
+class BaseDirectChainedHashMap : public B {
public:
- DirectChainedHashMap() : array_size_(0),
- lists_size_(0),
- count_(0),
- array_(NULL),
- lists_(NULL),
- free_list_head_(kNil) {
+ explicit BaseDirectChainedHashMap(Allocator* allocator)
+ : array_size_(0),
+ lists_size_(0),
+ count_(0),
+ array_(NULL),
+ lists_(NULL),
+ free_list_head_(kNil),
+ allocator_(allocator) {
ResizeLists(kInitialSize);
Resize(kInitialSize);
}
- DirectChainedHashMap(const DirectChainedHashMap& other);
+ BaseDirectChainedHashMap(const BaseDirectChainedHashMap& other);
+
+ ~BaseDirectChainedHashMap() {
+ allocator_->template Free<HashMapListElement>(array_, array_size_);
+ allocator_->template Free<HashMapListElement>(lists_, lists_size_);
+ }
void Insert(typename KeyValueTrait::Pair kv);
- typename KeyValueTrait::Value Lookup(typename KeyValueTrait::Key key) const;
+ typename KeyValueTrait::Value LookupValue(
+ typename KeyValueTrait::Key key) const;
+
+ typename KeyValueTrait::Pair* Lookup(typename KeyValueTrait::Key key) const;
bool IsEmpty() const { return count_ == 0; }
@@ -43,6 +54,29 @@ class DirectChainedHashMap: public ValueObject {
}
}
+ class Iterator {
+ public:
+ typename KeyValueTrait::Pair* Next();
+
+ void Reset() {
+ array_index_ = 0;
+ list_index_ = kNil;
+ }
+
+ private:
+ explicit Iterator(const BaseDirectChainedHashMap& map)
+ : map_(map), array_index_(0), list_index_(kNil) {}
+
+ const BaseDirectChainedHashMap& map_;
+ intptr_t array_index_;
+ intptr_t list_index_;
+
+ template<typename T, typename Bs, typename A>
+ friend class BaseDirectChainedHashMap;
+ };
+
+ Iterator GetIterator() const { return Iterator(*this); }
+
protected:
// A linked list of T values. Stored in arrays.
struct HashMapListElement {
@@ -72,12 +106,31 @@ class DirectChainedHashMap: public ValueObject {
// with a given hash. Colliding elements are stored in linked lists.
HashMapListElement* lists_; // The linked lists containing hash collisions.
intptr_t free_list_head_; // Unused elements in lists_ are on the free list.
+ Allocator* allocator_;
};
-template <typename KeyValueTrait>
-typename KeyValueTrait::Value
- DirectChainedHashMap<KeyValueTrait>::
+template<typename KeyValueTrait, typename B, typename Allocator>
+BaseDirectChainedHashMap<KeyValueTrait, B, Allocator>::
+ BaseDirectChainedHashMap(const BaseDirectChainedHashMap& other)
+ : B(),
+ array_size_(other.array_size_),
+ lists_size_(other.lists_size_),
+ count_(other.count_),
+ array_(other.allocator_->template Alloc<HashMapListElement>(
+ other.array_size_)),
+ lists_(other.allocator_->template Alloc<HashMapListElement>(
+ other.lists_size_)),
+ free_list_head_(other.free_list_head_),
+ allocator_(other.allocator_) {
+ memmove(array_, other.array_, array_size_ * sizeof(HashMapListElement));
+ memmove(lists_, other.lists_, lists_size_ * sizeof(HashMapListElement));
+}
+
+
+template<typename KeyValueTrait, typename B, typename Allocator>
+typename KeyValueTrait::Pair*
+ BaseDirectChainedHashMap<KeyValueTrait, B, Allocator>::
Lookup(typename KeyValueTrait::Key key) const {
const typename KeyValueTrait::Value kNoValue =
KeyValueTrait::ValueOf(typename KeyValueTrait::Pair());
@@ -86,40 +139,69 @@ typename KeyValueTrait::Value
uword pos = Bound(hash);
if (KeyValueTrait::ValueOf(array_[pos].kv) != kNoValue) {
if (KeyValueTrait::IsKeyEqual(array_[pos].kv, key)) {
- return KeyValueTrait::ValueOf(array_[pos].kv);
+ return &array_[pos].kv;
}
intptr_t next = array_[pos].next;
while (next != kNil) {
if (KeyValueTrait::IsKeyEqual(lists_[next].kv, key)) {
- return KeyValueTrait::ValueOf(lists_[next].kv);
+ return &lists_[next].kv;
}
next = lists_[next].next;
}
}
- return kNoValue;
+ return NULL;
}
-template <typename KeyValueTrait>
-DirectChainedHashMap<KeyValueTrait>::
- DirectChainedHashMap(const DirectChainedHashMap& other)
- : ValueObject(),
- array_size_(other.array_size_),
- lists_size_(other.lists_size_),
- count_(other.count_),
- array_(Thread::Current()->zone()->
- Alloc<HashMapListElement>(other.array_size_)),
- lists_(Thread::Current()->zone()->
- Alloc<HashMapListElement>(other.lists_size_)),
- free_list_head_(other.free_list_head_) {
- memmove(array_, other.array_, array_size_ * sizeof(HashMapListElement));
- memmove(lists_, other.lists_, lists_size_ * sizeof(HashMapListElement));
+template<typename KeyValueTrait, typename B, typename Allocator>
+typename KeyValueTrait::Value
+ BaseDirectChainedHashMap<KeyValueTrait, B, Allocator>::
+ LookupValue(typename KeyValueTrait::Key key) const {
+ const typename KeyValueTrait::Value kNoValue =
+ KeyValueTrait::ValueOf(typename KeyValueTrait::Pair());
+ typename KeyValueTrait::Pair* pair = Lookup(key);
+ return (pair == NULL) ? kNoValue : KeyValueTrait::ValueOf(*pair);
}
-template <typename KeyValueTrait>
-void DirectChainedHashMap<KeyValueTrait>::Resize(intptr_t new_size) {
+template<typename KeyValueTrait, typename B, typename Allocator>
+typename KeyValueTrait::Pair*
+ BaseDirectChainedHashMap<KeyValueTrait, B, Allocator>::Iterator::Next() {
+ const typename KeyValueTrait::Pair kNoPair = typename KeyValueTrait::Pair();
+
+ if (array_index_ < map_.array_size_) {
+ // If we're not in the middle of a list, find the next array slot.
+ if (list_index_ == kNil) {
+ while ((map_.array_[array_index_].kv == kNoPair) &&
+ (array_index_ < map_.array_size_)) {
+ array_index_++;
+ }
+ if (array_index_ < map_.array_size_) {
+ // When we're done with the list, we'll continue with the next array
+ // slot.
+ const intptr_t old_array_index = array_index_;
+ array_index_++;
+ list_index_ = map_.array_[old_array_index].next;
+ return &map_.array_[old_array_index].kv;
+ } else {
+ return NULL;
+ }
+ }
+
+ // Otherwise, return the current lists_ entry, advancing list_index_.
+ intptr_t current = list_index_;
+ list_index_ = map_.lists_[current].next;
+ return &map_.lists_[current].kv;
+ }
+
+ return NULL;
+}
+
+
+template<typename KeyValueTrait, typename B, typename Allocator>
+void BaseDirectChainedHashMap<KeyValueTrait, B, Allocator>::Resize(
+ intptr_t new_size) {
const typename KeyValueTrait::Value kNoValue =
KeyValueTrait::ValueOf(typename KeyValueTrait::Pair());
@@ -133,7 +215,7 @@ void DirectChainedHashMap<KeyValueTrait>::Resize(intptr_t new_size) {
}
HashMapListElement* new_array =
- Thread::Current()->zone()->Alloc<HashMapListElement>(new_size);
+ allocator_->template Alloc<HashMapListElement>(new_size);
InitArray(new_array, new_size);
HashMapListElement* old_array = array_;
@@ -163,16 +245,17 @@ void DirectChainedHashMap<KeyValueTrait>::Resize(intptr_t new_size) {
}
USE(old_count);
ASSERT(count_ == old_count);
+ allocator_->template Free<HashMapListElement>(old_array, old_size);
}
-template <typename T>
-void DirectChainedHashMap<T>::ResizeLists(intptr_t new_size) {
+template<typename KeyValueTrait, typename B, typename Allocator>
+void BaseDirectChainedHashMap<KeyValueTrait, B, Allocator>::ResizeLists(
+ intptr_t new_size) {
ASSERT(new_size > lists_size_);
HashMapListElement* new_lists =
- Thread::Current()->zone()->
- Alloc<HashMapListElement>(new_size);
+ allocator_->template Alloc<HashMapListElement>(new_size);
InitArray(new_lists, new_size);
HashMapListElement* old_lists = lists_;
@@ -188,11 +271,12 @@ void DirectChainedHashMap<T>::ResizeLists(intptr_t new_size) {
lists_[i].next = free_list_head_;
free_list_head_ = i;
}
+ allocator_->template Free<HashMapListElement>(old_lists, old_size);
}
-template <typename KeyValueTrait>
-void DirectChainedHashMap<KeyValueTrait>::
+template<typename KeyValueTrait, typename B, typename Allocator>
+void BaseDirectChainedHashMap<KeyValueTrait, B, Allocator>::
Insert(typename KeyValueTrait::Pair kv) {
const typename KeyValueTrait::Value kNoValue =
KeyValueTrait::ValueOf(typename KeyValueTrait::Pair());
@@ -223,6 +307,24 @@ void DirectChainedHashMap<KeyValueTrait>::
}
+template<typename KeyValueTrait>
+class DirectChainedHashMap
+ : public BaseDirectChainedHashMap<KeyValueTrait, ValueObject> {
+ public:
+ DirectChainedHashMap() : BaseDirectChainedHashMap<KeyValueTrait, ValueObject>(
+ ASSERT_NOTNULL(Thread::Current()->zone())) {}
+};
+
+
+template<typename KeyValueTrait>
+class MallocDirectChainedHashMap
+ : public BaseDirectChainedHashMap<KeyValueTrait, EmptyBase, Malloc> {
+ public:
+ MallocDirectChainedHashMap()
+ : BaseDirectChainedHashMap<KeyValueTrait, EmptyBase, Malloc>(NULL) {}
+};
+
+
template<typename T>
class PointerKeyValueTrait {
public:
@@ -247,6 +349,20 @@ class PointerKeyValueTrait {
}
};
+
+template<typename T>
+class NumbersKeyValueTrait {
+ public:
+ typedef T Value;
+ typedef intptr_t Key;
+ typedef T Pair;
+
+ static intptr_t KeyOf(Pair kv) { return kv.first(); }
+ static T ValueOf(Pair kv) { return kv; }
+ static inline intptr_t Hashcode(Key key) { return key; }
+ static inline bool IsKeyEqual(Pair kv, Key key) { return kv.first() == key; }
+};
+
} // namespace dart
#endif // VM_HASH_MAP_H_
« no previous file with comments | « runtime/vm/freelist.cc ('k') | runtime/vm/hash_map_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698