mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-05 15:18:49 +00:00
Fix map bug which removed N values from the beginning
This commit is contained in:
+29
-13
@@ -466,6 +466,16 @@ __dynamic_array_reserve :: proc(array_: rawptr, elem_size, elem_align: int, cap:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__dynamic_array_resize :: proc(array_: rawptr, elem_size, elem_align: int, len: int) -> bool {
|
||||||
|
array := cast(^raw.Dynamic_Array)array_;
|
||||||
|
|
||||||
|
ok := __dynamic_array_reserve(array_, elem_size, elem_align, len);
|
||||||
|
if ok {
|
||||||
|
array.len = len;
|
||||||
|
}
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
__dynamic_array_append :: proc(array_: rawptr, elem_size, elem_align: int,
|
__dynamic_array_append :: proc(array_: rawptr, elem_size, elem_align: int,
|
||||||
items: rawptr, item_count: int) -> int {
|
items: rawptr, item_count: int) -> int {
|
||||||
@@ -546,6 +556,8 @@ __default_hash_string :: proc(s: string) -> u64 {
|
|||||||
return __default_hash(cast([]byte)s);
|
return __default_hash(cast([]byte)s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__INITIAL_MAP_CAP :: 16;
|
||||||
|
|
||||||
__Map_Key :: struct #ordered {
|
__Map_Key :: struct #ordered {
|
||||||
hash: u64,
|
hash: u64,
|
||||||
str: string,
|
str: string,
|
||||||
@@ -571,6 +583,7 @@ __Map_Header :: struct #ordered {
|
|||||||
entry_size: int,
|
entry_size: int,
|
||||||
entry_align: int,
|
entry_align: int,
|
||||||
value_offset: int,
|
value_offset: int,
|
||||||
|
value_size: int,
|
||||||
}
|
}
|
||||||
|
|
||||||
__dynamic_map_reserve :: proc(using header: __Map_Header, cap: int) {
|
__dynamic_map_reserve :: proc(using header: __Map_Header, cap: int) {
|
||||||
@@ -587,21 +600,20 @@ __dynamic_map_rehash :: proc(using header: __Map_Header, new_count: int) {
|
|||||||
nm_hashes := cast(^raw.Dynamic_Array)^nm.hashes;
|
nm_hashes := cast(^raw.Dynamic_Array)^nm.hashes;
|
||||||
|
|
||||||
|
|
||||||
reserve(nm.hashes, new_count);
|
__dynamic_array_resize(nm_hashes, size_of(int), align_of(int), new_count);
|
||||||
nm_hashes.len = nm_hashes.cap;
|
__dynamic_array_reserve(^nm.entries, entry_size, entry_align, m.entries.len);
|
||||||
__dynamic_array_reserve(^nm.entries, entry_size, entry_align, m.entries.cap);
|
for i in 0..new_count {
|
||||||
for _, i in nm.hashes {
|
|
||||||
nm.hashes[i] = -1;
|
nm.hashes[i] = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < nm.entries.len; i++ {
|
for i := 0; i < m.entries.len; i++ {
|
||||||
entry_header := __dynamic_map_get_entry(new_header, i);
|
|
||||||
data := cast(^byte)entry_header;
|
|
||||||
|
|
||||||
if len(nm.hashes) == 0 {
|
if len(nm.hashes) == 0 {
|
||||||
__dynamic_map_grow(new_header);
|
__dynamic_map_grow(new_header);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
entry_header := __dynamic_map_get_entry(new_header, i);
|
||||||
|
data := cast(^byte)entry_header;
|
||||||
|
|
||||||
fr := __dynamic_map_find(new_header, entry_header.key);
|
fr := __dynamic_map_find(new_header, entry_header.key);
|
||||||
j := __dynamic_map_add_entry(new_header, entry_header.key);
|
j := __dynamic_map_add_entry(new_header, entry_header.key);
|
||||||
if fr.entry_prev < 0 {
|
if fr.entry_prev < 0 {
|
||||||
@@ -615,11 +627,12 @@ __dynamic_map_rehash :: proc(using header: __Map_Header, new_count: int) {
|
|||||||
e.next = fr.entry_index;
|
e.next = fr.entry_index;
|
||||||
ndata := cast(^byte)e;
|
ndata := cast(^byte)e;
|
||||||
__mem_copy(ndata+value_offset, data+value_offset, entry_size-value_offset);
|
__mem_copy(ndata+value_offset, data+value_offset, entry_size-value_offset);
|
||||||
|
|
||||||
if __dynamic_map_full(new_header) {
|
if __dynamic_map_full(new_header) {
|
||||||
__dynamic_map_grow(new_header);
|
__dynamic_map_grow(new_header);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free_ptr_with_allocator(header_hashes.allocator, header_hashes.data);
|
free_ptr_with_allocator(header_hashes.allocator, header_hashes.data);
|
||||||
free_ptr_with_allocator(header.m.entries.allocator, header.m.entries.data);
|
free_ptr_with_allocator(header.m.entries.allocator, header.m.entries.data);
|
||||||
header.m^ = nm;
|
header.m^ = nm;
|
||||||
}
|
}
|
||||||
@@ -640,8 +653,10 @@ __dynamic_map_set :: proc(using h: __Map_Header, key: __Map_Key, value: rawptr)
|
|||||||
|
|
||||||
|
|
||||||
if len(m.hashes) == 0 {
|
if len(m.hashes) == 0 {
|
||||||
|
__dynamic_map_reserve(h, __INITIAL_MAP_CAP);
|
||||||
__dynamic_map_grow(h);
|
__dynamic_map_grow(h);
|
||||||
}
|
}
|
||||||
|
|
||||||
fr := __dynamic_map_find(h, key);
|
fr := __dynamic_map_find(h, key);
|
||||||
if fr.entry_index >= 0 {
|
if fr.entry_index >= 0 {
|
||||||
index = fr.entry_index;
|
index = fr.entry_index;
|
||||||
@@ -655,9 +670,10 @@ __dynamic_map_set :: proc(using h: __Map_Header, key: __Map_Key, value: rawptr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
data := cast(^byte)__dynamic_map_get_entry(h, index);
|
e := __dynamic_map_get_entry(h, index);
|
||||||
val := data+value_offset;
|
e.key = key;
|
||||||
__mem_copy(val, value, entry_size-value_offset);
|
val := cast(^byte)e + value_offset;
|
||||||
|
__mem_copy(val, value, value_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
if __dynamic_map_full(h) {
|
if __dynamic_map_full(h) {
|
||||||
@@ -667,7 +683,7 @@ __dynamic_map_set :: proc(using h: __Map_Header, key: __Map_Key, value: rawptr)
|
|||||||
|
|
||||||
|
|
||||||
__dynamic_map_grow :: proc(using h: __Map_Header) {
|
__dynamic_map_grow :: proc(using h: __Map_Header) {
|
||||||
new_count := max(2*m.entries.cap + 8, 8);
|
new_count := max(2*m.entries.cap + 8, __INITIAL_MAP_CAP);
|
||||||
__dynamic_map_rehash(h, new_count);
|
__dynamic_map_rehash(h, new_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1502,12 +1502,15 @@ irValue *ir_gen_map_header(irProcedure *proc, irValue *map_val, Type *map_type)
|
|||||||
ir_emit_store(proc, ir_emit_struct_ep(proc, h, 1), v_true);
|
ir_emit_store(proc, ir_emit_struct_ep(proc, h, 1), v_true);
|
||||||
}
|
}
|
||||||
|
|
||||||
i64 entry_size = type_size_of(a, map_type->Map.entry_type);
|
i64 entry_size = type_size_of(a, map_type->Map.entry_type);
|
||||||
i64 entry_align = type_align_of(a, map_type->Map.entry_type);
|
i64 entry_align = type_align_of(a, map_type->Map.entry_type);
|
||||||
i64 value_offset = type_offset_of(a, map_type->Map.entry_type, 2);
|
i64 value_offset = type_offset_of(a, map_type->Map.entry_type, 2);
|
||||||
|
i64 value_size = type_size_of(a, map_type->Map.value);
|
||||||
|
|
||||||
ir_emit_store(proc, ir_emit_struct_ep(proc, h, 2), ir_const_int(a, entry_size));
|
ir_emit_store(proc, ir_emit_struct_ep(proc, h, 2), ir_const_int(a, entry_size));
|
||||||
ir_emit_store(proc, ir_emit_struct_ep(proc, h, 3), ir_const_int(a, entry_align));
|
ir_emit_store(proc, ir_emit_struct_ep(proc, h, 3), ir_const_int(a, entry_align));
|
||||||
ir_emit_store(proc, ir_emit_struct_ep(proc, h, 4), ir_const_int(a, value_offset));
|
ir_emit_store(proc, ir_emit_struct_ep(proc, h, 4), ir_const_int(a, value_offset));
|
||||||
|
ir_emit_store(proc, ir_emit_struct_ep(proc, h, 5), ir_const_int(a, value_size));
|
||||||
|
|
||||||
|
|
||||||
return ir_emit_load(proc, h);
|
return ir_emit_load(proc, h);
|
||||||
|
|||||||
Reference in New Issue
Block a user