Improve performance for large numbers of deletions
This commit is contained in:
parent
8623aa6c6b
commit
ae9516dbb7
|
@ -284,52 +284,43 @@ void CollectionChangeBuilder::move_over(size_t row_ndx, size_t last_row)
|
||||||
else
|
else
|
||||||
modifications.remove(row_ndx);
|
modifications.remove(row_ndx);
|
||||||
|
|
||||||
|
bool row_is_insertion = insertions.contains(row_ndx);
|
||||||
|
bool last_is_insertion = !insertions.empty() && prev(insertions.end())->second == last_row + 1;
|
||||||
|
REALM_ASSERT_DEBUG(insertions.empty() || prev(insertions.end())->second <= last_row + 1);
|
||||||
|
|
||||||
bool updated_existing_move = false;
|
bool updated_existing_move = false;
|
||||||
for (size_t i = 0; i < moves.size(); ++i) {
|
if (row_is_insertion || last_is_insertion) {
|
||||||
auto& move = moves[i];
|
for (size_t i = 0; i < moves.size(); ++i) {
|
||||||
// Remove moves to the row being deleted
|
auto& move = moves[i];
|
||||||
if (move.to == row_ndx) {
|
// Remove moves to the row being deleted
|
||||||
moves.erase(moves.begin() + i);
|
if (move.to == row_ndx) {
|
||||||
--i;
|
moves.erase(moves.begin() + i);
|
||||||
continue;
|
--i;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (move.to != last_row)
|
||||||
|
continue;
|
||||||
|
REALM_ASSERT(!updated_existing_move);
|
||||||
|
|
||||||
|
// Collapse A -> B, B -> C into a single A -> C move
|
||||||
|
move.to = row_ndx;
|
||||||
|
updated_existing_move = true;
|
||||||
}
|
}
|
||||||
if (move.to != last_row)
|
|
||||||
continue;
|
|
||||||
REALM_ASSERT(!updated_existing_move);
|
|
||||||
|
|
||||||
// Collapse A -> B, B -> C into a single A -> C move
|
|
||||||
move.to = row_ndx;
|
|
||||||
updated_existing_move = true;
|
|
||||||
|
|
||||||
if (!insertions.empty()) {
|
|
||||||
REALM_ASSERT(std::prev(insertions.end())->second - 1 <= last_row);
|
|
||||||
insertions.remove(last_row);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Don't mark the moved-over row as deleted if it was a new insertion
|
|
||||||
if (!insertions.contains(row_ndx)) {
|
|
||||||
deletions.add_shifted(insertions.unshift(row_ndx));
|
|
||||||
insertions.add(row_ndx);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Because this is a move, the unshifted source row has already been marked as deleted
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (updated_existing_move)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Don't report deletions/moves if last_row is newly inserted
|
// Don't report deletions/moves if last_row is newly inserted
|
||||||
if (!insertions.empty() && prev(insertions.end())->second == last_row + 1) {
|
if (last_is_insertion) {
|
||||||
insertions.remove(last_row);
|
insertions.remove(last_row);
|
||||||
}
|
}
|
||||||
else {
|
// If it was previously moved, the unshifted source row has already been marked as deleted
|
||||||
|
else if (!updated_existing_move) {
|
||||||
auto shifted_last_row = insertions.unshift(last_row);
|
auto shifted_last_row = insertions.unshift(last_row);
|
||||||
shifted_last_row = deletions.add_shifted(shifted_last_row);
|
shifted_last_row = deletions.add_shifted(shifted_last_row);
|
||||||
moves.push_back({shifted_last_row, row_ndx});
|
moves.push_back({shifted_last_row, row_ndx});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't mark the moved-over row as deleted if it was a new insertion
|
// Don't mark the moved-over row as deleted if it was a new insertion
|
||||||
if (!insertions.contains(row_ndx)) {
|
if (!row_is_insertion) {
|
||||||
deletions.add_shifted(insertions.unshift(row_ndx));
|
deletions.add_shifted(insertions.unshift(row_ndx));
|
||||||
insertions.add(row_ndx);
|
insertions.add(row_ndx);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue