Optimized win32 file track node lookups

This commit is contained in:
Allen Webster 2018-12-17 17:56:21 -08:00
parent 790d21f517
commit f0c39a267c
3 changed files with 234 additions and 46 deletions

2
4ed.h
View File

@ -9,7 +9,7 @@
// TOP // TOP
#ifndef FRED_H #if !defined(FRED_H)
#define FRED_H #define FRED_H
#define MAX_VIEWS 16 #define MAX_VIEWS 16

View File

@ -128,6 +128,9 @@ global System_Functions sysfunc;
#include "4ed_coroutine.cpp" #include "4ed_coroutine.cpp"
#include "4ed_font.cpp" #include "4ed_font.cpp"
#include "4ed_mem.cpp"
#include "4ed_hash_functions.cpp"
//////////////////////////////// ////////////////////////////////
struct Win32_Vars{ struct Win32_Vars{
@ -295,22 +298,50 @@ Sys_Is_Fullscreen_Sig(system_is_fullscreen){
// File Change Listener // File Change Listener
// //
struct Directory_Track_Node{ union Directory_Track_Node{
OVERLAPPED overlapped; struct{
HANDLE dir_handle; Directory_Track_Node *next;
Directory_Track_Node *next; Directory_Track_Node *prev;
Directory_Track_Node *prev; };
char buffer[(32 << 10) + 12]; struct{
String dir_name; OVERLAPPED overlapped;
i32 ref_count; HANDLE dir_handle;
char buffer[(32 << 10) + 12];
String dir_name;
i32 ref_count;
};
}; };
struct File_Track_Node{ union File_Track_Node{
File_Track_Node *next; struct{
File_Track_Node *prev; File_Track_Node *next;
String file_name; File_Track_Node *prev;
i32 ref_count; };
Directory_Track_Node *parent_dir; struct{
String file_name;
i32 ref_count;
Directory_Track_Node *parent_dir;
};
};
#if !defined(CString_Key_Reference_GAURD)
#define CString_Key_Reference_GAURD
struct CString_Key_Reference{
char*key;
i32 size;
};
#endif
struct CString_Ptr_Lookup_Result{
b32 success;
void **val;
};
struct CString_Ptr_Table{
void *mem;
u64 *hashes;
CString_Key_Reference*keys;
void **vals;
i32 count;
i32 dirty_slot_count;
i32 max;
}; };
typedef i32 File_Track_Instruction; typedef i32 File_Track_Instruction;
@ -339,12 +370,11 @@ struct File_Track_Note_Node{
Heap file_track_heap = {}; Heap file_track_heap = {};
Partition file_track_scratch = {}; Partition file_track_scratch = {};
Directory_Track_Node *file_track_dir_first = 0;
Directory_Track_Node *file_track_dir_last = 0; CString_Ptr_Table file_track_dir_table = {};
Directory_Track_Node *file_track_dir_free_first = 0; Directory_Track_Node *file_track_dir_free_first = 0;
Directory_Track_Node *file_track_dir_free_last = 0; Directory_Track_Node *file_track_dir_free_last = 0;
File_Track_Node *file_track_first = 0; CString_Ptr_Table file_track_table = {};
File_Track_Node *file_track_last = 0;
File_Track_Node *file_track_free_first = 0; File_Track_Node *file_track_free_first = 0;
File_Track_Node *file_track_free_last = 0; File_Track_Node *file_track_free_last = 0;
File_Track_Instruction_Node *file_track_ins_free_first = 0; File_Track_Instruction_Node *file_track_ins_free_first = 0;
@ -369,6 +399,177 @@ global_const u32 file_track_flags = 0
|FILE_NOTIFY_CHANGE_SECURITY |FILE_NOTIFY_CHANGE_SECURITY
; ;
////////////////////////////////
internal CString_Ptr_Table
make_CString_Ptr_table(void *mem, umem size){
CString_Ptr_Table table = {};
i32 max = (i32)(size/32ULL);
if (max > 0){
table.mem = mem;
u8 *cursor = (u8*)mem;
table.hashes = (u64*)cursor;
cursor += 8*max;
table.keys = (CString_Key_Reference*)cursor;
cursor += 16*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_CString_Ptr_table(i32 max){
return(max*32ULL);
}
internal b32
at_max_CString_Ptr_table(CString_Ptr_Table *table){
if (table->max > 0 && (table->count + 1)*8 <= table->max*7){
return(false);
}
return(true);
}
internal b32
insert_CString_Ptr_table(CString_Ptr_Table *table, char*key, i32 key_size, void **val){
i32 max = table->max;
if (max > 0){
i32 count = table->count;
if ((count + 1)*8 <= max*7){
u64 hash = table_hash_u8((u8*)key, key_size);
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;
CString_Key_Reference new_key = {key, key_size};
table->keys[index] = new_key;
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 CString_Ptr_Lookup_Result
lookup_CString_Ptr_table(CString_Ptr_Table *table, char*key, i32 key_size){
CString_Ptr_Lookup_Result result = {};
i32 max = table->max;
if (max > 0){
u64 hash = table_hash_u8((u8*)key, key_size);
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){
CString_Key_Reference *key_check = &table->keys[index];
b32 key_match = (key_size == key_check->size && block_compare(key, key_check->key, key_size*sizeof(*key)) == 0);
if (key_match){
result.success = true;
result.val = &table->vals[index];
return(result);
}
}
index = (index + 1)%max;
if (index == first_index) break;
}
}
return(result);
}
internal b32
erase_CString_Ptr_table(CString_Ptr_Table *table, char*key, i32 key_size){
i32 max = table->max;
if (max > 0 && table->count > 0){
u64 hash = table_hash_u8((u8*)key, key_size);
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){
CString_Key_Reference *key_check = &table->keys[index];
b32 key_match = (key_size == key_check->size && block_compare(key, key_check->key, key_size*sizeof(*key)) == 0);
if (key_match){
hashes[index] = 18446744073709551614ULL;
table->count -= 1;
return(true);
}
}
index = (index + 1)%max;
if (index == first_index) break;
}
}
return(false);
}
internal b32
move_CString_Ptr_table(CString_Ptr_Table *dst_table, CString_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){
char*key = src_table->keys[index].key;
i32 key_size = src_table->keys[index].size;
void **val = &src_table->vals[index];
insert_CString_Ptr_table(dst_table, key, key_size, val);
}
}
return(true);
}
return(false);
}
internal b32
lookup_CString_Ptr_table(CString_Ptr_Table *table, char *key, i32 key_size, void * *val_out){
CString_Ptr_Lookup_Result result = lookup_CString_Ptr_table(table, key, key_size);
if (result.success){
*val_out = *result.val;
}
return(result.success);
}
internal b32
insert_CString_Ptr_table(CString_Ptr_Table *table, char*key, i32 key_size, void * val){
return(insert_CString_Ptr_table(table, key, key_size, &val));
}
internal b32
alloc_insert_CString_Ptr_table(CString_Ptr_Table *table, char*key, i32 key_size, void *val){
if (at_max_CString_Ptr_table(table)){
i32 new_max = (table->max + 1)*2;
i32 new_size = max_to_memsize_CString_Ptr_table(new_max);
void *new_mem = system_memory_allocate(new_size);
CString_Ptr_Table new_table = make_CString_Ptr_table(new_mem, new_size);
if (table->mem != 0){
i32 old_size = max_to_memsize_CString_Ptr_table(table->max);
system_memory_free(table->mem, old_size);
}
*table = new_table;
}
return(insert_CString_Ptr_table(table, key, key_size, val));
}
////////////////////////////////
internal String internal String
file_track_store_string_copy(String string){ file_track_store_string_copy(String string){
i32 alloc_size = string.size + 1; i32 alloc_size = string.size + 1;
@ -414,7 +615,7 @@ file_track_store_new_dir_node(String dir_name_string, HANDLE dir_handle){
} }
Directory_Track_Node *new_node = file_track_dir_free_first; Directory_Track_Node *new_node = file_track_dir_free_first;
zdll_remove(file_track_dir_free_first, file_track_dir_free_last, new_node); zdll_remove(file_track_dir_free_first, file_track_dir_free_last, new_node);
zdll_push_back(file_track_dir_first, file_track_dir_last, new_node); alloc_insert_CString_Ptr_table(&file_track_dir_table, dir_name_string.str, dir_name_string.size, new_node);
memset(&new_node->overlapped, 0, sizeof(new_node->overlapped)); memset(&new_node->overlapped, 0, sizeof(new_node->overlapped));
new_node->dir_handle = dir_handle; new_node->dir_handle = dir_handle;
new_node->dir_name = file_track_store_string_copy(dir_name_string); new_node->dir_name = file_track_store_string_copy(dir_name_string);
@ -424,9 +625,9 @@ file_track_store_new_dir_node(String dir_name_string, HANDLE dir_handle){
internal void internal void
file_track_free_dir_node(Directory_Track_Node *node){ file_track_free_dir_node(Directory_Track_Node *node){
erase_CString_Ptr_table(&file_track_dir_table, node->dir_name.str, node->dir_name.size);
file_track_free_string(node->dir_name); file_track_free_string(node->dir_name);
memset(&node->dir_name, 0, sizeof(node->dir_name)); memset(&node->dir_name, 0, sizeof(node->dir_name));
zdll_remove(file_track_dir_first, file_track_dir_last, node);
zdll_push_back(file_track_dir_free_first, file_track_dir_free_last, node); zdll_push_back(file_track_dir_free_first, file_track_dir_free_last, node);
} }
@ -452,7 +653,7 @@ file_track_store_new_file_node(String file_name_string, Directory_Track_Node *ex
} }
File_Track_Node *new_node = file_track_free_first; File_Track_Node *new_node = file_track_free_first;
zdll_remove(file_track_free_first, file_track_free_last, new_node); zdll_remove(file_track_free_first, file_track_free_last, new_node);
zdll_push_back(file_track_first, file_track_last, new_node); alloc_insert_CString_Ptr_table(&file_track_table, file_name_string.str, file_name_string.size, new_node);
new_node->file_name = file_track_store_string_copy(file_name_string); new_node->file_name = file_track_store_string_copy(file_name_string);
new_node->ref_count = 1; new_node->ref_count = 1;
new_node->parent_dir = existing_dir_node; new_node->parent_dir = existing_dir_node;
@ -462,9 +663,9 @@ file_track_store_new_file_node(String file_name_string, Directory_Track_Node *ex
internal void internal void
file_track_free_file_node(File_Track_Node *node){ file_track_free_file_node(File_Track_Node *node){
erase_CString_Ptr_table(&file_track_table, node->file_name.str, node->file_name.size);
file_track_free_string(node->file_name); file_track_free_string(node->file_name);
memset(&node->file_name, 0, sizeof(node->file_name)); memset(&node->file_name, 0, sizeof(node->file_name));
zdll_remove(file_track_first, file_track_last, node);
zdll_push_back(file_track_free_first, file_track_free_last, node); zdll_push_back(file_track_free_first, file_track_free_last, node);
} }
@ -535,30 +736,16 @@ file_track_free_instruction_node(File_Track_Instruction_Node *node){
internal Directory_Track_Node* internal Directory_Track_Node*
file_track_dir_lookup(String dir_name_string){ file_track_dir_lookup(String dir_name_string){
Directory_Track_Node *existing_dir_node = 0; void *ptr = 0;
for (Directory_Track_Node *node = file_track_dir_first; lookup_CString_Ptr_table(&file_track_dir_table, dir_name_string.str, dir_name_string.size, &ptr);
node != 0; return((Directory_Track_Node*)ptr);
node = node->next){
if (match(dir_name_string, node->dir_name)){
existing_dir_node = node;
break;
}
}
return(existing_dir_node);
} }
internal File_Track_Node* internal File_Track_Node*
file_track_file_lookup(String file_name_string){ file_track_file_lookup(String file_name_string){
File_Track_Node *existing_file_node = 0; void *ptr = 0;
for (File_Track_Node *node = file_track_first; lookup_CString_Ptr_table(&file_track_table, file_name_string.str, file_name_string.size, &ptr);
node != 0; return((File_Track_Node*)ptr);
node = node->next){
if (match(file_name_string, node->file_name)){
existing_file_node = node;
break;
}
}
return(existing_file_node);
} }
internal DWORD CALL_CONVENTION internal DWORD CALL_CONVENTION

View File

@ -3,9 +3,8 @@
Features Features
{ {
[x] Fill Key_Input_Data's modifiers field [x] Fill Key_Input_Data's modifiers field
[] Recover scroll bars [x] Optimize lookup in file track data structures
[] Cold scroll [] Comment line/Uncomment line
[] Optimize lookup in file track data structures
} }
Bugs Bugs
@ -56,6 +55,8 @@ Long Term
[] Declarative system for keyword direct coloring [] Declarative system for keyword direct coloring
[] Reload all out of sync files [] Reload all out of sync files
[] Jump to Command Definition (useful for 4coder customization developers only) [] Jump to Command Definition (useful for 4coder customization developers only)
[] Recover scroll bars
[] Cold scroll
} }
Bugs Bugs