From 43ab9c11fa80714054eb8aaa1b0b1e8cfd4a55e3 Mon Sep 17 00:00:00 2001 From: Krzosa Karol Date: Fri, 8 Jul 2022 14:04:12 +0200 Subject: [PATCH] Array_List unordered remove --- main.cpp | 147 ++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 107 insertions(+), 40 deletions(-) diff --git a/main.cpp b/main.cpp index 35ee1ff..5cd001f 100644 --- a/main.cpp +++ b/main.cpp @@ -760,22 +760,21 @@ UI_SIGNAL_CALLBACK(scene_callback) { const int ARRAY_LIST_DEFAULT_CAP = 32; const int ARRAY_LIST_DEFAULT_ALLOCATION_MUL = 2; -template struct Array_List; template struct Array_List_Iter; -template void array_add_free_node(Arena *arena, Array_List *array, int size); template struct Array_Node{ Array_Node *next; Array_Node *prev; - int cap, len; + int cap; + int len; T data[]; }; template struct Array_List{ - S32 block_size = 0; - S32 allocation_multiplier = 0; + int block_size = 0; + int allocation_multiplier = 0; Array_Node *first = 0; Array_Node *last = 0; Array_Node *first_free = 0; @@ -798,21 +797,23 @@ struct Array_List_Iter{ template void Array_List_Iter::next(){ - if(node_index + 1 >= node->len){ - node = node->next; - node_index = -1; - item = 0; - } - - if(node){ - node_index += 1; - index += 1; - item = node->data + node_index; - } + if(node_index + 1 >= node->len){ + node = node->next; + node_index = -1; + item = 0; } + if(node){ + node_index += 1; + index += 1; + item = node->data + node_index; + } +} + template -B32 Array_List_Iter::is_valid(){ return item != 0; } +B32 Array_List_Iter::is_valid(){ + return item != 0; +} template Array_List_Iter Array_List::iter(){ @@ -832,7 +833,7 @@ Array_Node *array_allocate_node(Arena *arena, int size){ } template -void array_add_free_node(Arena *arena, Array_List *array, int size){ +void array_alloc_free_node(Arena *arena, Array_List *array, int size){ Array_Node *node = array_allocate_node(arena, size); DLLFreeListAdd(array->first_free, node); } @@ -857,6 +858,8 @@ void make_sure_there_is_room_for_item_count(Arena *arena, Array_List *array, if(!node){ if(!array->allocation_multiplier) array->allocation_multiplier = ARRAY_LIST_DEFAULT_ALLOCATION_MUL; if(!array->block_size) array->block_size = ARRAY_LIST_DEFAULT_CAP; + if(item_count > array->block_size) + array->block_size = item_count*2; node = array_allocate_node(arena, array->block_size); array->block_size *= array->allocation_multiplier; } @@ -883,6 +886,14 @@ void array_add(Arena *arena, Array_List *array, T item){ array->last->data[array->last->len++] = item; } +template +T *array_alloc(Arena *arena, Array_List *array, int count){ + make_sure_there_is_room_for_item_count(arena, array, count); + T *result = array->last->data; + array->last->len += count; + return result; +} + template void array_free_node(Array_List *array, Array_Node *node){ @@ -912,6 +923,35 @@ void array_free_all_nodes(Array_List *array){ array->last = array->first = 0; } +template +void array_unordered_remove(Array_List *array, int index){ + auto last = array->last; + assert(last); + assert(last->data); + assert(last->len != 0); + T *indexed_value = array_get(array, index); + T *last_value = last->data + (last->len-1); + + T temp = *indexed_value; + *indexed_value = *last_value; + *last_value = temp; + + array_pop(array); +} + +template +T array_pop(Array_List *array){ + assert(array->last != 0); + assert(array->last->len > 0); + T result = array->last->data[--array->last->len]; + if(array->last->len == 0){ + auto node = array->last; + DLLQueueRemove(array->first, array->last, node); + DLLFreeListAdd(array->first_free, node); + } + return result; +} + void array_print(Array_List *array){ log_info("\nNodes: "); for(Array_Node *it = array->first; it; it=it->next){ @@ -967,31 +1007,58 @@ void array_print(Array_List *array){ function void test_array_list(){ Scratch scratch; - Array_List array{32, 1}; - for(int i = 0; i < 512; i++){ - array_add(scratch, &array, i); + log_info("\nArray_List:%d Array_Node:%d Array:%d", (int)sizeof(Array_List), (int)sizeof(Array_Node), (int)sizeof(Array)); + + { + Array_List array{32,1}; + for(int i = 0; i < 33; i++){ + array_add(scratch, &array, i); + } + assert(array_pop(&array) == 32); + assert(array_pop(&array) == 31); + array_add(scratch, &array, 31); + array_add(scratch, &array, 32); + assert(array_pop(&array) == 32); + assert(array_pop(&array) == 31); + + array_add(scratch, &array, 31); + array_add(scratch, &array, 32); + + array_unordered_remove(&array, 31); + array_unordered_remove(&array, 31); + + assert(array_pop(&array) == 30); + assert(array_pop(&array) == 29); } - For_It(array){ - assert(it.index == *it.item); + { + Array_List array; + for(int i = 0; i < 100000; i++){ + array_add(scratch, &array, i); + } + + For_It(array){ + assert(it.index == *it.item); + } + + assert(*array_get(&array, 22) == 22); + assert(*array_get(&array, 65) == 65); + assert(*array_get(&array, 200) == 200); + + array_print(&array); + array_free_node(&array, array.last->prev); + array_free_node(&array, array.last->prev); + array_free_node(&array, array.last->prev); + array_free_node(&array, array.last->prev); + array_free_node(&array, array.last->prev->prev); + array_print(&array); + + for(int i = 0; i < 10000; i++){ + array_add(scratch, &array, i); + } + + array_print(&array); } - assert(*array_get(&array, 22) == 22); - assert(*array_get(&array, 65) == 65); - assert(*array_get(&array, 200) == 200); - - array_print(&array); - array_free_node(&array, array.last->prev); - array_free_node(&array, array.last->prev); - array_free_node(&array, array.last->prev); - array_free_node(&array, array.last->prev); - array_free_node(&array, array.last->prev->prev); - array_print(&array); - - for(int i = 0; i < 33; i++){ - array_add(scratch, &array, i); - } - - array_print(&array); __debugbreak(); }