4coder/4ed_ptr_check.cpp

366 lines
10 KiB
C++

/*
* Mr. 4th Dimention - Allen Webster
*
* 26.08.2018
*
* Pointer check table
*
*/
// TOP
internal Ptr_Table
make_Ptr_table(void *mem, umem size){
Ptr_Table table = {0};
i32 max = (i32)(size/8);
if (max > 0){
table.mem = mem;
u8 *cursor = (u8*)mem;
table.hashes = (u64*)cursor;
cursor += 8*max;
table.count = 0;
table.max = max;
block_fill_ones(table.hashes, sizeof(*table.hashes)*max);
}
return(table);
}
internal i32
max_to_memsize_Ptr_table(i32 max){
return(max*8);
}
internal b32
at_max_Ptr_table(Ptr_Table *table){
if (table->max > 0 && (table->count + 1)*8 <= table->max*7){
return(false);
}
return(true);
}
internal b32
insert_Ptr_table(Ptr_Table *table, void**key){
i32 max = table->max;
if (max > 0){
i32 count = table->count;
if ((count + 1)*8 <= max*7){
u64 hash = 0;
block_copy(&hash, key, 8);
if (hash >= 18446744073709551614ULL){ hash += 2; }
i32 first_index = hash%max;
i32 index = first_index;
u64 *hashes = table->hashes;
for (;;){
if (hashes[index] == 18446744073709551615ULL){
table->dirty_slot_count += 1;
}
if (hashes[index] == 18446744073709551615ULL || hashes[index] == 18446744073709551614ULL){
hashes[index] = hash;
table->count += 1;
return(true);
}
if (hashes[index] == hash) return(false);
index = (index + 1)%max;
if (index == first_index) return(false);
}
}
}
return(false);
}
internal b32
lookup_Ptr_table(Ptr_Table *table, void**key){
i32 max = table->max;
if (max > 0){
u64 hash = 0;
block_copy(&hash, key, 8);
if (hash >= 18446744073709551614ULL){ hash += 2; }
i32 first_index = hash%max;
i32 index = first_index;
u64 *hashes = table->hashes;
for (;;){
if (hashes[index] == 18446744073709551615ULL) break;
if (hashes[index] == hash){
return(true);
}
index = (index + 1)%max;
if (index == first_index) break;
}
}
return(false);
}
internal b32
erase_Ptr_table(Ptr_Table *table, void**key){
i32 max = table->max;
if (max > 0 && table->count > 0){
u64 hash = 0;
block_copy(&hash, key, 8);
if (hash >= 18446744073709551614ULL){ hash += 2; }
i32 first_index = hash%max;
i32 index = first_index;
u64 *hashes = table->hashes;
for (;;){
if (hashes[index] == 18446744073709551615ULL) break;
if (hashes[index] == hash){
hashes[index] = 18446744073709551614ULL;
table->count -= 1;
return(true);
}
index = (index + 1)%max;
if (index == first_index) break;
}
}
return(false);
}
internal b32
move_Ptr_table(Ptr_Table *dst_table, Ptr_Table *src_table){
if ((src_table->count + dst_table->count)*8 <= dst_table->max*7){
i32 max = src_table->max;
u64 *hashes = src_table->hashes;
for (i32 index = 0; index < max; index += 1){
if (hashes[index] != 18446744073709551615ULL && hashes[index] != 18446744073709551614ULL){
void* key_;
void**key = &key_;
block_copy(key, &hashes[index], 8);
insert_Ptr_table(dst_table, key);
}
}
return(true);
}
return(false);
}
internal b32
insert_Ptr_table(Ptr_Table *table, void* key){
return(insert_Ptr_table(table, &key));
}
internal b32
lookup_Ptr_table(Ptr_Table *table, void* key){
return(lookup_Ptr_table(table, &key));
}
internal b32
erase_Ptr_table(Ptr_Table *table, void* key){
return(erase_Ptr_table(table, &key));
}
////////////////////////////////
internal void
insert_Ptr_table(Heap *heap, Ptr_Table *table, void* key){
if (at_max_Ptr_table(table)){
i32 new_max = (table->max + 1)*2;
i32 new_mem_size = max_to_memsize_Ptr_table(new_max);
void *new_mem = heap_allocate(heap, new_mem_size);
Ptr_Table new_table = make_Ptr_table(new_mem, new_mem_size);
if (table->mem != 0){
b32 result = move_Ptr_table(&new_table, table);
Assert(result);
AllowLocal(result);
heap_free(heap, table->mem);
}
*table = new_table;
}
b32 result = insert_Ptr_table(table, &key);
Assert(result);
AllowLocal(result);
}
////////////////////////////////
internal u32_Ptr_Table
make_u32_Ptr_table(void *mem, umem size){
u32_Ptr_Table table = {0};
i32 max = (i32)(size/16);
if (max > 0){
table.mem = mem;
u8 *cursor = (u8*)mem;
table.hashes = (u64*)cursor;
cursor += 8*max;
table.vals = (void**)cursor;
table.count = 0;
table.max = max;
block_fill_ones(table.hashes, sizeof(*table.hashes)*max);
}
return(table);
}
internal i32
max_to_memsize_u32_Ptr_table(i32 max){
return(max*16);
}
internal b32
at_max_u32_Ptr_table(u32_Ptr_Table *table){
if (table->max > 0 && (table->count + 1)*8 <= table->max*7){
return(false);
}
return(true);
}
internal b32
insert_u32_Ptr_table(u32_Ptr_Table *table, u32*key, void**val){
i32 max = table->max;
if (max > 0){
i32 count = table->count;
if ((count + 1)*8 <= max*7){
u64 hash = 0;
block_copy(&hash, key, 4);
if (hash >= 18446744073709551614ULL){ hash += 2; }
i32 first_index = hash%max;
i32 index = first_index;
u64 *hashes = table->hashes;
for (;;){
if (hashes[index] == 18446744073709551615ULL){
table->dirty_slot_count += 1;
}
if (hashes[index] == 18446744073709551615ULL || hashes[index] == 18446744073709551614ULL){
hashes[index] = hash;
table->vals[index] = *val;
table->count += 1;
return(true);
}
if (hashes[index] == hash) return(false);
index = (index + 1)%max;
if (index == first_index) return(false);
}
}
}
return(false);
}
internal u32_Ptr_Lookup_Result
lookup_u32_Ptr_table(u32_Ptr_Table *table, u32*key){
u32_Ptr_Lookup_Result result = {0};
i32 max = table->max;
if (max > 0){
u64 hash = 0;
block_copy(&hash, key, 4);
if (hash >= 18446744073709551614ULL){ hash += 2; }
i32 first_index = hash%max;
i32 index = first_index;
u64 *hashes = table->hashes;
for (;;){
if (hashes[index] == 18446744073709551615ULL) break;
if (hashes[index] == hash){
result.success = true;
result.val = &table->vals[index];
return(result);
}
index = (index + 1)%max;
if (index == first_index) break;
}
}
return(result);
}
internal b32
erase_u32_Ptr_table(u32_Ptr_Table *table, u32*key){
i32 max = table->max;
if (max > 0 && table->count > 0){
u64 hash = 0;
block_copy(&hash, key, 4);
if (hash >= 18446744073709551614ULL){ hash += 2; }
i32 first_index = hash%max;
i32 index = first_index;
u64 *hashes = table->hashes;
for (;;){
if (hashes[index] == 18446744073709551615ULL) break;
if (hashes[index] == hash){
hashes[index] = 18446744073709551614ULL;
table->count -= 1;
return(true);
}
index = (index + 1)%max;
if (index == first_index) break;
}
}
return(false);
}
internal b32
move_u32_Ptr_table(u32_Ptr_Table *dst_table, u32_Ptr_Table *src_table){
if ((src_table->count + dst_table->count)*8 <= dst_table->max*7){
i32 max = src_table->max;
u64 *hashes = src_table->hashes;
for (i32 index = 0; index < max; index += 1){
if (hashes[index] != 18446744073709551615ULL && hashes[index] != 18446744073709551614ULL){
u32 key_;
u32*key = &key_;
block_copy(key, &hashes[index], 4);
void**val = &src_table->vals[index];
insert_u32_Ptr_table(dst_table, key, val);
}
}
return(true);
}
return(false);
}
internal b32
lookup_u32_Ptr_table(u32_Ptr_Table *table, u32 *key, void* *val_out){
u32_Ptr_Lookup_Result result = lookup_u32_Ptr_table(table, key);
if (result.success){
*val_out = *result.val;
}
return(result.success);
}
internal b32
insert_u32_Ptr_table(u32_Ptr_Table *table, u32*key, void* val){
return(insert_u32_Ptr_table(table, key, &val));
}
internal b32
insert_u32_Ptr_table(u32_Ptr_Table *table, u32 key, void**val){
return(insert_u32_Ptr_table(table, &key, val));
}
internal b32
insert_u32_Ptr_table(u32_Ptr_Table *table, u32 key, void* val){
return(insert_u32_Ptr_table(table, &key, &val));
}
internal u32_Ptr_Lookup_Result
lookup_u32_Ptr_table(u32_Ptr_Table *table, u32 key){
return(lookup_u32_Ptr_table(table, &key));
}
internal b32
lookup_u32_Ptr_table(u32_Ptr_Table *table, u32 key, void* *val_out){
return(lookup_u32_Ptr_table(table, &key, val_out));
}
internal b32
erase_u32_Ptr_table(u32_Ptr_Table *table, u32 key){
return(erase_u32_Ptr_table(table, &key));
}
////////////////////////////////
internal void
insert_u32_Ptr_table(Heap *heap, u32_Ptr_Table *table, u32 key, void* val){
if (at_max_u32_Ptr_table(table)){
i32 new_max = (table->max + 1)*2;
i32 new_mem_size = max_to_memsize_u32_Ptr_table(new_max);
void *new_mem = heap_allocate(heap, new_mem_size);
u32_Ptr_Table new_table = make_u32_Ptr_table(new_mem, new_mem_size);
if (table->mem != 0){
b32 result = move_u32_Ptr_table(&new_table, table);
Assert(result);
AllowLocal(result);
heap_free(heap, table->mem);
}
*table = new_table;
}
b32 result = insert_u32_Ptr_table(table, &key, &val);
Assert(result);
AllowLocal(result);
}
// BOTTOM