Skip to content

Commit 4d0d431

Browse files
committed
Refactor the marker searching algorithm to be much faster, especially in large documents, add missing consts.
1 parent c3a5391 commit 4d0d431

File tree

3 files changed

+58
-80
lines changed

3 files changed

+58
-80
lines changed

src/document_buffer.cpp

Lines changed: 28 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,12 @@ void document_buffer::clear() {
7676
}
7777

7878
int document_buffer::next_marker_index(int position, marker_type type) const noexcept {
79-
for (size_t i = 0; i < markers.size(); ++i) {
80-
if (static_cast<long>(markers[i].pos) > position && markers[i].type == type) {
81-
return static_cast<int>(i);
79+
auto it = std::upper_bound(markers.begin(), markers.end(), position, [](int pos, const marker& m) { return pos < static_cast<long>(m.pos); });
80+
while (it != markers.end()) {
81+
if (it->type == type) {
82+
return static_cast<int>(std::distance(markers.begin(), it));
8283
}
84+
++it;
8385
}
8486
return -1;
8587
}
@@ -94,73 +96,50 @@ int document_buffer::find_first_marker_after(int position, marker_type type) con
9496
}
9597

9698
int document_buffer::previous_marker_index(int position, marker_type type) const noexcept {
97-
int current_index = -1;
98-
for (size_t i = 0; i < markers.size(); ++i) {
99-
if (markers[i].pos >= position && markers[i].type == type) {
100-
current_index = static_cast<int>(i);
101-
break;
102-
}
103-
}
104-
if (current_index >= 0) {
105-
for (int i = current_index - 1; i >= 0; --i) {
106-
if (markers[i].type == type) {
107-
return i;
108-
}
109-
}
110-
} else {
111-
for (int i = static_cast<int>(markers.size()) - 1; i >= 0; --i) {
112-
if (markers[i].pos < position && markers[i].type == type) {
113-
return i;
114-
}
99+
auto it = std::lower_bound(markers.begin(), markers.end(), position, [](const marker& m, int pos) { return static_cast<long>(m.pos) < pos; });
100+
auto rit = std::make_reverse_iterator(it);
101+
while (rit != markers.rend()) {
102+
if (rit->type == type && static_cast<long>(rit->pos) < position) {
103+
return static_cast<int>(std::distance(markers.begin(), rit.base()) - 1);
115104
}
105+
++rit;
116106
}
117107
return -1;
118108
}
119109

120110
int document_buffer::current_marker_index(size_t position, marker_type type) const noexcept {
121-
for (int i = static_cast<int>(markers.size()) - 1; i >= 0; --i) {
122-
if (markers[i].pos <= position && markers[i].type == type) {
123-
return i;
111+
auto it = std::upper_bound(markers.begin(), markers.end(), position, [](size_t pos, const marker& m) { return pos < m.pos; });
112+
auto rit = std::make_reverse_iterator(it);
113+
while (rit != markers.rend()) {
114+
if (rit->type == type) {
115+
return static_cast<int>(std::distance(markers.begin(), rit.base()) - 1);
124116
}
117+
++rit;
125118
}
126119
return -1;
127120
}
128121

129122
int document_buffer::next_heading_marker_index(int position, int level) const {
130123
const auto heading_markers = get_heading_markers();
131-
for (size_t i = 0; i < heading_markers.size(); ++i) {
132-
if (static_cast<long>(heading_markers[i]->pos) > position) {
133-
if (level == -1 || heading_markers[i]->level == level) {
134-
return static_cast<int>(i);
135-
}
124+
auto it = std::upper_bound(heading_markers.begin(), heading_markers.end(), position, [](int pos, const marker* m) { return pos < static_cast<long>(m->pos); });
125+
while (it != heading_markers.end()) {
126+
if (level == -1 || (*it)->level == level) {
127+
return static_cast<int>(std::distance(heading_markers.begin(), it));
136128
}
129+
++it;
137130
}
138131
return -1;
139132
}
140133

141134
int document_buffer::previous_heading_marker_index(int position, int level) const {
142135
const auto heading_markers = get_heading_markers();
143-
int current_index = -1;
144-
for (size_t i = 0; i < heading_markers.size(); ++i) {
145-
if (heading_markers[i]->pos >= position) {
146-
current_index = static_cast<int>(i);
147-
break;
148-
}
149-
}
150-
if (current_index >= 0) {
151-
for (int i = current_index - 1; i >= 0; --i) {
152-
if (level == -1 || heading_markers[i]->level == level) {
153-
return i;
154-
}
155-
}
156-
} else {
157-
for (int i = static_cast<int>(heading_markers.size()) - 1; i >= 0; --i) {
158-
if (heading_markers[i]->pos < position) {
159-
if (level == -1 || heading_markers[i]->level == level) {
160-
return i;
161-
}
162-
}
136+
auto it = std::lower_bound(heading_markers.begin(), heading_markers.end(), position, [](const marker* m, int pos) { return static_cast<long>(m->pos) < pos; });
137+
auto rit = std::make_reverse_iterator(it);
138+
while (rit != heading_markers.rend()) {
139+
if (static_cast<long>((*rit)->pos) < position && (level == -1 || (*rit)->level == level)) {
140+
return static_cast<int>(std::distance(heading_markers.begin(), rit.base()) - 1);
163141
}
142+
++rit;
164143
}
165144
return -1;
166145
}

src/document_manager.cpp

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,6 @@ bool document_manager::export_document(int index, const wxString& export_path) c
142142
return false;
143143
}
144144
file.Write(tab->text_ctrl->GetValue());
145-
file.Close();
146145
return true;
147146
}
148147

@@ -265,19 +264,19 @@ void document_manager::go_to_next_section() const {
265264
navigate_to_section(true);
266265
}
267266

268-
void document_manager::go_to_previous_heading() {
267+
void document_manager::go_to_previous_heading() const {
269268
navigate_to_heading(false);
270269
}
271270

272-
void document_manager::go_to_next_heading() {
271+
void document_manager::go_to_next_heading() const {
273272
navigate_to_heading(true);
274273
}
275274

276-
void document_manager::go_to_previous_heading(int level) {
275+
void document_manager::go_to_previous_heading(int level) const {
277276
navigate_to_heading(false, level);
278277
}
279278

280-
void document_manager::go_to_next_heading(int level) {
279+
void document_manager::go_to_next_heading(int level) const {
281280
navigate_to_heading(true, level);
282281
}
283282

@@ -326,7 +325,7 @@ void document_manager::go_to_next_page() const {
326325
navigate_to_page(true);
327326
}
328327

329-
void document_manager::navigate_to_bookmark(bool next) {
328+
void document_manager::navigate_to_bookmark(bool next) const {
330329
const document_tab* tab = get_active_tab();
331330
wxTextCtrl* text_ctrl = get_active_text_ctrl();
332331
if (tab == nullptr || text_ctrl == nullptr) {
@@ -376,11 +375,11 @@ void document_manager::navigate_to_bookmark(bool next) {
376375
speak(announcement);
377376
}
378377

379-
void document_manager::go_to_previous_bookmark() {
378+
void document_manager::go_to_previous_bookmark() const {
380379
navigate_to_bookmark(false);
381380
}
382381

383-
void document_manager::go_to_next_bookmark() {
382+
void document_manager::go_to_next_bookmark() const {
384383
navigate_to_bookmark(true);
385384
}
386385

@@ -509,7 +508,7 @@ void document_manager::activate_current_link() const {
509508
}
510509
}
511510

512-
void document_manager::navigate_to_list(bool next) {
511+
void document_manager::navigate_to_list(bool next) const {
513512
const document* doc = get_active_document();
514513
wxTextCtrl* text_ctrl = get_active_text_ctrl();
515514
const parser* par = get_active_parser();
@@ -560,15 +559,15 @@ void document_manager::navigate_to_list(bool next) {
560559
}
561560
}
562561

563-
void document_manager::go_to_previous_list() {
562+
void document_manager::go_to_previous_list() const {
564563
navigate_to_list(false);
565564
}
566565

567-
void document_manager::go_to_next_list() {
566+
void document_manager::go_to_next_list() const {
568567
navigate_to_list(true);
569568
}
570569

571-
void document_manager::navigate_to_list_item(bool next) {
570+
void document_manager::navigate_to_list_item(bool next) const {
572571
const document* doc = get_active_document();
573572
wxTextCtrl* text_ctrl = get_active_text_ctrl();
574573
const parser* par = get_active_parser();
@@ -623,15 +622,15 @@ void document_manager::navigate_to_list_item(bool next) {
623622
}
624623
}
625624

626-
void document_manager::go_to_previous_list_item() {
625+
void document_manager::go_to_previous_list_item() const {
627626
navigate_to_list_item(false);
628627
}
629628

630-
void document_manager::go_to_next_list_item() {
629+
void document_manager::go_to_next_list_item() const {
631630
navigate_to_list_item(true);
632631
}
633632

634-
void document_manager::toggle_bookmark() {
633+
void document_manager::toggle_bookmark() const {
635634
const document_tab* tab = get_active_tab();
636635
const wxTextCtrl* text_ctrl = get_active_text_ctrl();
637636
if (tab == nullptr || text_ctrl == nullptr) {
@@ -663,7 +662,7 @@ void document_manager::toggle_bookmark() {
663662
speak(was_bookmarked ? _("Bookmark removed") : _("Bookmarked"));
664663
}
665664

666-
void document_manager::add_bookmark_with_note() {
665+
void document_manager::add_bookmark_with_note() const {
667666
const document_tab* tab = get_active_tab();
668667
wxTextCtrl* text_ctrl = get_active_text_ctrl();
669668
if (tab == nullptr || text_ctrl == nullptr) {

src/document_manager.hpp

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -67,23 +67,23 @@ class document_manager {
6767
void go_to_position(int position) const;
6868
void go_to_previous_section() const;
6969
void go_to_next_section() const;
70-
void go_to_previous_heading();
71-
void go_to_next_heading();
72-
void go_to_previous_heading(int level);
73-
void go_to_next_heading(int level);
70+
void go_to_previous_heading() const;
71+
void go_to_next_heading() const;
72+
void go_to_previous_heading(int level) const;
73+
void go_to_next_heading(int level) const;
7474
void go_to_previous_page() const;
7575
void go_to_next_page() const;
76-
void go_to_previous_bookmark();
77-
void go_to_next_bookmark();
76+
void go_to_previous_bookmark() const;
77+
void go_to_next_bookmark() const;
7878
void go_to_previous_link() const;
7979
void go_to_next_link() const;
80-
void go_to_previous_list();
81-
void go_to_next_list();
82-
void go_to_previous_list_item();
83-
void go_to_next_list_item();
80+
void go_to_previous_list() const;
81+
void go_to_next_list() const;
82+
void go_to_previous_list_item() const;
83+
void go_to_next_list_item() const;
8484
void activate_current_link() const;
85-
void toggle_bookmark();
86-
void add_bookmark_with_note();
85+
void toggle_bookmark() const;
86+
void add_bookmark_with_note() const;
8787
void show_bookmark_dialog(wxWindow* parent);
8888
void show_table_of_contents(wxWindow* parent) const;
8989
void show_document_info(wxWindow* parent) const;
@@ -109,8 +109,8 @@ class document_manager {
109109
void navigate_to_heading(bool next, int specific_level = -1) const;
110110
void navigate_to_section(bool next) const;
111111
void navigate_to_page(bool next) const;
112-
void navigate_to_bookmark(bool next);
112+
void navigate_to_bookmark(bool next) const;
113113
void navigate_to_link(bool next) const;
114-
void navigate_to_list(bool next);
115-
void navigate_to_list_item(bool next);
114+
void navigate_to_list(bool next) const;
115+
void navigate_to_list_item(bool next) const;
116116
};

0 commit comments

Comments
 (0)