diff options
| author | geppettodivacin <ericdilmore@gmail.com> | 2020-02-01 17:24:08 -0600 |
|---|---|---|
| committer | geppettodivacin <ericdilmore@gmail.com> | 2020-02-02 22:12:18 -0600 |
| commit | 39a2ab84fa4b537ed8a54d5a32a0ef158f59003e (patch) | |
| tree | 89e2ba471703fe4955cd2b487ab5099dda341067 /src/normal.cc | |
| parent | 5596b4b2b9dbc56d106f1cd3d3b09ccdcd28ad88 (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.cc | 19 |
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); } |
