fixed some bugs in the new word complete

This commit is contained in:
Allen Webster 2016-07-11 12:57:00 -04:00
parent 0d5f6e82d3
commit 174ff25d1a
2 changed files with 432 additions and 398 deletions

View File

@ -1,397 +1,431 @@
#ifndef FCODER_SEARCH #ifndef FCODER_SEARCH
#define FCODER_SEARCH #define FCODER_SEARCH
enum Search_Range_Type{ enum Search_Range_Type{
SearchRange_FrontToBack, SearchRange_FrontToBack,
SearchRange_BackToFront, SearchRange_BackToFront,
SearchRange_Wave, SearchRange_Wave,
}; };
struct Search_Range{ struct Search_Range{
int type; int type;
int buffer; int buffer;
int start; int start;
int size; int size;
int mid_start; int mid_start;
int mid_size; int mid_size;
}; };
struct Search_Set{ struct Search_Set{
Search_Range *ranges; Search_Range *ranges;
int count; int count;
int max; int max;
}; };
struct Search_Iter{ struct Search_Iter{
String word; String word;
int pos; int pos;
int back_pos; int back_pos;
int i; int i;
int range_initialized; int range_initialized;
}; };
struct Search_Match{ struct Search_Match{
Buffer_Summary buffer; Buffer_Summary buffer;
int start; int start;
int end; int end;
int found_match; int found_match;
}; };
static void static void
search_iter_init(Application_Links *app, Search_Iter *iter, int size){ search_iter_init(Application_Links *app, Search_Iter *iter, int size){
int str_max = size*2; int str_max = size*2;
if (iter->word.str == 0){ if (iter->word.str == 0){
iter->word.str = (char*)general_memory_allocate(&general, str_max); iter->word.str = (char*)general_memory_allocate(&general, str_max);
iter->word.memory_size = str_max; iter->word.memory_size = str_max;
} }
else if (iter->word.memory_size < size){ else if (iter->word.memory_size < size){
iter->word.str = (char*)general_memory_reallocate_nocopy(&general, iter->word.str, str_max); iter->word.str = (char*)general_memory_reallocate_nocopy(&general, iter->word.str, str_max);
iter->word.memory_size = str_max; iter->word.memory_size = str_max;
} }
iter->i = 0; iter->i = 0;
iter->pos = 0; iter->range_initialized = 0;
} }
static void static void
search_set_init(Application_Links *app, Search_Set *set, int range_count){ search_set_init(Application_Links *app, Search_Set *set, int range_count){
int max = range_count*2; int max = range_count*2;
if (set->ranges == 0){ if (set->ranges == 0){
set->ranges = (Search_Range*)general_memory_allocate(&general, sizeof(Search_Range)*max); set->ranges = (Search_Range*)general_memory_allocate(&general, sizeof(Search_Range)*max);
set->max = max; set->max = max;
} }
else if (set->max < range_count){ else if (set->max < range_count){
set->ranges = (Search_Range*)general_memory_reallocate_nocopy( set->ranges = (Search_Range*)general_memory_reallocate_nocopy(
&general, set->ranges, sizeof(Search_Range)*max); &general, set->ranges, sizeof(Search_Range)*max);
set->max = max; set->max = max;
} }
set->count = range_count; set->count = range_count;
} }
static void static void
search_hits_table_alloc(Application_Links *app, Table *hits, int table_size){ search_hits_table_alloc(Application_Links *app, Table *hits, int table_size){
void *mem = 0; void *mem = 0;
int mem_size = table_required_mem_size(table_size, sizeof(Offset_String)); int mem_size = table_required_mem_size(table_size, sizeof(Offset_String));
if (hits->hash_array == 0){ if (hits->hash_array == 0){
mem = general_memory_allocate(&general, mem_size); mem = general_memory_allocate(&general, mem_size);
} }
else{ else{
mem = general_memory_reallocate_nocopy(&general, hits->hash_array, mem_size); mem = general_memory_reallocate_nocopy(&general, hits->hash_array, mem_size);
} }
table_init_memory(hits, mem, table_size, sizeof(Offset_String)); table_init_memory(hits, mem, table_size, sizeof(Offset_String));
} }
static void static void
search_hits_init(Application_Links *app, Table *hits, String_Space *str, int table_size, int str_size){ search_hits_init(Application_Links *app, Table *hits, String_Space *str, int table_size, int str_size){
if (hits->hash_array == 0){ if (hits->hash_array == 0){
search_hits_table_alloc(app, hits, table_size); search_hits_table_alloc(app, hits, table_size);
} }
else{ else{
int mem_size = table_required_mem_size(table_size, sizeof(Offset_String)); int mem_size = table_required_mem_size(table_size, sizeof(Offset_String));
void *mem = general_memory_reallocate_nocopy(&general, hits->hash_array, mem_size); void *mem = general_memory_reallocate_nocopy(&general, hits->hash_array, mem_size);
table_init_memory(hits, mem, table_size, sizeof(Offset_String)); table_init_memory(hits, mem, table_size, sizeof(Offset_String));
} }
if (str->space == 0){ if (str->space == 0){
str->space = (char*)general_memory_allocate(&general, str_size); str->space = (char*)general_memory_allocate(&general, str_size);
str->max = str_size; str->max = str_size;
} }
else if (str->max < str_size){ else if (str->max < str_size){
str->space = (char*)general_memory_reallocate_nocopy(&general, str->space, str_size); str->space = (char*)general_memory_reallocate_nocopy(&general, str->space, str_size);
str->max = str_size; str->max = str_size;
} }
str->pos = str->new_pos = 0; str->pos = str->new_pos = 0;
table_clear(hits); table_clear(hits);
} }
static int static int
search_hit_add(Application_Links *app, Table *hits, String_Space *space, char *str, int len){ search_hit_add(Application_Links *app, Table *hits, String_Space *space, char *str, int len){
int result = false; int result = false;
assert(len != 0); assert(len != 0);
Offset_String ostring = strspace_append(space, str, len); Offset_String ostring = strspace_append(space, str, len);
if (ostring.size == 0){ if (ostring.size == 0){
int new_size = space->max*2; int new_size = space->max*2;
if (new_size < space->max + len){ if (new_size < space->max + len){
new_size = space->max + len; new_size = space->max + len;
} }
space->space = (char*)general_memory_reallocate( space->space = (char*)general_memory_reallocate(
&general, space->space, space->new_pos, new_size); &general, space->space, space->new_pos, new_size);
ostring = strspace_append(space, str, len); ostring = strspace_append(space, str, len);
} }
assert(ostring.size != 0); assert(ostring.size != 0);
if (table_at_capacity(hits)){ if (table_at_capacity(hits)){
Table new_hits = {0}; Table new_hits = {0};
search_hits_table_alloc(app, &new_hits, hits->max*2); search_hits_table_alloc(app, &new_hits, hits->max*2);
table_clear(&new_hits); table_clear(&new_hits);
table_rehash(hits, &new_hits, space->space, tbl_offset_string_hash, tbl_offset_string_compare); table_rehash(hits, &new_hits, space->space, tbl_offset_string_hash, tbl_offset_string_compare);
general_memory_free(&general, hits->hash_array); general_memory_free(&general, hits->hash_array);
*hits = new_hits; *hits = new_hits;
} }
if (!table_add(hits, &ostring, space->space, tbl_offset_string_hash, tbl_offset_string_compare)){ if (!table_add(hits, &ostring, space->space, tbl_offset_string_hash, tbl_offset_string_compare)){
result = true; result = true;
strspace_keep_prev(space); strspace_keep_prev(space);
} }
else{ else{
strspace_discard_prev(space); strspace_discard_prev(space);
} }
return(result); return(result);
} }
static int static int
buffer_seek_alpha_numeric_end(Application_Links *app, Buffer_Summary *buffer, int pos){ buffer_seek_alpha_numeric_end(Application_Links *app, Buffer_Summary *buffer, int pos){
char space[1024]; char space[1024];
Stream_Chunk chunk = {0}; Stream_Chunk chunk = {0};
if (init_stream_chunk(&chunk, app, buffer, pos, space, sizeof(space))){ if (init_stream_chunk(&chunk, app, buffer, pos, space, sizeof(space))){
int still_looping = true; int still_looping = true;
do{ do{
for (; pos < chunk.end; ++pos){ for (; pos < chunk.end; ++pos){
char at_pos = chunk.data[pos]; char at_pos = chunk.data[pos];
if (!char_is_alpha_numeric(at_pos)) goto double_break; if (!char_is_alpha_numeric(at_pos)) goto double_break;
} }
still_looping = forward_stream_chunk(&chunk); still_looping = forward_stream_chunk(&chunk);
}while(still_looping); }while(still_looping);
} }
double_break:; double_break:;
return(pos); return(pos);
} }
static void static void
search_iter_next_range(Search_Iter *it){ search_iter_next_range(Search_Iter *it){
++it->i; ++it->i;
it->pos = 0; it->pos = 0;
it->back_pos = 0; it->back_pos = 0;
it->range_initialized = 0; it->range_initialized = 0;
} }
enum{ enum{
FindResult_None, FindResult_None,
FindResult_FoundMatch, FindResult_FoundMatch,
FindResult_PastEnd FindResult_PastEnd
}; };
static int static int
search_front_to_back_step(Application_Links *app, search_front_to_back_step(Application_Links *app,
Search_Range *range, Search_Range *range,
String word, String word,
int *pos, int *pos,
Search_Match *result_ptr){ Search_Match *result_ptr){
int found_match = FindResult_None; int found_match = FindResult_None;
Search_Match result = *result_ptr; Search_Match result = *result_ptr;
int end_pos = range->start + range->size; int end_pos = range->start + range->size;
if (*pos + word.size < end_pos){ if (*pos + word.size < end_pos){
int start_pos = *pos; int start_pos = *pos;
if (start_pos < range->start){ if (start_pos < range->start){
start_pos = range->start; start_pos = range->start;
} }
result.buffer = app->get_buffer(app, range->buffer, AccessAll); result.buffer = app->get_buffer(app, range->buffer, AccessAll);
buffer_seek_string_forward(app, &result.buffer, buffer_seek_string_forward(app, &result.buffer,
start_pos, end_pos, start_pos, end_pos,
word.str, word.size, word.str, word.size,
&result.start); &result.start);
if (result.start < end_pos){ if (result.start < end_pos){
*pos = result.start + 1; *pos = result.start + 1;
char prev = ' '; char prev = ' ';
if (result.start > 0){ if (result.start > 0){
prev = buffer_get_char(app, &result.buffer, result.start - 1); prev = buffer_get_char(app, &result.buffer, result.start - 1);
} }
if (!char_is_alpha_numeric(prev)){ if (!char_is_alpha_numeric(prev)){
result.end = result.end =
buffer_seek_alpha_numeric_end( buffer_seek_alpha_numeric_end(
app, &result.buffer, result.start); app, &result.buffer, result.start);
if (result.end < end_pos){ if (result.end < end_pos){
result.found_match = true; result.found_match = true;
*pos = result.end; *pos = result.end;
found_match = FindResult_FoundMatch; found_match = FindResult_FoundMatch;
} }
} }
} }
else{ else{
found_match = FindResult_PastEnd; found_match = FindResult_PastEnd;
} *pos = end_pos + 1;
} }
else{ }
found_match = FindResult_PastEnd; else{
} found_match = FindResult_PastEnd;
*pos = end_pos + 1;
*result_ptr = result; }
return(found_match); *result_ptr = result;
}
return(found_match);
static int }
search_back_to_front_step(Application_Links *app,
Search_Range *range, static int
String word, search_front_to_back(Application_Links *app,
int *pos, Search_Range *range,
Search_Match *result_ptr){ String word,
int found_match = FindResult_None; int *pos,
Search_Match *result_ptr){
Search_Match result = *result_ptr; int found_match = FindResult_None;
for (;found_match == FindResult_None;){
int end_pos = range->start + range->size; found_match = search_front_to_back_step(app, range, word, pos, result_ptr);
if (*pos > range->start){ }
int start_pos = *pos; return(found_match);
}
result.buffer = app->get_buffer(app, range->buffer, AccessAll);
buffer_seek_string_backward(app, &result.buffer, static int
start_pos, range->start, search_back_to_front_step(Application_Links *app,
word.str, word.size, Search_Range *range,
&result.start); String word,
int *pos,
if (result.start >= range->start){ Search_Match *result_ptr){
*pos = result.start - 1; int found_match = FindResult_None;
char prev = ' ';
if (result.start > 0){ Search_Match result = *result_ptr;
prev = buffer_get_char(app, &result.buffer, result.start - 1);
} int end_pos = range->start + range->size;
if (!char_is_alpha_numeric(prev)){ if (*pos > range->start){
result.end = int start_pos = *pos;
buffer_seek_alpha_numeric_end(
app, &result.buffer, result.start); result.buffer = app->get_buffer(app, range->buffer, AccessAll);
buffer_seek_string_backward(app, &result.buffer,
if (result.end < end_pos){ start_pos, range->start,
result.found_match = true; word.str, word.size,
*pos = result.start - word.size; &result.start);
found_match = FindResult_FoundMatch;
} if (result.start >= range->start){
} *pos = result.start - 1;
} char prev = ' ';
else{ if (result.start > 0){
found_match = FindResult_PastEnd; prev = buffer_get_char(app, &result.buffer, result.start - 1);
} }
} if (!char_is_alpha_numeric(prev)){
else{ result.end =
found_match = FindResult_PastEnd; buffer_seek_alpha_numeric_end(
} app, &result.buffer, result.start);
*result_ptr = result; if (result.end < end_pos){
result.found_match = true;
return(found_match); *pos = result.start - word.size;
} found_match = FindResult_FoundMatch;
}
static Search_Match }
search_next_match(Application_Links *app, Search_Set *set, Search_Iter *it_ptr){ }
Search_Match result = {0}; else{
Search_Iter iter = *it_ptr; found_match = FindResult_PastEnd;
}
int count = set->count; }
for (; iter.i < count;){ else{
Search_Range *range = set->ranges + iter.i; found_match = FindResult_PastEnd;
}
int find_result = FindResult_None;
*result_ptr = result;
if (!iter.range_initialized){
iter.range_initialized = true; return(found_match);
switch (range->type){ }
case SearchRange_BackToFront:
{ static int
iter.back_pos = range->start+range->size-1; search_back_to_front(Application_Links *app,
}break; Search_Range *range,
String word,
case SearchRange_Wave: int *pos,
{ Search_Match *result_ptr){
iter.back_pos = range->mid_start-1; int found_match = FindResult_None;
iter.pos = range->mid_start + range->mid_size; for (;found_match == FindResult_None;){
}break; found_match = search_back_to_front_step(app, range, word, pos, result_ptr);
} }
} return(found_match);
}
switch (range->type){
case SearchRange_FrontToBack: static Search_Match
{ search_next_match(Application_Links *app, Search_Set *set, Search_Iter *it_ptr){
find_result = Search_Match result = {0};
search_front_to_back_step(app, range, Search_Iter iter = *it_ptr;
iter.word,
&iter.pos, int count = set->count;
&result); for (; iter.i < count;){
}break; Search_Range *range = set->ranges + iter.i;
case SearchRange_BackToFront: int find_result = FindResult_None;
{
find_result = if (!iter.range_initialized){
search_back_to_front_step(app, range, iter.range_initialized = true;
iter.word, switch (range->type){
&iter.back_pos, case SearchRange_BackToFront:
&result); {
}break; iter.back_pos = range->start+range->size-1;
}break;
case SearchRange_Wave:
{ case SearchRange_Wave:
Search_Match forward_match = {0}; {
int forward_result = iter.back_pos = range->mid_start-1;
search_front_to_back_step(app, range, iter.pos = range->mid_start + range->mid_size;
iter.word, }break;
&iter.pos, }
&forward_match); }
Search_Match backward_match = {0}; switch (range->type){
int backward_result = case SearchRange_FrontToBack:
search_back_to_front_step(app, range, {
iter.word, find_result =
&iter.back_pos, search_front_to_back(app, range,
&backward_match); iter.word,
&iter.pos,
if (forward_result == FindResult_FoundMatch){ &result);
if (backward_result == FindResult_FoundMatch){ }break;
find_result = FindResult_FoundMatch;
case SearchRange_BackToFront:
int forward_start = range->mid_start + range->mid_size; {
int forward_distance = (forward_match.start - forward_start); find_result =
int backward_distance = (forward_match.end - range->mid_start); search_back_to_front(app, range,
iter.word,
if (backward_distance < forward_distance){ &iter.back_pos,
--iter.pos; &result);
result = forward_match; }break;
}
else{ case SearchRange_Wave:
++iter.back_pos; {
result = backward_match; Search_Match forward_match = {0};
} Search_Match backward_match = {0};
}
else{ int forward_result = FindResult_PastEnd;
find_result = FindResult_FoundMatch; int backward_result = FindResult_PastEnd;
result = forward_match;
} if (iter.pos < range->start + range->size){
} forward_result = search_front_to_back(app, range,
else{ iter.word,
if (backward_result == FindResult_FoundMatch){ &iter.pos,
find_result = FindResult_FoundMatch; &forward_match);
result = backward_match; }
--iter.pos;
} if (iter.back_pos > range->start){
else{ backward_result = search_back_to_front(app, range,
find_result = FindResult_PastEnd; iter.word,
} &iter.back_pos,
} &backward_match);
}break; }
}
if (forward_result == FindResult_FoundMatch){
if (find_result == FindResult_FoundMatch){ if (backward_result == FindResult_FoundMatch){
goto double_break; find_result = FindResult_FoundMatch;
}
else if (find_result == FindResult_PastEnd){ int forward_start = range->mid_start + range->mid_size;
search_iter_next_range(&iter); int forward_distance = (forward_match.start - forward_start);
} int backward_distance = (range->mid_start - backward_match.end);
}
double_break:; if (backward_distance < forward_distance){
iter.pos = forward_match.start;
*it_ptr = iter; result = backward_match;
}
return(result); else{
} iter.back_pos = backward_match.start;
result = forward_match;
#endif }
}
else{
find_result = FindResult_FoundMatch;
result = forward_match;
}
}
else{
if (backward_result == FindResult_FoundMatch){
find_result = FindResult_FoundMatch;
result = backward_match;
--iter.pos;
}
else{
find_result = FindResult_PastEnd;
}
}
}break;
}
if (find_result == FindResult_FoundMatch){
goto double_break;
}
else if (find_result == FindResult_PastEnd){
search_iter_next_range(&iter);
}
}
double_break:;
*it_ptr = iter;
return(result);
}
#endif

View File

@ -1,4 +1,4 @@
Distribution Date: 8.7.2016 (dd.mm.yyyy) Distribution Date: 11.7.2016 (dd.mm.yyyy)
Thank you for contributing to the 4coder project! Thank you for contributing to the 4coder project!