From 68eefd8c199cfcf53cfbdf5714bb71c9ac83c212 Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Fri, 11 Mar 2016 16:54:32 -0500 Subject: [PATCH] new file identification scheme up and running --- 4ed.cpp | 37 ++++++++++++------ 4ed_file.cpp | 97 ++++++++++++++++++++++++++++++++++++++++------- 4ed_file_view.cpp | 5 +++ 4ed_system.h | 2 +- 4tech_table.cpp | 8 ++-- win32_4ed.cpp | 24 +++++++----- 6 files changed, 133 insertions(+), 40 deletions(-) diff --git a/4ed.cpp b/4ed.cpp index a9eeccc5..aadf0fea 100644 --- a/4ed.cpp +++ b/4ed.cpp @@ -1732,27 +1732,37 @@ COMMAND_DECL(command_line){ if (vars->cli_processes.count < vars->cli_processes.max){ if (buffer_id){ file = working_set_get_active_file(working_set, buffer_id); + if (file && file->settings.read_only == 0){ + // TODO(allen): feedback message - file not read only + return; + } } else if (buffer_name){ file = working_set_contains(system, working_set, make_string(buffer_name, buffer_name_len)); - if (file == 0){ + if (file){ + if (file->settings.read_only == 0){ + // TODO(allen): feedback message - file not read only + return; + } + } + else{ file = working_set_alloc_always(working_set, &models->mem.general); + + file_create_read_only(system, models, file, buffer_name); + working_set_add(system, working_set, file); + if (file == 0){ // TODO(allen): feedback message - no available file return; } } } - + if (file){ i32 proc_count = vars->cli_processes.count; View_Iter iter; i32 i; - - file_create_read_only(system, models, file, buffer_name); - file->settings.unimportant = 1; - working_set_add(system, working_set, file); - + for (i = 0; i < proc_count; ++i){ if (procs[i].out_file == file){ if (flags & CLI_OverlapWithConflict) @@ -1762,8 +1772,11 @@ COMMAND_DECL(command_line){ break; } } - + if (file){ + file_clear(system, models, file, 1); + file->settings.unimportant = 1; + if (!(flags & CLI_AlwaysBindToView)){ iter = file_view_iter_init(&models->layout, file, 0); if (file_view_iter_good(iter)){ @@ -1776,7 +1789,7 @@ COMMAND_DECL(command_line){ return; } } - + if (!path){ path = models->hot_directory.string.str; terminate_with_null(&models->hot_directory.string); @@ -4036,7 +4049,7 @@ App_Step_Sig(app_step){ } } else{ - table_remove(&models->working_set.table, ed_file->name.source_path); + working_set_remove(system, &models->working_set, ed_file->name.source_path); working_set_free_file(&models->working_set, ed_file); } @@ -4270,7 +4283,7 @@ App_Step_Sig(app_step){ } if (file){ - table_remove(&working_set->table, file->name.source_path); + working_set_remove(system, working_set, file->name.source_path); kill_file(system, exchange, models, file, models->hooks[hook_open_file], &app_links); } @@ -4301,7 +4314,7 @@ App_Step_Sig(app_step){ copy(&view->dest, file->name.live_name); } else{ - table_remove(&working_set->table, file->name.source_path); + working_set_remove(system, working_set, file->name.source_path); kill_file(system, exchange, models, file, models->hooks[hook_open_file], &app_links); } diff --git a/4ed_file.cpp b/4ed_file.cpp index 409e8e01..1cb0f97b 100644 --- a/4ed_file.cpp +++ b/4ed_file.cpp @@ -257,6 +257,11 @@ table_remove(File_Table *table, String name){ } #endif +struct Non_File_Table_Entry{ + String name; + File_ID id; +}; + struct File_Table_Entry{ Unique_Hash key; File_ID id; @@ -277,7 +282,7 @@ internal i32 tbl_file_compare(void *a, void *b, void *arg){ Unique_Hash ahash = *((Unique_Hash*)a); Unique_Hash bhash = *((Unique_Hash*)b); - i32 result = uhash_equal(ahash, bhash); + i32 result = !uhash_equal(ahash, bhash); return(result); } @@ -294,6 +299,7 @@ struct Working_Set{ File_Node free_sentinel; File_Node used_sentinel; + Table non_file_table; Table table; String clipboards[64]; @@ -415,7 +421,7 @@ working_set_get_active_file(Working_Set *working_set, i32 id){ } inline Editing_File* -working_set_contains(Working_Set *working_set, Unique_Hash file_hash){ +working_set_contains_file(Working_Set *working_set, Unique_Hash file_hash){ Editing_File *result = 0; File_Table_Entry *entry = 0; @@ -428,13 +434,33 @@ working_set_contains(Working_Set *working_set, Unique_Hash file_hash){ return (result); } +inline Editing_File* +working_set_contains_non_file(Working_Set *working_set, String filename){ + Editing_File *result = 0; + Non_File_Table_Entry *entry = 0; + + entry = (Non_File_Table_Entry*)table_find_item( + &working_set->non_file_table, &filename, 0, tbl_string_hash, tbl_string_compare); + if (entry){ + result = working_set_index(working_set, entry->id); + } + + return (result); +} + inline Editing_File* working_set_contains(System_Functions *system, Working_Set *working_set, String filename){ Unique_Hash file_hash; Editing_File *result; - terminate_with_null(&filename); - file_hash = system->file_unique_hash(filename.str); - result = working_set_contains(working_set, file_hash); + b32 success = 0; + //terminate_with_null(&filename); + file_hash = system->file_unique_hash(filename, &success); + if (success){ + result = working_set_contains_file(working_set, file_hash); + } + else{ + result = working_set_contains_non_file(working_set, filename); + } return(result); } @@ -442,7 +468,7 @@ internal void working_set_init(Working_Set *working_set, Partition *partition){ Editing_File *files, *null_file; void *mem; - i32 mem_size; + i32 mem_size, table_size; i16 init_count = 128; dll_init_sentinel(&working_set->free_sentinel); @@ -459,26 +485,69 @@ working_set_init(Working_Set *working_set, Partition *partition){ null_file->state.is_dummy = 1; ++working_set->file_count; - mem_size = table_required_mem_size(working_set->file_max * 3 / 2, sizeof(File_Table_Entry)); + table_size = working_set->file_max * 3 / 2; + mem_size = table_required_mem_size(table_size, sizeof(File_Table_Entry)); mem = push_block(partition, mem_size); memset(mem, 0, mem_size); - table_init_memory(&working_set->table, mem, working_set->file_max * 3 / 2, sizeof(File_Table_Entry)); + table_init_memory(&working_set->table, mem, table_size, sizeof(File_Table_Entry)); + + table_size = working_set->file_max / 4; + mem_size = table_required_mem_size(table_size, sizeof(Non_File_Table_Entry)); + mem = push_block(partition, mem_size); + memset(mem, 0, mem_size); + table_init_memory(&working_set->non_file_table, mem, table_size, sizeof(Non_File_Table_Entry)); } -internal void -working_set_add(Working_Set *working_set, Unique_Hash key, File_ID file_id){ +inline void +working_set_add_file(Working_Set *working_set, Unique_Hash key, File_ID file_id){ File_Table_Entry entry; entry.key = key; entry.id = file_id; - table_add(&working_set->table, &entry, 0, tbl_file_hash, tbl_file_compare); } -internal void +inline void +working_set_add_non_file(Working_Set *working_set, String filename, File_ID file_id){ + Non_File_Table_Entry entry; + entry.name = filename; + entry.id = file_id; + table_add(&working_set->non_file_table, &entry, 0, tbl_string_hash, tbl_string_compare); +} + +inline void working_set_add(System_Functions *system, Working_Set *working_set, Editing_File *file){ Unique_Hash file_hash; - file_hash = system->file_unique_hash(file->name.source_path.str); - working_set_add(working_set, file_hash, file->id); + b32 success = 0; + file_hash = system->file_unique_hash(file->name.source_path, &success); + if (success){ + working_set_add_file(working_set, file_hash, file->id); + } + else{ + working_set_add_non_file(working_set, file->name.source_path, file->id); + } +} + +inline void +working_set_remove_file(Working_Set *working_set, Unique_Hash file_hash){ + table_remove_match(&working_set->table, &file_hash, 0, tbl_file_hash, tbl_file_compare); +} + +inline void +working_set_remove_non_file(Working_Set *working_set, String filename){ + table_remove_match(&working_set->non_file_table, &filename, 0, tbl_string_hash, tbl_string_compare); +} + +inline void +working_set_remove(System_Functions *system, Working_Set *working_set, String filename){ + Unique_Hash file_hash; + b32 success = 0; + file_hash = system->file_unique_hash(filename, &success); + if (success){ + working_set_remove_file(working_set, file_hash); + } + else{ + working_set_remove_non_file(working_set, filename); + } } // TODO(allen): Pick better first options. diff --git a/4ed_file_view.cpp b/4ed_file_view.cpp index 41e08782..9cec9e44 100644 --- a/4ed_file_view.cpp +++ b/4ed_file_view.cpp @@ -1831,6 +1831,11 @@ file_replace_range(System_Functions *system, Models *models, Editing_File *file, file_do_single_edit(system, models, file, spec, hist_normal, use_high_permission); } +inline void +file_clear(System_Functions *system, Models *models, Editing_File *file, b32 use_high_permission = 0){ + file_replace_range(system, models, file, 0, buffer_size(&file->state.buffer), 0, 0, 0, use_high_permission); +} + inline void view_replace_range(System_Functions *system, Models *models, View *view, i32 start, i32 end, char *str, i32 len, i32 next_cursor){ diff --git a/4ed_system.h b/4ed_system.h index 90d2b39f..2d7d06b2 100644 --- a/4ed_system.h +++ b/4ed_system.h @@ -37,7 +37,7 @@ typedef Sys_File_Time_Stamp_Sig(System_File_Time_Stamp); #define Sys_Set_File_List_Sig(name) void name(File_List *file_list, String directory) typedef Sys_Set_File_List_Sig(System_Set_File_List); -#define Sys_File_Unique_Hash_Sig(name) Unique_Hash name(char *filename) +#define Sys_File_Unique_Hash_Sig(name) Unique_Hash name(String filename, b32 *success) typedef Sys_File_Unique_Hash_Sig(System_File_Unique_Hash); #define Sys_Post_Clipboard_Sig(name) void name(String str) diff --git a/4tech_table.cpp b/4tech_table.cpp index 613b134b..ceab37da 100644 --- a/4tech_table.cpp +++ b/4tech_table.cpp @@ -113,7 +113,7 @@ table_find_pos(Table *table, void *search_key, void *arg, i32 *pos, i32 *index, return(0); } -internal void* +inline void* table_find_item(Table *table, void *search_key, void *arg, Hash_Function *hash_func, Compare_Function *comp_func){ i32 pos; void *result = 0; @@ -123,13 +123,13 @@ table_find_item(Table *table, void *search_key, void *arg, Hash_Function *hash_f return(result); } -internal void +inline void table_remove_index(Table *table, i32 index){ table->hash_array[index] = TableHashDeleted; --table->count; } -internal b32 +inline b32 table_remove_match(Table *table, void *search_key, void *arg, Hash_Function *hash_func, Compare_Function *comp_func){ i32 index; b32 result = 0; @@ -140,7 +140,7 @@ table_remove_match(Table *table, void *search_key, void *arg, Hash_Function *has return(result); } -internal void +inline void table_clear(Table *table){ table->count = 0; memset(table->hash_array, 0, table->max*sizeof(*table->hash_array)); diff --git a/win32_4ed.cpp b/win32_4ed.cpp index 9b53a733..51925479 100644 --- a/win32_4ed.cpp +++ b/win32_4ed.cpp @@ -461,20 +461,26 @@ Sys_Set_File_List_Sig(system_set_file_list){ } } +// TODO(allen): proper "is terminated" check internal Sys_File_Unique_Hash_Sig(system_file_unique_hash){ - Unique_Hash hash; + Unique_Hash hash = {0}; BY_HANDLE_FILE_INFORMATION info; HANDLE handle; - - handle = CreateFile(filename, GENERIC_READ, 0, 0, + + handle = CreateFile(filename.str, GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); - - hash = {0}; - if (GetFileInformationByHandle(handle, &info)){ - hash.d[2] = info.dwVolumeSerialNumber; - hash.d[1] = info.nFileIndexHigh; - hash.d[0] = info.nFileIndexLow; + + *success = 0; + if (handle && handle != INVALID_HANDLE_VALUE){ + if (GetFileInformationByHandle(handle, &info)){ + hash.d[2] = info.dwVolumeSerialNumber; + hash.d[1] = info.nFileIndexHigh; + hash.d[0] = info.nFileIndexLow; + *success = 1; + } + + CloseHandle(handle); } return(hash);