summaryrefslogtreecommitdiff
path: root/src/normal.cc
diff options
context:
space:
mode:
authorgeppettodivacin <ericdilmore@gmail.com>2020-02-01 17:24:08 -0600
committergeppettodivacin <ericdilmore@gmail.com>2020-02-02 22:12:18 -0600
commit39a2ab84fa4b537ed8a54d5a32a0ef158f59003e (patch)
tree89e2ba471703fe4955cd2b487ab5099dda341067 /src/normal.cc
parent5596b4b2b9dbc56d106f1cd3d3b09ccdcd28ad88 (diff)
Use ReverseView to perform fewer allocations
The first attempt at a bug fix for @ symbols in selection buffer names worked, but it was very inefficient. In particular, it allocated three different vectors, and we really only needed the correct elements. Manipulating iterators to give us the right slices of the existing vector is far more efficient. By reversing the original content and taking the last two, we're able to get the number of selections and main selection without too much hassle. The buffer name is everything from the start of the content to the selection count. This gets us through with only one vector allocation. Credit to @mawww for the optimization idea and for fixing my types.
Diffstat (limited to 'src/normal.cc')
-rw-r--r--src/normal.cc19
1 files changed, 8 insertions, 11 deletions
diff --git a/src/normal.cc b/src/normal.cc
index 2c00fb63..89659c4a 100644
--- a/src/normal.cc
+++ b/src/normal.cc
@@ -1778,18 +1778,15 @@ SelectionList read_selections_from_register(char reg, Context& context)
// Use the last two values for timestamp and main_index to allow the buffer
// name to have @ symbols
- struct error : runtime_error { error() : runtime_error{"expected <buffer>@<timestamp>@main_index"} {} };
- const auto desc = content[0] | split<StringView>('@') | gather<Vector>();
- const size_t desc_size = desc.size();
- if (desc_size < 3)
- throw new error;
- auto const buffer_name_view = desc | drop(2);
- auto const buffer_name_temp = accumulate (buffer_name_view, ""_str,
- [](auto str1, auto str2) { return str1 + "@"_str + str2; });
- auto const buffer_name = buffer_name_temp.substr (CharCount (1));
+ struct error : runtime_error { error(size_t) : runtime_error{"expected <buffer>@<timestamp>@main_index"} {} };
+ auto end_content = content[0] | reverse() | split('@') | transform([] (auto bounds) {
+ return StringView{bounds.second.base(), bounds.first.base()};
+ }) | static_gather<error, 2, false>();
+
+ const size_t main = str_to_int(end_content[0]);
+ const size_t timestamp = str_to_int(end_content[1]);
+ const auto buffer_name = StringView{ content[0].begin (), end_content[1].begin () - 1 };
Buffer& buffer = BufferManager::instance().get_buffer(buffer_name);
- const size_t timestamp = str_to_int(desc[desc_size - 2]);
- size_t main = str_to_int(desc[desc_size - 1]);
return selection_list_from_strings(buffer, ColumnType::Byte, content | skip(1), timestamp, main);
}