Optimized win32 file track node lookups
parent
790d21f517
commit
f0c39a267c
2
4ed.h
2
4ed.h
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
7
todo.txt
7
todo.txt
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue