diff --git a/base/runtime/dynamic_map_internal.odin b/base/runtime/dynamic_map_internal.odin index ca6d4eb11..2e8b60f4a 100644 --- a/base/runtime/dynamic_map_internal.odin +++ b/base/runtime/dynamic_map_internal.odin @@ -94,17 +94,6 @@ map_cell_index_dynamic :: #force_inline proc "contextless" (base: uintptr, #no_a return base + offset } -// Same as above procedure but with compile-time constant index. -@(require_results) -map_cell_index_dynamic_const :: proc "contextless" (base: uintptr, #no_alias info: ^Map_Cell_Info, $INDEX: uintptr) -> uintptr { - elements_per_cell := uintptr(info.elements_per_cell) - size_of_cell := uintptr(info.size_of_cell) - size_of_type := uintptr(info.size_of_type) - cell_index := INDEX / elements_per_cell - data_index := INDEX % elements_per_cell - return base + (cell_index * size_of_cell) + (data_index * size_of_type) -} - // We always round the capacity to a power of two so this becomes [16]Foo, which // works out to [4]Cell(Foo). // @@ -264,7 +253,7 @@ map_kvh_data_dynamic :: proc "contextless" (m: Raw_Map, #no_alias info: ^Map_Inf sk = map_cell_index_dynamic(hs_, INFO_HS, capacity) // Skip past hs to get start of sk // Need to skip past two elements in the scratch key space to get to the start // of the scratch value space, of which there's only two elements as well. - sv = map_cell_index_dynamic_const(sk, info.ks, 2) + sv = map_cell_index_dynamic(sk, info.ks, 2) hs = ([^]Map_Hash)(hs_) return @@ -562,36 +551,57 @@ map_reserve_dynamic :: #force_no_inline proc "odin" (#no_alias m: ^Raw_Map, #no_ } resized := map_alloc_dynamic(info, log2_min_cap, m.allocator, loc) or_return - - ks, vs, hs, _, _ := map_kvh_data_dynamic(m^, info) - - // Cache these loads to avoid hitting them in the for loop. - n := m.len - for i in 0.. map_probe_distance(dst^, element_hash, pos) { + break + } + pos = (pos + 1) & mask + distance += 1 + } + + if map_hash_is_empty(dhs[pos]) { + intrinsics.mem_copy_non_overlapping(rawptr(map_cell_index_dynamic(dks, info.ks, pos)), rawptr(k), size_of_k) + intrinsics.mem_copy_non_overlapping(rawptr(map_cell_index_dynamic(dvs, info.vs, pos)), rawptr(v), size_of_v) + dhs[pos] = h + } else { + _ = map_insert_hash_dynamic(dst, info, h, k, v) + } + } +} + @(require_results) map_shrink_dynamic :: #force_no_inline proc "odin" (#no_alias m: ^Raw_Map, #no_alias info: ^Map_Info, loc := #caller_location) -> (did_shrink: bool, err: Allocator_Error) { @@ -622,32 +632,7 @@ map_shrink_dynamic :: #force_no_inline proc "odin" (#no_alias m: ^Raw_Map, #no_a } shrunk := map_alloc_dynamic(info, log2_capacity_new, m.allocator) or_return - - capacity := uintptr(1) << log2_capacity_new - - ks, vs, hs, _, _ := map_kvh_data_dynamic(m^, info) - - n := m.len - for i in 0..