aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2022-11-08 11:29:09 +0000
committergingerBill <bill@gingerbill.org>2022-11-08 11:29:09 +0000
commitea263b8cc55cdfbec38dcd6bf64e9cc3fee22fb0 (patch)
tree00805aa2fb85e58e6c403a29c3159693bed2f27f
parent45f0c812afc91038eaf2ed674c1b2d6792c6c349 (diff)
Add `runtime.map_exists_dynamic`
-rw-r--r--core/runtime/dynamic_map_internal.odin25
1 files changed, 24 insertions, 1 deletions
diff --git a/core/runtime/dynamic_map_internal.odin b/core/runtime/dynamic_map_internal.odin
index 465c5bfb7..6f6a17f11 100644
--- a/core/runtime/dynamic_map_internal.odin
+++ b/core/runtime/dynamic_map_internal.odin
@@ -692,7 +692,30 @@ map_lookup_dynamic :: proc "contextless" (m: Raw_Map, #no_alias info: ^Map_Info,
d += 1
}
}
-
+@(optimization_mode="speed")
+map_exists_dynamic :: proc "contextless" (m: Raw_Map, #no_alias info: ^Map_Info, k: uintptr) -> (ok: bool) {
+ if map_len(m) == 0 {
+ return false
+ }
+ h := info.key_hasher(rawptr(k), 0)
+ p := map_desired_position(m, h)
+ d := uintptr(0)
+ c := (uintptr(1) << map_log2_cap(m)) - 1
+ ks, _, hs, _, _ := map_kvh_data_dynamic(m, info)
+ info_ks := &info.ks
+ for {
+ element_hash := hs[p]
+ if map_hash_is_empty(element_hash) {
+ return false
+ } else if d > map_probe_distance(m, element_hash, p) {
+ return false
+ } else if element_hash == h && info.key_equal(rawptr(k), rawptr(map_cell_index_dynamic(ks, info_ks, p))) {
+ return true
+ }
+ p = (p + 1) & c
+ d += 1
+ }
+}