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.
This commit is contained in:
parent
5596b4b2b9
commit
39a2ab84fa
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -37,6 +37,12 @@ struct ReverseView
|
|||
{
|
||||
decltype(auto) begin() { return m_range.rbegin(); }
|
||||
decltype(auto) end() { return m_range.rend(); }
|
||||
decltype(auto) rbegin() { return m_range.begin(); }
|
||||
decltype(auto) rend() { return m_range.end(); }
|
||||
decltype(auto) begin() const { return m_range.rbegin(); }
|
||||
decltype(auto) end() const { return m_range.rend(); }
|
||||
decltype(auto) rbegin() const { return m_range.begin(); }
|
||||
decltype(auto) rend() const { return m_range.end(); }
|
||||
|
||||
Range m_range;
|
||||
};
|
||||
|
@ -495,15 +501,15 @@ auto elements(bool exact_size = false)
|
|||
}
|
||||
|
||||
template<typename ExceptionType, size_t... Indexes>
|
||||
auto static_gather_impl(std::index_sequence<Indexes...>)
|
||||
auto static_gather_impl(std::index_sequence<Indexes...>, bool exact_size)
|
||||
{
|
||||
return elements<ExceptionType, Indexes...>(true);
|
||||
return elements<ExceptionType, Indexes...>(exact_size);
|
||||
}
|
||||
|
||||
template<typename ExceptionType, size_t size>
|
||||
template<typename ExceptionType, size_t size, bool exact_size=true>
|
||||
auto static_gather()
|
||||
{
|
||||
return static_gather_impl<ExceptionType>(std::make_index_sequence<size>());
|
||||
return static_gather_impl<ExceptionType>(std::make_index_sequence<size>(), exact_size);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user