Buffer: optimize do_insert to minimize changes in m_lines vector

This commit is contained in:
Maxime Coste 2013-03-18 19:39:32 +01:00
parent e6c635be34
commit a11a162734

View File

@ -240,6 +240,10 @@ void Buffer::do_insert(const BufferIterator& pos, const String& content)
{ {
assert(pos.is_valid() and (pos.is_end() or utf8::is_character_start(pos))); assert(pos.is_valid() and (pos.is_end() or utf8::is_character_start(pos)));
assert(not contains(content, '\0')); assert(not contains(content, '\0'));
if (content.empty())
return;
++m_timestamp; ++m_timestamp;
ByteCount offset = pos.offset(); ByteCount offset = pos.offset();
@ -273,8 +277,7 @@ void Buffer::do_insert(const BufferIterator& pos, const String& content)
String prefix = m_lines[pos.line()].content.substr(0, pos.column()); String prefix = m_lines[pos.line()].content.substr(0, pos.column());
String suffix = m_lines[pos.line()].content.substr(pos.column()); String suffix = m_lines[pos.line()].content.substr(pos.column());
auto line_it = m_lines.begin() + (int)pos.line(); std::vector<Line> new_lines;
line_it = m_lines.erase(line_it);
ByteCount start = 0; ByteCount start = 0;
for (ByteCount i = 0; i < content.length(); ++i) for (ByteCount i = 0; i < content.length(); ++i)
@ -285,27 +288,28 @@ void Buffer::do_insert(const BufferIterator& pos, const String& content)
if (start == 0) if (start == 0)
{ {
line_content = prefix + line_content; line_content = prefix + line_content;
line_it = m_lines.insert(line_it, { offset + start - prefix.length(), new_lines.push_back({ offset + start - prefix.length(),
std::move(line_content) }); std::move(line_content) });
} }
else else
line_it = m_lines.insert(line_it, { offset + start, new_lines.push_back({ offset + start, std::move(line_content) });
std::move(line_content) });
++line_it;
start = i + 1; start = i + 1;
} }
} }
if (start == 0) if (start == 0)
line_it = m_lines.insert(line_it, { offset + start - prefix.length(), prefix + content + suffix }); new_lines.push_back({ offset + start - prefix.length(), prefix + content + suffix });
else if (start != content.length() or not suffix.empty()) else if (start != content.length() or not suffix.empty())
line_it = m_lines.insert(line_it, { offset + start, content.substr(start) + suffix }); new_lines.push_back({ offset + start, content.substr(start) + suffix });
else
--line_it; LineCount last_line = pos.line() + new_lines.size() - 1;
auto line_it = m_lines.begin() + (int)pos.line();
*line_it = std::move(*new_lines.begin());
m_lines.insert(line_it+1, std::make_move_iterator(new_lines.begin() + 1),
std::make_move_iterator(new_lines.end()));
begin_it = pos; begin_it = pos;
end_it = BufferIterator(*this, { LineCount(line_it - m_lines.begin()), end_it = BufferIterator{*this, { last_line, m_lines[last_line].length() - suffix.length() }};
line_it->length() - suffix.length() });
} }
check_invariant(); check_invariant();