5#ifndef V8_BASE_HASHMAP_H_
6#define V8_BASE_HASHMAP_H_
24 template <
typename T,
typename TypeTag = T[]>
26 return static_cast<T*
>(
base::Malloc(length *
sizeof(T)));
28 template <
typename T,
typename TypeTag = T[]>
34template <
typename Key,
typename Value,
class MatchFun,
class AllocationPolicy>
47 MatchFun match = MatchFun(),
48 AllocationPolicy allocator = AllocationPolicy());
55 AllocationPolicy allocator = AllocationPolicy());
76 template <
typename Func>
89 template <
typename LookupKey,
typename KeyFunc,
typename ValueFunc>
91 const KeyFunc& key_func,
const ValueFunc& value_func);
136 template <
typename LookupKey>
150 struct Impl :
private MatchFun,
private AllocationPolicy {
152 : MatchFun(
std::move(
match)), AllocationPolicy(
std::move(allocator)) {}
160 MatchFun::operator=(std::move(other));
161 AllocationPolicy::operator=(std::move(other));
166 other.map_ =
nullptr;
168 other.occupancy_ = 0;
172 const MatchFun&
match()
const {
return *
this; }
175 const AllocationPolicy&
allocator()
const {
return *
this; }
183template <
typename Key,
typename Value,
typename MatchFun,
184 class AllocationPolicy>
187 AllocationPolicy allocator)
192template <
typename Key,
typename Value,
typename MatchFun,
193 class AllocationPolicy>
196 AllocationPolicy allocator)
204template <
typename Key,
typename Value,
typename MatchFun,
205 class AllocationPolicy>
207 AllocationPolicy>::~TemplateHashMapImpl() {
211template <
typename Key,
typename Value,
typename MatchFun,
212 class AllocationPolicy>
215 const Key&
key, uint32_t
hash)
const {
217 return entry->
exists() ? entry :
nullptr;
220template <
typename Key,
typename Value,
typename MatchFun,
221 class AllocationPolicy>
224 const Key&
key, uint32_t
hash) {
225 return LookupOrInsert(
key,
hash, []() {
return Value(); });
228template <
typename Key,
typename Value,
typename MatchFun,
229 class AllocationPolicy>
230template <
typename Func>
233 const Key&
key, uint32_t
hash,
const Func& value_func) {
234 return LookupOrInsert(
238template <
typename Key,
typename Value,
typename MatchFun,
239 class AllocationPolicy>
240template <
typename LookupKey,
typename KeyFunc,
typename ValueFunc>
243 const LookupKey& lookup_key, uint32_t
hash,
const KeyFunc& key_func,
244 const ValueFunc& value_func) {
251 return FillEmptyEntry(entry, key_func(), value_func(),
hash);
254template <
typename Key,
typename Value,
typename MatchFun,
255 class AllocationPolicy>
258 const Key&
key, uint32_t
hash) {
263template <
typename Key,
typename Value,
typename MatchFun,
264 class AllocationPolicy>
266 const Key&
key, uint32_t
hash) {
289 DCHECK(occupancy() < capacity());
296 if (q == map_end()) {
325template <
typename Key,
typename Value,
typename MatchFun,
326 class AllocationPolicy>
329 for (
size_t i = 0;
i < capacity(); ++
i) {
332 impl_.occupancy_ = 0;
335template <
typename Key,
typename Value,
typename MatchFun,
336 class AllocationPolicy>
339 return Next(
impl_.map_ - 1);
342template <
typename Key,
typename Value,
typename MatchFun,
343 class AllocationPolicy>
346 Entry* entry)
const {
349 for (entry++; entry <
end; entry++) {
357template <
typename Key,
typename Value,
typename MatchFun,
358 class AllocationPolicy>
359template <
typename LookupKey>
362 const LookupKey&
key, uint32_t
hash)
const {
364 size_t i =
hash & (capacity() - 1);
367 DCHECK(occupancy() < capacity());
369 while (map[
i].exists() &&
371 i = (
i + 1) & (capacity() - 1);
377template <
typename Key,
typename Value,
typename MatchFun,
378 class AllocationPolicy>
388 if (occupancy() + occupancy() / 4 >= capacity()) {
396template <
typename Key,
typename Value,
typename MatchFun,
397 class AllocationPolicy>
401 impl_.map_ =
impl_.allocator().template AllocateArray<Entry>(capacity);
402 if (
impl_.map_ ==
nullptr) {
403 FATAL(
"Out of memory: HashMap::Initialize");
406 impl_.capacity_ = capacity;
410template <
typename Key,
typename Value,
typename MatchFun,
411 class AllocationPolicy>
414 uint32_t old_capacity = capacity();
415 uint32_t n = occupancy();
418 Initialize(capacity() * 2);
421 for (
Entry* entry = old_map; n > 0; entry++) {
422 if (entry->exists()) {
423 Entry* new_entry = Probe(entry->key, entry->hash);
425 FillEmptyEntry(new_entry, entry->
key, entry->value, entry->hash);
431 impl_.allocator().DeleteArray(old_map, old_capacity);
436template <
typename Key,
typename MatchFun>
440 bool operator()(uint32_t hash1, uint32_t hash2,
const Key& key1,
441 const Key& key2)
const {
442 return hash1 == hash2 &&
match_(key1, key2);
450template <
typename AllocationPolicy>
454 HashEqualityThenKeyMatcher<void*, bool (*)(void*, void*)>,
465 AllocationPolicy allocator = AllocationPolicy())
471 AllocationPolicy allocator = AllocationPolicy())
472 :
Base(original, allocator) {}
484template <
typename Key>
486 bool operator()(uint32_t hash1, uint32_t hash2,
const Key& key1,
487 const Key& key2)
const {
493template <
typename AllocationPolicy>
503 AllocationPolicy allocator = AllocationPolicy())
507 AllocationPolicy allocator = AllocationPolicy())
508 :
Base(&other, allocator) {}
511 :
Base(std::move(other)) {}
515 static_cast<Base&
>(*this) = std::move(other);
523template <
class Key,
class Value,
class MatchFun,
class AllocationPolicy>
526 HashEqualityThenKeyMatcher<void*, MatchFun>,
533 static_assert(
sizeof(Key*) ==
sizeof(
void*));
534 static_assert(
sizeof(
Value*) ==
sizeof(
void*));
561 AllocationPolicy allocator = AllocationPolicy())
bool(*)(void *, void *) MatchFun
CustomMatcherTemplateHashMapImpl(MatchFun match, uint32_t capacity=Base::kDefaultHashMapCapacity, AllocationPolicy allocator=AllocationPolicy())
CustomMatcherTemplateHashMapImpl(const CustomMatcherTemplateHashMapImpl *original, AllocationPolicy allocator=AllocationPolicy())
CustomMatcherTemplateHashMapImpl & operator=(const CustomMatcherTemplateHashMapImpl &)=delete
CustomMatcherTemplateHashMapImpl(const CustomMatcherTemplateHashMapImpl &)=delete
V8_INLINE T * AllocateArray(size_t length)
V8_INLINE void DeleteArray(T *p, size_t length)
TemplateHashMapImpl< void *, void *, KeyEqualityMatcher< void * >, AllocationPolicy > Base
PointerTemplateHashMapImpl(uint32_t capacity=Base::kDefaultHashMapCapacity, AllocationPolicy allocator=AllocationPolicy())
PointerTemplateHashMapImpl(const PointerTemplateHashMapImpl &other, AllocationPolicy allocator=AllocationPolicy())
PointerTemplateHashMapImpl & operator=(PointerTemplateHashMapImpl &&other) V8_NOEXCEPT
PointerTemplateHashMapImpl(PointerTemplateHashMapImpl &&other) V8_NOEXCEPT
Entry * LookupOrInsert(const Key &key, uint32_t hash, const Func &value_func)
Entry * LookupOrInsert(const LookupKey &lookup_key, uint32_t hash, const KeyFunc &key_func, const ValueFunc &value_func)
Entry * Next(Entry *entry) const
static const uint32_t kDefaultHashMapCapacity
Entry * Probe(const LookupKey &key, uint32_t hash) const
TemplateHashMapImpl(uint32_t capacity=kDefaultHashMapCapacity, MatchFun match=MatchFun(), AllocationPolicy allocator=AllocationPolicy())
TemplateHashMapImpl & operator=(const TemplateHashMapImpl &)=delete
uint32_t occupancy() const
v8::base::TemplateHashMapImpl::Impl impl_
AllocationPolicy allocator() const
Entry * LookupOrInsert(const Key &key, uint32_t hash)
Value Remove(const Key &key, uint32_t hash)
uint32_t capacity() const
Entry * Lookup(const Key &key, uint32_t hash) const
TemplateHashMapImpl(const TemplateHashMapImpl &)=delete
TemplateHashMapImpl & operator=(TemplateHashMapImpl &&other) V8_NOEXCEPT=default
Entry * InsertNew(const Key &key, uint32_t hash)
TemplateHashMapImpl(const TemplateHashMapImpl *original, AllocationPolicy allocator=AllocationPolicy())
void Initialize(uint32_t capacity)
Entry * FillEmptyEntry(Entry *entry, const Key &key, const Value &value, uint32_t hash)
TemplateHashMapImpl(TemplateHashMapImpl &&other) V8_NOEXCEPT=default
bool operator!=(const Iterator &other)
Iterator(const Base *map, typename Base::Entry *entry)
value_type * operator->()
TemplateHashMap(MatchFun match, AllocationPolicy allocator=AllocationPolicy())
Iterator find(Key *key, bool insert=false)
constexpr bool IsPowerOfTwo(T value)
void * Malloc(size_t size)
#define DCHECK_NOT_NULL(val)
#define DCHECK(condition)
bool operator()(uint32_t hash1, uint32_t hash2, const Key &key1, const Key &key2) const
HashEqualityThenKeyMatcher(MatchFun match)
bool operator()(uint32_t hash1, uint32_t hash2, const Key &key1, const Key &key2) const
Impl & operator=(Impl &&other) V8_NOEXCEPT
const AllocationPolicy & allocator() const
Impl(MatchFun match, AllocationPolicy allocator)
Impl(const Impl &) V8_NOEXCEPT=default
Impl(Impl &&other) V8_NOEXCEPT
Impl & operator=(const Impl &other) V8_NOEXCEPT=default
const MatchFun & match() const
AllocationPolicy & allocator()
std::unique_ptr< ValueMirror > value
std::unique_ptr< ValueMirror > key