From 155d9497938d046e9cc35e4f98694de17f7a1b0f Mon Sep 17 00:00:00 2001 From: Thomas Goyne Date: Wed, 30 Mar 2016 12:12:05 -0700 Subject: [PATCH] Only track inserts and deletes for tables being queried directly # Conflicts: # src/collection_notifications.cpp # src/collection_notifications.hpp --- src/impl/background_collection.cpp | 18 ++++++++++++------ src/impl/background_collection.hpp | 7 ++++--- src/impl/realm_coordinator.cpp | 2 +- src/impl/results_notifier.cpp | 6 ++++++ src/impl/transact_log_handler.cpp | 14 ++++++++++---- tests/transaction_log_parsing.cpp | 9 ++++++--- 6 files changed, 39 insertions(+), 17 deletions(-) diff --git a/src/impl/background_collection.cpp b/src/impl/background_collection.cpp index d0166cf1..552f457b 100644 --- a/src/impl/background_collection.cpp +++ b/src/impl/background_collection.cpp @@ -166,10 +166,10 @@ void BackgroundCollection::add_required_change_info(TransactionChangeInfo& info) } auto max = *max_element(begin(m_relevant_tables), end(m_relevant_tables)) + 1; - if (max > info.tables_needed.size()) - info.tables_needed.resize(max, false); + if (max > info.table_modifications_needed.size()) + info.table_modifications_needed.resize(max, false); for (auto table_ndx : m_relevant_tables) { - info.tables_needed[table_ndx] = true; + info.table_modifications_needed[table_ndx] = true; } } @@ -384,9 +384,12 @@ void CollectionChangeBuilder::modify(size_t ndx) modifications.add(ndx); } -void CollectionChangeBuilder::insert(size_t index, size_t count) +void CollectionChangeBuilder::insert(size_t index, size_t count, bool track_moves) { modifications.shift_for_insert_at(index, count); + if (!track_moves) + return; + insertions.insert_at(index, count); for (auto& move : moves) { @@ -474,12 +477,12 @@ void CollectionChangeBuilder::move(size_t from, size_t to) modifications.shift_for_insert_at(to); } -void CollectionChangeBuilder::move_over(size_t row_ndx, size_t last_row) +void CollectionChangeBuilder::move_over(size_t row_ndx, size_t last_row, bool track_moves) { REALM_ASSERT(row_ndx <= last_row); REALM_ASSERT(insertions.empty() || prev(insertions.end())->second - 1 <= last_row); REALM_ASSERT(modifications.empty() || prev(modifications.end())->second - 1 <= last_row); - if (row_ndx == last_row) { + if (track_moves && row_ndx == last_row) { erase(row_ndx); return; } @@ -492,6 +495,9 @@ void CollectionChangeBuilder::move_over(size_t row_ndx, size_t last_row) else modifications.remove(row_ndx); + if (!track_moves) + return; + 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); diff --git a/src/impl/background_collection.hpp b/src/impl/background_collection.hpp index 84d0df09..2772f591 100644 --- a/src/impl/background_collection.hpp +++ b/src/impl/background_collection.hpp @@ -52,10 +52,10 @@ public: void merge(CollectionChangeBuilder&&); void clean_up_stale_moves(); - void insert(size_t ndx, size_t count=1); + void insert(size_t ndx, size_t count=1, bool track_moves=true); void modify(size_t ndx); void erase(size_t ndx); - void move_over(size_t ndx, size_t last_ndx); + void move_over(size_t ndx, size_t last_ndx, bool track_moves=true); void clear(size_t old_size); void move(size_t from, size_t to); @@ -75,7 +75,8 @@ struct ListChangeInfo { }; struct TransactionChangeInfo { - std::vector tables_needed; + std::vector table_modifications_needed; + std::vector table_moves_needed; std::vector lists; std::vector tables; diff --git a/src/impl/realm_coordinator.cpp b/src/impl/realm_coordinator.cpp index 4425d2d3..55ee1f9e 100644 --- a/src/impl/realm_coordinator.cpp +++ b/src/impl/realm_coordinator.cpp @@ -362,7 +362,7 @@ void RealmCoordinator::run_async_notifiers() for (auto& notifier : new_notifiers) { if (version != notifier->version()) { transaction::advance(*m_advancer_sg, *info, notifier->version()); - change_info.push_back({{}, std::move(info->lists)}); + change_info.push_back({{}, {}, std::move(info->lists)}); info = &change_info.back(); version = notifier->version(); } diff --git a/src/impl/results_notifier.cpp b/src/impl/results_notifier.cpp index 44782305..8d04f771 100644 --- a/src/impl/results_notifier.cpp +++ b/src/impl/results_notifier.cpp @@ -65,6 +65,12 @@ bool ResultsNotifier::do_add_required_change_info(TransactionChangeInfo& info) { REALM_ASSERT(m_query); m_info = &info; + + auto table_ndx = m_query->get_table()->get_index_in_group(); + if (info.table_moves_needed.size() <= table_ndx) + info.table_moves_needed.resize(table_ndx + 1); + info.table_moves_needed[table_ndx] = true; + return m_initial_run_complete && have_callbacks(); } diff --git a/src/impl/transact_log_handler.cpp b/src/impl/transact_log_handler.cpp index c0ea4531..41c0701d 100644 --- a/src/impl/transact_log_handler.cpp +++ b/src/impl/transact_log_handler.cpp @@ -427,7 +427,7 @@ class LinkViewObserver : public TransactLogValidationMixin, public MarkDirtyMixi _impl::CollectionChangeBuilder* get_change() { auto tbl_ndx = current_table(); - if (tbl_ndx >= m_info.tables_needed.size() || !m_info.tables_needed[tbl_ndx]) + if (tbl_ndx >= m_info.table_modifications_needed.size() || !m_info.table_modifications_needed[tbl_ndx]) return nullptr; if (m_info.tables.size() <= tbl_ndx) { m_info.tables.resize(std::max(m_info.tables.size() * 2, tbl_ndx + 1)); @@ -435,6 +435,12 @@ class LinkViewObserver : public TransactLogValidationMixin, public MarkDirtyMixi return &m_info.tables[tbl_ndx]; } + bool need_move_info() const + { + auto tbl_ndx = current_table(); + return tbl_ndx < m_info.table_moves_needed.size() && m_info.table_moves_needed[tbl_ndx]; + } + public: LinkViewObserver(_impl::TransactionChangeInfo& info) : m_info(info) { } @@ -521,7 +527,7 @@ public: { REALM_ASSERT(!unordered); if (auto change = get_change()) - change->insert(row_ndx, num_rows_to_insert); + change->insert(row_ndx, num_rows_to_insert, need_move_info()); return true; } @@ -545,7 +551,7 @@ public: } if (auto change = get_change()) - change->move_over(row_ndx, last_row); + change->move_over(row_ndx, last_row, need_move_info()); return true; } @@ -599,7 +605,7 @@ void advance(SharedGroup& sg, TransactionChangeInfo& info, SharedGroup::VersionID version) { - if (info.tables_needed.empty() && info.lists.empty()) { + if (info.table_modifications_needed.empty() && info.lists.empty()) { LangBindHelper::advance_read(sg, version); } else { diff --git a/tests/transaction_log_parsing.cpp b/tests/transaction_log_parsing.cpp index aed20b8a..da394289 100644 --- a/tests/transaction_log_parsing.cpp +++ b/tests/transaction_log_parsing.cpp @@ -37,7 +37,8 @@ public: _impl::CollectionChangeBuilder c; _impl::TransactionChangeInfo info; info.lists.push_back({ndx, 0, 0, &c}); - info.tables_needed.resize(m_group.size(), true); + info.table_modifications_needed.resize(m_group.size(), true); + info.table_moves_needed.resize(m_group.size(), true); _impl::transaction::advance(m_sg, info); if (info.lists.empty()) { @@ -204,7 +205,8 @@ TEST_CASE("Transaction log parsing") { r->commit_transaction(); _impl::TransactionChangeInfo info; - info.tables_needed.resize(g.size(), true); + info.table_modifications_needed.resize(g.size(), true); + info.table_moves_needed.resize(g.size(), true); _impl::transaction::advance(sg, info); return info; }; @@ -349,7 +351,8 @@ TEST_CASE("Transaction log parsing") { r->commit_transaction(); _impl::TransactionChangeInfo info; - info.tables_needed = tables_needed; + info.table_modifications_needed = tables_needed; + info.table_moves_needed = tables_needed; _impl::transaction::advance(sg, info); return info; };