From 1b48c7193281abb7b30e8f60715ae02909faf3de Mon Sep 17 00:00:00 2001 From: Thomas Goyne Date: Wed, 16 Mar 2016 11:18:59 -0700 Subject: [PATCH] Speed up transaction log parsing for queries --- src/collection_notifications.cpp | 60 ++++++++++++++++++-------------- src/index_set.cpp | 8 +---- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/src/collection_notifications.cpp b/src/collection_notifications.cpp index a005ba10..de7cc26e 100644 --- a/src/collection_notifications.cpp +++ b/src/collection_notifications.cpp @@ -267,45 +267,51 @@ void CollectionChangeBuilder::move_over(size_t row_ndx, size_t last_row) erase(row_ndx); return; } - move(last_row, row_ndx); - erase(row_ndx + 1); - return; + + bool modified = modifications.contains(last_row); + modifications.erase_at(last_row); + if (modified) + modifications.add(row_ndx); + else + modifications.remove(row_ndx); bool updated_existing_move = false; for (size_t i = 0; i < moves.size(); ++i) { auto& move = moves[i]; - REALM_ASSERT(move.to <= last_row); - + // Remove moves to the row being deleted if (move.to == row_ndx) { - REALM_ASSERT(!updated_existing_move); - moves[i] = moves.back(); - moves.pop_back(); + moves.erase(moves.begin() + i); --i; - updated_existing_move = true; + continue; } - else if (move.to == last_row) { - REALM_ASSERT(!updated_existing_move); - move.to = row_ndx; - updated_existing_move = true; - } - } - if (!updated_existing_move) { - moves.push_back({last_row, row_ndx}); + 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; + + insertions.erase_at(last_row); + insertions.insert_at(row_ndx); + // Because this is a move, the unshifted source row has already been marked as deleted } - insertions.remove(row_ndx); - modifications.remove(row_ndx); + if (updated_existing_move) + return; - // not add_shifted() because unordered removal does not shift - // mixed ordered/unordered removal currently not supported - deletions.add(row_ndx); - - if (modifications.contains(last_row)) { - modifications.remove(last_row); - modifications.add(row_ndx); + // Don't report deletions/moves if last_row is newly inserted + auto shifted_last_row = insertions.erase_and_unshift(last_row); + if (shifted_last_row != npos) { + shifted_last_row = deletions.add_shifted(shifted_last_row); + moves.push_back({shifted_last_row, row_ndx}); } - insertions.add(row_ndx); + // 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); + } } void CollectionChangeBuilder::verify() diff --git a/src/index_set.cpp b/src/index_set.cpp index 2e553b38..68fa6b2c 100644 --- a/src/index_set.cpp +++ b/src/index_set.cpp @@ -385,13 +385,7 @@ size_t IndexSet::shift(size_t index) const size_t IndexSet::unshift(size_t index) const { REALM_ASSERT_DEBUG(!contains(index)); - auto shifted = index; - for (auto range : m_ranges) { - if (range.first >= index) - break; - shifted -= std::min(range.second, index) - range.first; - } - return shifted; + return index - count(0, index); } void IndexSet::clear()