diff --git a/4ed_file_view.cpp b/4ed_file_view.cpp index 6e3fe123..09461b68 100644 --- a/4ed_file_view.cpp +++ b/4ed_file_view.cpp @@ -2517,7 +2517,9 @@ file_do_single_edit(Mem_Options *mem, Editing_File *file, if (old_data) general_memory_free(general, old_data); } +#if BUFFER_EXPERIMENT_SCALPEL == 3 buffer_rope_check(&file->buffer, part->base + part->pos, scratch_size); +#endif #if BUFFER_EXPERIMENT_SCALPEL == 2 buffer_mugab_check(&file->buffer); diff --git a/buffer/4coder_buffer_abstract.cpp b/buffer/4coder_buffer_abstract.cpp index a7174603..998c50cd 100644 --- a/buffer/4coder_buffer_abstract.cpp +++ b/buffer/4coder_buffer_abstract.cpp @@ -546,8 +546,7 @@ buffer_measure_starts_end: #endif internal_4tech int -buffer_measure_starts_widths(Buffer_Measure_Starts *state, Buffer_Type *buffer, - float *advance_data){ +buffer_measure_starts_widths(Buffer_Measure_Starts *state, Buffer_Type *buffer, float *advance_data){ Buffer_Stringify_Type loop; int *start_ptr, *start_end; float *width_ptr; diff --git a/buffer/4coder_multi_gap_buffer.cpp b/buffer/4coder_multi_gap_buffer.cpp index ea91001a..3b385d6b 100644 --- a/buffer/4coder_multi_gap_buffer.cpp +++ b/buffer/4coder_multi_gap_buffer.cpp @@ -542,7 +542,8 @@ buffer_replace_range(Multi_Gap_Buffer *buffer, int start, int end, char *str, in } else{ middle_size = 0; - assert_4tech(head_size + tail_size >= len); + head_size = len - tail_size; + assert_4tech(head_size + gap->size1 <= fixed_width_buffer_size); } } else{ @@ -585,7 +586,7 @@ buffer_replace_range(Multi_Gap_Buffer *buffer, int start, int end, char *str, in mem_pos += tail_size; assert_4tech(mem_pos == len); debug_4tech(local_start_pos += gap->size1 + gap->size2); - assert_4tech(local_start_pos == buffer->size); + //assert_4tech(local_start_pos == buffer->size); buffer->chunk_count += required_empty_buffers; diff --git a/buffer/4coder_test_abstract.cpp b/buffer/4coder_test_abstract.cpp index 39801040..671ab18b 100644 --- a/buffer/4coder_test_abstract.cpp +++ b/buffer/4coder_test_abstract.cpp @@ -63,5 +63,80 @@ measure_starts_widths(Buffer_Type *buffer, float *font_widths){ buffer->widths_count = state.count; } +void +edit(Buffer_Type *buffer, int start, int end, char *word, int len, + float *advance_data, void *scratch, int scratch_size){ + int shift_amount, request_amount; + + for (;buffer_replace_range(buffer, start, end, word, len, &shift_amount, + scratch, scratch_size, &request_amount);){ + void *new_data = 0; + if (request_amount > 0) new_data = malloc(request_amount); + void *old_data = buffer_edit_provide_memory(buffer, new_data, request_amount); + if (old_data) free(old_data); + } + + int line_start = buffer_get_line_index(buffer, start); + int line_end = buffer_get_line_index(buffer, end); + int replaced_line_count = line_end - line_start; + int new_line_count = buffer_count_newlines(buffer, start, start+len); + int line_shift = new_line_count - replaced_line_count; + + { + assert_4tech(buffer->line_starts); + int count = buffer->line_count; + if (count + line_shift > buffer->line_max){ + int new_max = round_up_4tech(buffer->line_max + line_shift, 1 << 10); + int *new_lines = (int*)malloc(sizeof(int)*new_max); + memcpy_4tech(new_lines, buffer->line_starts, sizeof(int)*count); + free(buffer->line_starts); + + buffer->line_starts = new_lines; + buffer->line_max = new_max; + } + + buffer_remeasure_starts(buffer, line_start, line_end, line_shift, shift_amount); + } + + { + assert_4tech(buffer->line_widths); + if (buffer->line_count > buffer->widths_max){ + int new_max = round_up_4tech(buffer->line_max, 1 << 10); + float *new_widths = (float*)malloc(sizeof(float)*new_max); + memcpy_4tech(new_widths, buffer->line_widths, sizeof(float)*buffer->widths_count); + free(buffer->line_widths); + + buffer->line_widths = new_widths; + buffer->widths_max = new_max; + } + + buffer_remeasure_widths(buffer, advance_data, line_start, line_end, line_shift); + } +} + +void +insert_bottom(Buffer_Type *buffer, char *word, int len, float *advance_data, void *scratch, int scratch_size){ + int size; + size = buffer_size(buffer); + edit(buffer, size, size, word, len, advance_data, scratch, scratch_size); +} + +void +insert_top(Buffer_Type *buffer, char *word, int len, float *advance_data, void *scratch, int scratch_size){ + edit(buffer, 0, 0, word, len, advance_data, scratch, scratch_size); +} + +void +delete_bottom(Buffer_Type *buffer, int len, float *advance_data, void *scratch, int scratch_size){ + int size; + size = buffer_size(buffer); + edit(buffer, size - len, size, 0, 0, advance_data, scratch, scratch_size); +} + +void +delete_top(Buffer_Type *buffer, int len, float *advance_data, void *scratch, int scratch_size){ + edit(buffer, 0, len, 0, 0, advance_data, scratch, scratch_size); +} + // BOTTOM diff --git a/buffer/4coder_test_main.cpp b/buffer/4coder_test_main.cpp index 9c41399e..c46093ad 100644 --- a/buffer/4coder_test_main.cpp +++ b/buffer/4coder_test_main.cpp @@ -928,6 +928,45 @@ full_cursor_xy_test(Stats_Log *log, Buffer_Set *buffers, float x, float y, int r log_sample_set(log, litstr("full-cursor-seek"), stats_out, machine.samples, machine.count); } +void +word_seek_test(Stats_Log *log, Buffer_Set *buffers, int test_repitions, + int incremental_position, char *word, int len, + void *scratch, int scratch_size, Record_Statistics *stats_out){ + Sample_Machine machine; + machine = begin_machine(test_repitions, &scratch, &scratch_size); + assert_4tech(scratch_size >= len); + + int pos, pos2, old_pos; + old_pos = 0; + + for (int i = 0; i < machine.count; ++i){ + start(&machine); + pos = buffer_find_string(&buffers->buffer, old_pos, word, len, (char*)scratch); + machine.samples[i].buffer = stop(&machine); + + start(&machine); + pos2 = buffer_find_string(&buffers->gap_buffer, old_pos, word, len, (char*)scratch); + machine.samples[i].gap_buffer = stop(&machine); + assert_4tech(pos2 == pos); + + start(&machine); + pos2 = buffer_find_string(&buffers->multi_gap_buffer, old_pos, word, len, (char*)scratch); + machine.samples[i].multi_gap_buffer = stop(&machine); + assert_4tech(pos2 == pos); + + start(&machine); + pos2 = buffer_find_string(&buffers->rope_buffer, old_pos, word, len, (char*)scratch); + machine.samples[i].rope_buffer = stop(&machine); + assert_4tech(pos2 == pos); + + if (incremental_position) old_pos = pos; + } + + end_machine(&machine, stats_out, __FUNCTION__); + + log_sample_set(log, litstr("word-seek"), stats_out, machine.samples, machine.count); +} + void stream_check_test(Buffer_Set *buffers, void *scratch, int scratch_size){ int i, page_size, size; @@ -983,6 +1022,200 @@ stream_check_test(Buffer_Set *buffers, void *scratch, int scratch_size){ } } +void +insert_bottom_test(Stats_Log *log, Buffer_Set *buffers, int test_repitions, float *advance_data, + int edit_count, void *scratch, int scratch_size, Record_Statistics *stats_out){ + Sample_Machine machine; + machine = begin_machine(test_repitions, &scratch, &scratch_size); + + char word[] = "stuff"; + int word_len = sizeof(word) - 1; + + int i, j; + for (i = 0; i < test_repitions; ++i){ + start(&machine); + for (j = 0; j < edit_count; ++j){ + insert_bottom(&buffers->buffer, word, word_len, + advance_data, scratch, scratch_size); + } + machine.samples[i].buffer = stop(&machine); + + start(&machine); + for (j = 0; j < edit_count; ++j){ + insert_bottom(&buffers->gap_buffer, word, word_len, + advance_data, scratch, scratch_size); + } + machine.samples[i].gap_buffer = stop(&machine); + + start(&machine); + for (j = 0; j < edit_count; ++j){ + insert_bottom(&buffers->multi_gap_buffer, word, word_len, + advance_data, scratch, scratch_size); + } + machine.samples[i].multi_gap_buffer = stop(&machine); + + start(&machine); + for (j = 0; j < edit_count; ++j){ + insert_bottom(&buffers->rope_buffer, word, word_len, + advance_data, scratch, scratch_size); + } + machine.samples[i].rope_buffer = stop(&machine); + + if (i == 0){ + stream_check_test(buffers, scratch, scratch_size); + } + } + + end_machine(&machine, stats_out, __FUNCTION__); + + log_sample_set(log, litstr("insert-bottom"), stats_out, machine.samples, machine.count); +} + +void +insert_top_test(Stats_Log *log, Buffer_Set *buffers, int test_repitions, float *advance_data, + int edit_count, void *scratch, int scratch_size, Record_Statistics *stats_out){ + Sample_Machine machine; + machine = begin_machine(test_repitions, &scratch, &scratch_size); + + char word[] = "stuff"; + int word_len = sizeof(word) - 1; + + int i, j; + for (i = 0; i < test_repitions; ++i){ + start(&machine); + for (j = 0; j < edit_count; ++j){ + insert_top(&buffers->buffer, word, word_len, + advance_data, scratch, scratch_size); + } + machine.samples[i].buffer = stop(&machine); + + start(&machine); + for (j = 0; j < edit_count; ++j){ + insert_top(&buffers->gap_buffer, word, word_len, + advance_data, scratch, scratch_size); + } + machine.samples[i].gap_buffer = stop(&machine); + + start(&machine); + for (j = 0; j < edit_count; ++j){ + insert_top(&buffers->multi_gap_buffer, word, word_len, + advance_data, scratch, scratch_size); + } + machine.samples[i].multi_gap_buffer = stop(&machine); + + start(&machine); + for (j = 0; j < edit_count; ++j){ + insert_top(&buffers->rope_buffer, word, word_len, + advance_data, scratch, scratch_size); + } + machine.samples[i].rope_buffer = stop(&machine); + + if (i == 0){ + stream_check_test(buffers, scratch, scratch_size); + } + } + + end_machine(&machine, stats_out, __FUNCTION__); + + log_sample_set(log, litstr("insert-top"), stats_out, machine.samples, machine.count); +} + +void +delete_bottom_test(Stats_Log *log, Buffer_Set *buffers, int test_repitions, float *advance_data, + int edit_count, void *scratch, int scratch_size, Record_Statistics *stats_out){ + Sample_Machine machine; + machine = begin_machine(test_repitions, &scratch, &scratch_size); + + int len = 5; + + int i, j; + for (i = 0; i < test_repitions; ++i){ + start(&machine); + for (j = 0; j < edit_count; ++j){ + delete_bottom(&buffers->buffer, len, + advance_data, scratch, scratch_size); + } + machine.samples[i].buffer = stop(&machine); + + start(&machine); + for (j = 0; j < edit_count; ++j){ + delete_bottom(&buffers->gap_buffer, len, + advance_data, scratch, scratch_size); + } + machine.samples[i].gap_buffer = stop(&machine); + + start(&machine); + for (j = 0; j < edit_count; ++j){ + delete_bottom(&buffers->multi_gap_buffer, len, + advance_data, scratch, scratch_size); + } + machine.samples[i].multi_gap_buffer = stop(&machine); + + start(&machine); + for (j = 0; j < edit_count; ++j){ + delete_bottom(&buffers->rope_buffer, len, + advance_data, scratch, scratch_size); + } + machine.samples[i].rope_buffer = stop(&machine); + + if (i == 0){ + stream_check_test(buffers, scratch, scratch_size); + } + } + + end_machine(&machine, stats_out, __FUNCTION__); + + log_sample_set(log, litstr("delete-bottom"), stats_out, machine.samples, machine.count); +} + +void +delete_top_test(Stats_Log *log, Buffer_Set *buffers, int test_repitions, float *advance_data, + int edit_count, void *scratch, int scratch_size, Record_Statistics *stats_out){ + Sample_Machine machine; + machine = begin_machine(test_repitions, &scratch, &scratch_size); + + int len = 5; + + int i, j; + for (i = 0; i < test_repitions; ++i){ + start(&machine); + for (j = 0; j < edit_count; ++j){ + delete_top(&buffers->buffer, len, + advance_data, scratch, scratch_size); + } + machine.samples[i].buffer = stop(&machine); + + start(&machine); + for (j = 0; j < edit_count; ++j){ + delete_top(&buffers->gap_buffer, len, + advance_data, scratch, scratch_size); + } + machine.samples[i].gap_buffer = stop(&machine); + + start(&machine); + for (j = 0; j < edit_count; ++j){ + delete_top(&buffers->multi_gap_buffer, len, + advance_data, scratch, scratch_size); + } + machine.samples[i].multi_gap_buffer = stop(&machine); + + start(&machine); + for (j = 0; j < edit_count; ++j){ + delete_top(&buffers->rope_buffer, len, + advance_data, scratch, scratch_size); + } + machine.samples[i].rope_buffer = stop(&machine); + + if (i == 0){ + stream_check_test(buffers, scratch, scratch_size); + } + } + + end_machine(&machine, stats_out, __FUNCTION__); + + log_sample_set(log, litstr("delete-top"), stats_out, machine.samples, machine.count); +} + void measure_check_test(Buffer_Set *buffers){ int count; @@ -1137,6 +1370,41 @@ int main(int argc, char **argv){ } log_end_section(&log); + log_begin_section(&log, litstr("word-seek")); + { + Record_Statistics word_seek; + + { + char word[] = "not-going-to-find-this"; + int word_len = sizeof(word) - 1; + + word_seek_test(&log, &buffers, 25, 0, word, word_len, scratch, scratch_size, &word_seek); + + } + + { + char word[] = "return"; + int word_len = sizeof(word) - 1; + + word_seek_test(&log, &buffers, 25, 1, word, word_len, scratch, scratch_size, &word_seek); + + printf("average normal word seek:\n"); + print_record(word_seek.expected); + printf("\n"); + } + } + log_end_section(&log); + + log_begin_section(&log, litstr("one-hundred-single-edits")); + { + Record_Statistics edits; + insert_bottom_test(&log, &buffers, 25, widths_data, 100, scratch, scratch_size, &edits); + insert_top_test(&log, &buffers, 25, widths_data, 100, scratch, scratch_size, &edits); + delete_bottom_test(&log, &buffers, 25, widths_data, 100, scratch, scratch_size, &edits); + delete_top_test(&log, &buffers, 25, widths_data, 100, scratch, scratch_size, &edits); + } + log_end_section(&log); + log_finish(&log); return(0);