PieceTable: keep the line index across consolidation; reset moved-from
Consolidation rewrites pieces without changing content or offsets but invalidated the line index, so once a buffer passed the piece limit every edit paid a full rescan again. A moved-from table kept the index of the text it gave away, and Insert now updates that index in place, producing ranges past the end of its buffer. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015rcVQiiWyTzoNrsvLSaAfB
This commit is contained in:
+5
-2
@@ -74,6 +74,7 @@ PieceTable::PieceTable(PieceTable &&other) noexcept
|
||||
{
|
||||
other.dirty_ = true;
|
||||
other.total_size_ = 0;
|
||||
other.InvalidateLineIndex(); // its index described the moved-away text
|
||||
version_ = other.version_;
|
||||
range_cache_ = {};
|
||||
find_cache_ = {};
|
||||
@@ -93,6 +94,7 @@ PieceTable::operator=(PieceTable &&other) noexcept
|
||||
total_size_ = other.total_size_;
|
||||
other.dirty_ = true;
|
||||
other.total_size_ = 0;
|
||||
other.InvalidateLineIndex(); // its index described the moved-away text
|
||||
version_ = other.version_;
|
||||
range_cache_ = {};
|
||||
find_cache_ = {};
|
||||
@@ -603,9 +605,10 @@ PieceTable::consolidateRange(std::size_t start_idx, std::size_t end_idx)
|
||||
pieces_.begin() + static_cast<std::ptrdiff_t>(end_idx));
|
||||
pieces_.insert(pieces_.begin() + static_cast<std::ptrdiff_t>(start_idx), consolidated);
|
||||
|
||||
// total_size_ unchanged
|
||||
// total_size_ unchanged. Content and byte offsets are unchanged too, so
|
||||
// the line index stays valid (invalidating it here forced a full rescan
|
||||
// on every edit once a buffer had many pieces).
|
||||
dirty_ = true;
|
||||
InvalidateLineIndex();
|
||||
coalesceNeighbors(start_idx);
|
||||
// Layout changed; invalidate caches/version
|
||||
version_++;
|
||||
|
||||
Reference in New Issue
Block a user