Only track inserts and deletes for tables being queried directly

# Conflicts:
#	src/collection_notifications.cpp
#	src/collection_notifications.hpp
This commit is contained in:
Thomas Goyne 2016-03-30 12:12:05 -07:00
parent a86265f4dc
commit 155d949793
6 changed files with 39 additions and 17 deletions

View File

@ -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);

View File

@ -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<bool> tables_needed;
std::vector<bool> table_modifications_needed;
std::vector<bool> table_moves_needed;
std::vector<ListChangeInfo> lists;
std::vector<CollectionChangeBuilder> tables;

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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 {

View File

@ -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;
};