mirror of
https://github.com/odin-lang/Odin.git
synced 2026-04-18 20:40:28 +00:00
Do an extra check before insertion for pre-existing keys
This is test code
This commit is contained in:
@@ -354,12 +354,27 @@ map_alloc_dynamic :: proc "odin" (info: ^Map_Info, log2_capacity: uintptr, alloc
|
||||
// This procedure returns the address of the just inserted value.
|
||||
@(optimization_mode="speed")
|
||||
map_insert_hash_dynamic :: proc "odin" (m: Raw_Map, #no_alias info: ^Map_Info, h: Map_Hash, ik: uintptr, iv: uintptr) -> (result: uintptr) {
|
||||
p := map_desired_position(m, h)
|
||||
d := uintptr(0)
|
||||
c := (uintptr(1) << map_log2_cap(m)) - 1 // Saturating arithmetic mask
|
||||
pos := map_desired_position(m, h)
|
||||
distance := uintptr(0)
|
||||
mask := (uintptr(1) << map_log2_cap(m)) - 1 // Saturating arithmetic mask
|
||||
|
||||
ks, vs, hs, sk, sv := map_kvh_data_dynamic(m, info)
|
||||
|
||||
get_loop: for {
|
||||
element_hash := hs[pos]
|
||||
if map_hash_is_empty(element_hash) {
|
||||
break get_loop
|
||||
} else if distance > map_probe_distance(m, element_hash, pos) {
|
||||
break get_loop
|
||||
} else if element_hash == h && info.key_equal(rawptr(ik), rawptr(map_cell_index_dynamic(ks, info.ks, pos))) {
|
||||
result = map_cell_index_dynamic(vs, info.vs, pos)
|
||||
intrinsics.mem_copy_non_overlapping(rawptr(result), rawptr(iv), info.ks.size_of_type)
|
||||
return
|
||||
}
|
||||
pos = (pos + 1) & mask
|
||||
distance += 1
|
||||
}
|
||||
|
||||
// Avoid redundant loads of these values
|
||||
size_of_k := info.ks.size_of_type
|
||||
size_of_v := info.vs.size_of_type
|
||||
@@ -381,38 +396,38 @@ map_insert_hash_dynamic :: proc "odin" (m: Raw_Map, #no_alias info: ^Map_Info, h
|
||||
tv := map_cell_index_dynamic_const(sv, info.vs, 1)
|
||||
|
||||
for {
|
||||
hp := &hs[p]
|
||||
hp := &hs[pos]
|
||||
element_hash := hp^
|
||||
|
||||
if map_hash_is_empty(element_hash) {
|
||||
k_dst := map_cell_index_dynamic(ks, info.ks, p)
|
||||
v_dst := map_cell_index_dynamic(vs, info.vs, p)
|
||||
k_dst := map_cell_index_dynamic(ks, info.ks, pos)
|
||||
v_dst := map_cell_index_dynamic(vs, info.vs, pos)
|
||||
intrinsics.mem_copy_non_overlapping(rawptr(k_dst), rawptr(k), size_of_k)
|
||||
intrinsics.mem_copy_non_overlapping(rawptr(v_dst), rawptr(v), size_of_v)
|
||||
hp^ = h
|
||||
return result if result != 0 else v_dst
|
||||
}
|
||||
|
||||
if pd := map_probe_distance(m, element_hash, p); pd <= d {
|
||||
if pd := map_probe_distance(m, element_hash, pos); pd <= distance {
|
||||
if map_hash_is_deleted(element_hash) {
|
||||
k_dst := map_cell_index_dynamic(ks, info.ks, p)
|
||||
v_dst := map_cell_index_dynamic(vs, info.vs, p)
|
||||
k_dst := map_cell_index_dynamic(ks, info.ks, pos)
|
||||
v_dst := map_cell_index_dynamic(vs, info.vs, pos)
|
||||
intrinsics.mem_copy_non_overlapping(rawptr(k_dst), rawptr(k), size_of_k)
|
||||
intrinsics.mem_copy_non_overlapping(rawptr(v_dst), rawptr(v), size_of_v)
|
||||
hp^ = h
|
||||
return result if result != 0 else v_dst
|
||||
} else if element_hash == h && info.key_equal(rawptr(k), rawptr(map_cell_index_dynamic(ks, info.ks, p))) {
|
||||
v_dst := map_cell_index_dynamic(vs, info.vs, p)
|
||||
} else if element_hash == h && info.key_equal(rawptr(k), rawptr(map_cell_index_dynamic(ks, info.ks, pos))) {
|
||||
v_dst := map_cell_index_dynamic(vs, info.vs, pos)
|
||||
intrinsics.mem_copy_non_overlapping(rawptr(v_dst), rawptr(iv), info.vs.size_of_type)
|
||||
return v_dst
|
||||
}
|
||||
|
||||
if result == 0 {
|
||||
result = map_cell_index_dynamic(vs, info.vs, p)
|
||||
result = map_cell_index_dynamic(vs, info.vs, pos)
|
||||
}
|
||||
|
||||
kp := map_cell_index_dynamic(ks, info.vs, p)
|
||||
vp := map_cell_index_dynamic(vs, info.ks, p)
|
||||
kp := map_cell_index_dynamic(ks, info.vs, pos)
|
||||
vp := map_cell_index_dynamic(vs, info.ks, pos)
|
||||
|
||||
// Simulate the following at runtime with dynamic storage
|
||||
//
|
||||
@@ -427,11 +442,11 @@ map_insert_hash_dynamic :: proc "odin" (m: Raw_Map, #no_alias info: ^Map_Info, h
|
||||
intrinsics.mem_copy_non_overlapping(rawptr(v), rawptr(tv), size_of_v)
|
||||
hp^, h = h, hp^
|
||||
|
||||
d = pd
|
||||
distance = pd
|
||||
}
|
||||
|
||||
p = (p + 1) & c
|
||||
d += 1
|
||||
pos = (pos + 1) & mask
|
||||
distance += 1
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user