diff options
| author | gingerBill <bill@gingerbill.org> | 2023-01-14 13:23:17 +0000 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2023-01-14 13:23:17 +0000 |
| commit | 518f30e52307e12fe184c34f0da8f197b976ced5 (patch) | |
| tree | 3f5db726b8ece6f07b7c1147c56f954615048765 /src/ptr_map.cpp | |
| parent | 868aa4c14ab6c63b9b797f4a8178c73b69897711 (diff) | |
Bring `PtrMap` inline with `StringMap`
Diffstat (limited to 'src/ptr_map.cpp')
| -rw-r--r-- | src/ptr_map.cpp | 175 |
1 files changed, 94 insertions, 81 deletions
diff --git a/src/ptr_map.cpp b/src/ptr_map.cpp index 598904906..0a5c1e492 100644 --- a/src/ptr_map.cpp +++ b/src/ptr_map.cpp @@ -2,6 +2,13 @@ typedef u32 MapIndex; +enum { + MAP_CACHE_LINE_SIZE_POW = 6, + MAP_CACHE_LINE_SIZE = 1<<MAP_CACHE_LINE_SIZE_POW, + MAP_CACHE_LINE_MASK = MAP_CACHE_LINE_SIZE-1, +}; + + struct MapFindResult { MapIndex hash_index; MapIndex entry_prev; @@ -21,8 +28,11 @@ struct PtrMapEntry { template <typename K, typename V> struct PtrMap { - Slice<MapIndex> hashes; - Array<PtrMapEntry<K, V> > entries; + MapIndex * hashes; + usize hashes_count; + PtrMapEntry<K, V> *entries; + u32 count; + u32 entries_capacity; }; @@ -78,42 +88,48 @@ gb_internal gbAllocator map_allocator(void) { template <typename K, typename V> gb_internal gb_inline void map_init(PtrMap<K, V> *h, isize capacity) { capacity = next_pow2_isize(capacity); - slice_init(&h->hashes, map_allocator(), capacity); - array_init(&h->entries, map_allocator(), 0, capacity); - for (isize i = 0; i < capacity; i++) { - h->hashes.data[i] = MAP_SENTINEL; - } + map_reserve(h, capacity); } template <typename K, typename V> gb_internal gb_inline void map_destroy(PtrMap<K, V> *h) { - if (h->entries.allocator.proc == nullptr) { - h->entries.allocator = map_allocator(); - } - slice_free(&h->hashes, h->entries.allocator); - array_free(&h->entries); + gbAllocator a = map_allocator(); + gb_free(a, h->hashes); + gb_free(a, h->entries); } template <typename K, typename V> +gb_internal void map__resize_hashes(PtrMap<K, V> *h, usize count) { + h->hashes_count = cast(u32)resize_array_raw(&h->hashes, string_map_allocator(), h->hashes_count, count, MAP_CACHE_LINE_SIZE); +} + +template <typename K, typename V> +gb_internal void map__reserve_entries(PtrMap<K, V> *h, usize capacity) { + h->entries_capacity = cast(u32)resize_array_raw(&h->entries, string_map_allocator(), h->entries_capacity, capacity, MAP_CACHE_LINE_SIZE); +} + + +template <typename K, typename V> gb_internal MapIndex map__add_entry(PtrMap<K, V> *h, K key) { PtrMapEntry<K, V> e = {}; e.key = key; e.next = MAP_SENTINEL; - array_add(&h->entries, e); - return cast(MapIndex)(h->entries.count-1); + map__reserve_entries(h, h->count+1); + h->entries[h->count++] = e; + return cast(MapIndex)(h->count-1); } template <typename K, typename V> gb_internal MapFindResult map__find(PtrMap<K, V> *h, K key) { MapFindResult fr = {MAP_SENTINEL, MAP_SENTINEL, MAP_SENTINEL}; - if (h->hashes.count == 0) { + if (h->hashes_count == 0) { return fr; } u32 hash = ptr_map_hash_key(key); - fr.hash_index = cast(MapIndex)(hash & (h->hashes.count-1)); - fr.entry_index = h->hashes.data[fr.hash_index]; + fr.hash_index = cast(MapIndex)(hash & (h->hashes_count-1)); + fr.entry_index = h->hashes[fr.hash_index]; while (fr.entry_index != MAP_SENTINEL) { - auto *entry = &h->entries.data[fr.entry_index]; + auto *entry = &h->entries[fr.entry_index]; if (entry->key == key) { return fr; } @@ -126,41 +142,41 @@ gb_internal MapFindResult map__find(PtrMap<K, V> *h, K key) { template <typename K, typename V> gb_internal MapFindResult map__find_from_entry(PtrMap<K, V> *h, PtrMapEntry<K, V> *e) { MapFindResult fr = {MAP_SENTINEL, MAP_SENTINEL, MAP_SENTINEL}; - if (h->hashes.count == 0) { + if (h->hashes_count == 0) { return fr; } u32 hash = ptr_map_hash_key(e->key); - fr.hash_index = cast(MapIndex)(hash & (h->hashes.count-1)); - fr.entry_index = h->hashes.data[fr.hash_index]; + fr.hash_index = cast(MapIndex)(hash & (h->hashes_count-1)); + fr.entry_index = h->hashes[fr.hash_index]; while (fr.entry_index != MAP_SENTINEL) { - if (&h->entries.data[fr.entry_index] == e) { + if (&h->entries[fr.entry_index] == e) { return fr; } fr.entry_prev = fr.entry_index; - fr.entry_index = h->entries.data[fr.entry_index].next; + fr.entry_index = h->entries[fr.entry_index].next; } return fr; } template <typename K, typename V> gb_internal b32 map__full(PtrMap<K, V> *h) { - return 0.75f * h->hashes.count <= h->entries.count; + return 0.75f * h->hashes_count <= h->count; } template <typename K, typename V> gb_internal gb_inline void map_grow(PtrMap<K, V> *h) { - isize new_count = gb_max(h->hashes.count<<1, 16); + isize new_count = gb_max(h->hashes_count<<1, 16); map_rehash(h, new_count); } template <typename K, typename V> gb_internal void map_reset_entries(PtrMap<K, V> *h) { - for (isize i = 0; i < h->hashes.count; i++) { - h->hashes.data[i] = MAP_SENTINEL; + for (usize i = 0; i < h->hashes_count; i++) { + h->hashes[i] = MAP_SENTINEL; } - for (isize i = 0; i < h->entries.count; i++) { + for (usize i = 0; i < h->count; i++) { MapFindResult fr; - PtrMapEntry<K, V> *e = &h->entries.data[i]; + PtrMapEntry<K, V> *e = &h->entries[i]; e->next = MAP_SENTINEL; fr = map__find_from_entry(h, e); if (fr.entry_prev == MAP_SENTINEL) { @@ -173,14 +189,11 @@ gb_internal void map_reset_entries(PtrMap<K, V> *h) { template <typename K, typename V> gb_internal void map_reserve(PtrMap<K, V> *h, isize cap) { - if (h->entries.allocator.proc == nullptr) { - h->entries.allocator = map_allocator(); - } - array_reserve(&h->entries, cap); - if (h->entries.count*2 < h->hashes.count) { + if (h->count*2 < h->hashes_count) { return; } - slice_resize(&h->hashes, h->entries.allocator, cap*2); + map__reserve_entries(h, cap); + map__resize_hashes(h, cap*2); map_reset_entries(h); } @@ -195,12 +208,12 @@ gb_internal V *map_get(PtrMap<K, V> *h, K key) { MapIndex hash_index = MAP_SENTINEL; MapIndex entry_prev = MAP_SENTINEL; MapIndex entry_index = MAP_SENTINEL; - if (h->hashes.count != 0) { + if (h->hashes_count != 0) { u32 hash = ptr_map_hash_key(key); - hash_index = cast(MapIndex)(hash & (h->hashes.count-1)); - entry_index = h->hashes.data[hash_index]; + hash_index = cast(MapIndex)(hash & (h->hashes_count-1)); + entry_index = h->hashes[hash_index]; while (entry_index != MAP_SENTINEL) { - auto *entry = &h->entries.data[entry_index]; + auto *entry = &h->entries[entry_index]; if (entry->key == key) { return &entry->value; } @@ -213,12 +226,12 @@ gb_internal V *map_get(PtrMap<K, V> *h, K key) { template <typename K, typename V> gb_internal V *map_try_get(PtrMap<K, V> *h, K key, MapFindResult *fr_) { MapFindResult fr = {MAP_SENTINEL, MAP_SENTINEL, MAP_SENTINEL}; - if (h->hashes.count != 0) { + if (h->hashes_count != 0) { u32 hash = ptr_map_hash_key(key); - fr.hash_index = cast(MapIndex)(hash & (h->hashes.count-1)); - fr.entry_index = h->hashes.data[fr.hash_index]; + fr.hash_index = cast(MapIndex)(hash & (h->hashes_count-1)); + fr.entry_index = h->hashes[fr.hash_index]; while (fr.entry_index != MAP_SENTINEL) { - auto *entry = &h->entries.data[fr.entry_index]; + auto *entry = &h->entries[fr.entry_index]; if (entry->key == key) { return &entry->value; } @@ -226,7 +239,7 @@ gb_internal V *map_try_get(PtrMap<K, V> *h, K key, MapFindResult *fr_) { fr.entry_index = entry->next; } } - if (h->hashes.count == 0 || map__full(h)) { + if (h->hashes_count == 0 || map__full(h)) { map_grow(h); } if (fr_) *fr_ = fr; @@ -238,11 +251,11 @@ template <typename K, typename V> gb_internal void map_set_internal_from_try_get(PtrMap<K, V> *h, K key, V const &value, MapFindResult const &fr) { MapIndex index = map__add_entry(h, key); if (fr.entry_prev != MAP_SENTINEL) { - h->entries.data[fr.entry_prev].next = index; + h->entries[fr.entry_prev].next = index; } else { - h->hashes.data[fr.hash_index] = index; + h->hashes[fr.hash_index] = index; } - h->entries.data[index].value = value; + h->entries[index].value = value; } template <typename K, typename V> @@ -256,7 +269,7 @@ template <typename K, typename V> gb_internal void map_set(PtrMap<K, V> *h, K key, V const &value) { MapIndex index; MapFindResult fr; - if (h->hashes.count == 0) { + if (h->hashes_count == 0) { map_grow(h); } fr = map__find(h, key); @@ -265,12 +278,12 @@ gb_internal void map_set(PtrMap<K, V> *h, K key, V const &value) { } else { index = map__add_entry(h, key); if (fr.entry_prev != MAP_SENTINEL) { - h->entries.data[fr.entry_prev].next = index; + h->entries[fr.entry_prev].next = index; } else { - h->hashes.data[fr.hash_index] = index; + h->hashes[fr.hash_index] = index; } } - h->entries.data[index].value = value; + h->entries[index].value = value; if (map__full(h)) { map_grow(h); @@ -282,7 +295,7 @@ template <typename K, typename V> gb_internal bool map_set_if_not_previously_exists(PtrMap<K, V> *h, K key, V const &value) { MapIndex index; MapFindResult fr; - if (h->hashes.count == 0) { + if (h->hashes_count == 0) { map_grow(h); } fr = map__find(h, key); @@ -291,12 +304,12 @@ gb_internal bool map_set_if_not_previously_exists(PtrMap<K, V> *h, K key, V cons } else { index = map__add_entry(h, key); if (fr.entry_prev != MAP_SENTINEL) { - h->entries.data[fr.entry_prev].next = index; + h->entries[fr.entry_prev].next = index; } else { - h->hashes.data[fr.hash_index] = index; + h->hashes[fr.hash_index] = index; } } - h->entries.data[index].value = value; + h->entries[index].value = value; if (map__full(h)) { map_grow(h); @@ -309,22 +322,22 @@ template <typename K, typename V> gb_internal void map__erase(PtrMap<K, V> *h, MapFindResult const &fr) { MapFindResult last; if (fr.entry_prev == MAP_SENTINEL) { - h->hashes.data[fr.hash_index] = h->entries.data[fr.entry_index].next; + h->hashes[fr.hash_index] = h->entries[fr.entry_index].next; } else { - h->entries.data[fr.entry_prev].next = h->entries.data[fr.entry_index].next; + h->entries[fr.entry_prev].next = h->entries[fr.entry_index].next; } - if (fr.entry_index == h->entries.count-1) { - array_pop(&h->entries); + if (fr.entry_index == h->count-1) { + h->count--; return; } - h->entries.data[fr.entry_index] = h->entries.data[h->entries.count-1]; - array_pop(&h->entries); + h->entries[fr.entry_index] = h->entries[h->count-1]; + h->count--; - last = map__find(h, h->entries.data[fr.entry_index].key); + last = map__find(h, h->entries[fr.entry_index].key); if (last.entry_prev != MAP_SENTINEL) { - h->entries.data[last.entry_prev].next = fr.entry_index; + h->entries[last.entry_prev].next = fr.entry_index; } else { - h->hashes.data[last.hash_index] = fr.entry_index; + h->hashes[last.hash_index] = fr.entry_index; } } @@ -338,9 +351,9 @@ gb_internal void map_remove(PtrMap<K, V> *h, K key) { template <typename K, typename V> gb_internal gb_inline void map_clear(PtrMap<K, V> *h) { - array_clear(&h->entries); - for (isize i = 0; i < h->hashes.count; i++) { - h->hashes.data[i] = MAP_SENTINEL; + h->count = 0; + for (usize i = 0; i < h->hashes_count; i++) { + h->hashes[i] = MAP_SENTINEL; } } @@ -352,17 +365,17 @@ gb_internal PtrMapEntry<K, V> *multi_map_find_first(PtrMap<K, V> *h, K key) { if (i == MAP_SENTINEL) { return nullptr; } - return &h->entries.data[i]; + return &h->entries[i]; } template <typename K, typename V> gb_internal PtrMapEntry<K, V> *multi_map_find_next(PtrMap<K, V> *h, PtrMapEntry<K, V> *e) { MapIndex i = e->next; while (i != MAP_SENTINEL) { - if (h->entries.data[i].key == e->key) { - return &h->entries.data[i]; + if (h->entries[i].key == e->key) { + return &h->entries[i]; } - i = h->entries.data[i].next; + i = h->entries[i].next; } return nullptr; } @@ -380,7 +393,7 @@ gb_internal isize multi_map_count(PtrMap<K, V> *h, K key) { template <typename K, typename V> gb_internal void multi_map_get_all(PtrMap<K, V> *h, K key, V *items) { - isize i = 0; + usize i = 0; PtrMapEntry<K, V> *e = multi_map_find_first(h, key); while (e != nullptr) { items[i++] = e->value; @@ -392,19 +405,19 @@ template <typename K, typename V> gb_internal void multi_map_insert(PtrMap<K, V> *h, K key, V const &value) { MapFindResult fr; MapIndex i; - if (h->hashes.count == 0) { + if (h->hashes_count == 0) { map_grow(h); } // Make fr = map__find(h, key); i = map__add_entry(h, key); if (fr.entry_prev == MAP_SENTINEL) { - h->hashes.data[fr.hash_index] = i; + h->hashes[fr.hash_index] = i; } else { - h->entries.data[fr.entry_prev].next = i; + h->entries[fr.entry_prev].next = i; } - h->entries.data[i].next = fr.entry_index; - h->entries.data[i].value = value; + h->entries[i].next = fr.entry_index; + h->entries[i].value = value; // Grow if needed if (map__full(h)) { map_grow(h); @@ -430,20 +443,20 @@ gb_internal void multi_map_remove_all(PtrMap<K, V> *h, K key) { template <typename K, typename V> gb_internal PtrMapEntry<K, V> *begin(PtrMap<K, V> &m) { - return m.entries.data; + return m.entries; } template <typename K, typename V> gb_internal PtrMapEntry<K, V> const *begin(PtrMap<K, V> const &m) { - return m.entries.data; + return m.entries; } template <typename K, typename V> gb_internal PtrMapEntry<K, V> *end(PtrMap<K, V> &m) { - return m.entries.data + m.entries.count; + return m.entries + m.count; } template <typename K, typename V> gb_internal PtrMapEntry<K, V> const *end(PtrMap<K, V> const &m) { - return m.entries.data + m.entries.count; + return m.entries + m.count; } |