From ce19193172a9645ba2f7b9a4d0de83898f6e2332 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Edelbo?= Date: Thu, 22 Aug 2024 13:43:53 +0200 Subject: [PATCH 1/3] Optimize size of Node and Array The size of Node and Array decresed from 64 and 128 to 56 and 112. Some redundant code removed in Spec class. --- src/realm/array.hpp | 2 +- src/realm/node.hpp | 8 ++------ src/realm/search_index.hpp | 6 ------ src/realm/spec.cpp | 37 +++++++++---------------------------- src/realm/spec.hpp | 6 ------ src/realm/table.hpp | 8 -------- 6 files changed, 12 insertions(+), 55 deletions(-) diff --git a/src/realm/array.hpp b/src/realm/array.hpp index af6fee1efa6..54cec41b774 100644 --- a/src/realm/array.hpp +++ b/src/realm/array.hpp @@ -532,10 +532,10 @@ class Array : public Node, public ArrayParent { Getter m_getter = nullptr; // cached to avoid indirection const VTable* m_vtable = nullptr; - uint_least8_t m_width = 0; // Size of an element (meaning depend on type of array). int64_t m_lbound; // min number that can be stored with current m_width int64_t m_ubound; // max number that can be stored with current m_width + uint8_t m_width = 0; // Size of an element (meaning depend on type of array). bool m_is_inner_bptree_node; // This array is an inner node of B+-tree. bool m_has_refs; // Elements whose first bit is zero are refs to subarrays. bool m_context_flag; // Meaning depends on context. diff --git a/src/realm/node.hpp b/src/realm/node.hpp index 8bea1c9559d..8c4290b4b9f 100644 --- a/src/realm/node.hpp +++ b/src/realm/node.hpp @@ -243,11 +243,7 @@ class Node : public NodeHeader { void set_parent(ArrayParent* parent, size_t ndx_in_parent) noexcept { m_parent = parent; - m_ndx_in_parent = ndx_in_parent; - } - void set_ndx_in_parent(size_t ndx) noexcept - { - m_ndx_in_parent = ndx; + m_ndx_in_parent = unsigned(ndx_in_parent); } void clear_missing_parent_update() @@ -339,7 +335,7 @@ class Node : public NodeHeader { private: friend class NodeTree; ArrayParent* m_parent = nullptr; - size_t m_ndx_in_parent = 0; // Ignored if m_parent is null. + unsigned m_ndx_in_parent = 0; // Ignored if m_parent is null. bool m_missing_parent_update = false; void do_copy_on_write(size_t minimum_size = 0); diff --git a/src/realm/search_index.hpp b/src/realm/search_index.hpp index 4848e9b89c3..4c040b8f85e 100644 --- a/src/realm/search_index.hpp +++ b/src/realm/search_index.hpp @@ -116,7 +116,6 @@ class SearchIndex { bool is_attached() const noexcept; void set_parent(ArrayParent* parent, size_t ndx_in_parent) noexcept; size_t get_ndx_in_parent() const noexcept; - void set_ndx_in_parent(size_t ndx_in_parent) noexcept; void update_from_parent() noexcept; void refresh_accessor_tree(const ClusterColumn& target_column); ref_type get_ref() const noexcept; @@ -174,11 +173,6 @@ inline size_t SearchIndex::get_ndx_in_parent() const noexcept return m_root_array->get_ndx_in_parent(); } -inline void SearchIndex::set_ndx_in_parent(size_t ndx_in_parent) noexcept -{ - m_root_array->set_ndx_in_parent(ndx_in_parent); -} - inline void SearchIndex::update_from_parent() noexcept { m_root_array->update_from_parent(); diff --git a/src/realm/spec.cpp b/src/realm/spec.cpp index b2746f3c1c2..d14e6e50bbf 100644 --- a/src/realm/spec.cpp +++ b/src/realm/spec.cpp @@ -41,16 +41,13 @@ void Spec::init(MemRef mem) noexcept { m_top.init_from_mem(mem); size_t top_size = m_top.size(); - REALM_ASSERT(top_size > s_attributes_ndx && top_size <= s_spec_max_size); + // Since Core6 we will always have the column keys array + REALM_ASSERT(top_size == s_spec_max_size); m_types.init_from_ref(m_top.get_as_ref(s_types_ndx)); m_names.init_from_ref(m_top.get_as_ref(s_names_ndx)); m_attr.init_from_ref(m_top.get_as_ref(s_attributes_ndx)); - while (m_top.size() < s_spec_max_size) { - m_top.add(0); - } - // Enumkeys array is only there when there are StringEnum columns if (auto ref = m_top.get_as_ref(s_enum_keys_ndx)) { m_enumkeys.init_from_ref(ref); @@ -59,34 +56,22 @@ void Spec::init(MemRef mem) noexcept m_enumkeys.detach(); } - if (m_top.get_as_ref(s_col_keys_ndx) == 0) { - // This is an upgrade - create column key array - MemRef mem_ref = Array::create_empty_array(Array::type_Normal, false, m_top.get_alloc()); // Throws - m_keys.init_from_mem(mem_ref); - m_keys.update_parent(); - size_t num_cols = m_types.size(); - for (size_t i = 0; i < num_cols; i++) { - m_keys.add(i); - } - } - else { - m_keys.init_from_parent(); - } - + m_keys.init_from_parent(); update_internals(); } void Spec::update_internals() noexcept { - m_num_public_columns = 0; size_t n = m_types.size(); - for (size_t i = 0; i < n; ++i) { - if (ColumnType(int(m_types.get(i))) == col_type_BackLink) { - // Now we have no more public columns + m_num_public_columns = n; + // We normally have fewer backlink columns than public columns, so quicker to go backwards + for (size_t i = n; i; --i) { + if (ColumnType(int(m_types.get(i - 1))) != col_type_BackLink) { + // Now we have no more backlink columns. The rest must be public return; } - m_num_public_columns++; + m_num_public_columns--; } } @@ -207,8 +192,6 @@ void Spec::insert_column(size_t column_ndx, ColKey col_key, ColumnType type, Str if (m_enumkeys.is_attached() && type != col_type_BackLink) { m_enumkeys.insert(column_ndx, 0); } - - update_internals(); } void Spec::erase_column(size_t column_ndx) @@ -246,8 +229,6 @@ void Spec::erase_column(size_t column_ndx) m_types.erase(column_ndx); // Throws m_attr.erase(column_ndx); // Throws m_keys.erase(column_ndx); - - update_internals(); } void Spec::upgrade_string_to_enum(size_t column_ndx, ref_type keys_ref) diff --git a/src/realm/spec.hpp b/src/realm/spec.hpp index c9f3ff0c230..bd0d830da3c 100644 --- a/src/realm/spec.hpp +++ b/src/realm/spec.hpp @@ -81,7 +81,6 @@ class Spec { void destroy() noexcept; size_t get_ndx_in_parent() const noexcept; - void set_ndx_in_parent(size_t) noexcept; void verify() const; @@ -177,11 +176,6 @@ inline size_t Spec::get_ndx_in_parent() const noexcept return m_top.get_ndx_in_parent(); } -inline void Spec::set_ndx_in_parent(size_t ndx) noexcept -{ - m_top.set_ndx_in_parent(ndx); -} - inline ref_type Spec::get_ref() const noexcept { return m_top.get_ref(); diff --git a/src/realm/table.hpp b/src/realm/table.hpp index 80496b12fb9..b5e19db851b 100644 --- a/src/realm/table.hpp +++ b/src/realm/table.hpp @@ -838,8 +838,6 @@ class Table { util::Logger* get_logger() const noexcept; - void set_ndx_in_parent(size_t ndx_in_parent) noexcept; - /// Refresh the part of the accessor tree that is rooted at this /// table. void refresh_accessor_tree(); @@ -1340,12 +1338,6 @@ inline bool Table::is_link_type(ColumnType col_type) noexcept return col_type == col_type_Link; } -inline void Table::set_ndx_in_parent(size_t ndx_in_parent) noexcept -{ - REALM_ASSERT(m_top.is_attached()); - m_top.set_ndx_in_parent(ndx_in_parent); -} - inline size_t Table::colkey2spec_ndx(ColKey key) const { auto leaf_idx = key.get_index(); From 7101d7cafa115887534359343374362629ec3dc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Edelbo?= Date: Thu, 22 Aug 2024 14:47:46 +0200 Subject: [PATCH 2/3] Reduce stack usage of StringIndex::insert Reduse the stack usage of StringIndex::leaf_insert from 832 to 608 (debug) and StringIndex::TreeInsert from 208 to 128 --- src/realm/index_string.cpp | 142 +++++++++++++++++++------------------ src/realm/index_string.hpp | 1 + 2 files changed, 73 insertions(+), 70 deletions(-) diff --git a/src/realm/index_string.cpp b/src/realm/index_string.cpp index b313b7c8383..c2b2fb09629 100644 --- a/src/realm/index_string.cpp +++ b/src/realm/index_string.cpp @@ -930,39 +930,38 @@ void StringIndex::insert_row_list(size_t ref, size_t offset, StringData index_da m_array->insert(ins_pos + 1, ref); } - -void StringIndex::TreeInsert(ObjKey obj_key, key_type key, size_t offset, StringData index_data, const Mixed& value) +void StringIndex::new_node(const NodeChange& nc) { - NodeChange nc = do_insert(obj_key, key, offset, index_data, value); + StringIndex new_node(inner_node_tag(), m_array->get_alloc()); switch (nc.type) { case NodeChange::change_None: - return; + break; case NodeChange::change_InsertBefore: { - StringIndex new_node(inner_node_tag(), m_array->get_alloc()); new_node.node_add_key(nc.ref1); new_node.node_add_key(get_ref()); - m_array->init_from_ref(new_node.get_ref()); - m_array->update_parent(); - return; + break; } case NodeChange::change_InsertAfter: { - StringIndex new_node(inner_node_tag(), m_array->get_alloc()); new_node.node_add_key(get_ref()); new_node.node_add_key(nc.ref1); - m_array->init_from_ref(new_node.get_ref()); - m_array->update_parent(); - return; + break; } case NodeChange::change_Split: { - StringIndex new_node(inner_node_tag(), m_array->get_alloc()); new_node.node_add_key(nc.ref1); new_node.node_add_key(nc.ref2); - m_array->init_from_ref(new_node.get_ref()); - m_array->update_parent(); - return; + break; } } - REALM_ASSERT(false); // LCOV_EXCL_LINE; internal Realm error + m_array->init_from_ref(new_node.get_ref()); + m_array->update_parent(); +} + +void StringIndex::TreeInsert(ObjKey obj_key, key_type key, size_t offset, StringData index_data, const Mixed& value) +{ + auto nc = do_insert(obj_key, key, offset, index_data, value); + if (nc.type != NodeChange::change_None) { + new_node(nc); + } } @@ -1155,58 +1154,61 @@ bool StringIndex::leaf_insert(ObjKey obj_key, key_type key, size_t offset, Strin throw LogicError(ErrorCodes::LimitExceeded, util::format("String of length %1 exceeds maximum string length of %2.", len, max)); } - - // Get subnode table Allocator& alloc = m_array->get_alloc(); - Array keys(alloc); - get_child(*m_array, 0, keys); - REALM_ASSERT(m_array->size() == keys.size() + 1); + size_t ins_pos_refs; // first entry in refs points to offsets - // If we are keeping the complete string in the index - // we want to know if this is the last part - bool is_at_string_end = offset + 4 >= index_data.size(); + { + // Get subnode table + Array keys(alloc); + get_child(*m_array, 0, keys); + REALM_ASSERT(m_array->size() == keys.size() + 1); - size_t ins_pos = keys.lower_bound_int(key); - size_t ins_pos_refs = ins_pos + 1; // first entry in refs points to offsets + // If we are keeping the complete string in the index + // we want to know if this is the last part + bool is_at_string_end = offset + 4 >= index_data.size(); - if (ins_pos == keys.size()) { - if (noextend) - return false; + size_t ins_pos = keys.lower_bound_int(key); + ins_pos_refs = ins_pos + 1; // first entry in refs points to offsets - // When key is outside current range, we can just add it - keys.add(key); - if (!m_target_column.full_word() || is_at_string_end) { - int64_t shifted = int64_t((uint64_t(obj_key.value) << 1) + 1); // shift to indicate literal - m_array->add(shifted); - } - else { - // create subindex for rest of string - StringIndex subindex(m_target_column, m_array->get_alloc()); - subindex.insert_with_offset(obj_key, index_data, value, offset + 4); - m_array->add(subindex.get_ref()); + if (ins_pos == keys.size()) { + if (noextend) + return false; + + // When key is outside current range, we can just add it + keys.add(key); + if (!m_target_column.full_word() || is_at_string_end) { + int64_t shifted = int64_t((uint64_t(obj_key.value) << 1) + 1); // shift to indicate literal + m_array->add(shifted); + } + else { + // create subindex for rest of string + StringIndex subindex(m_target_column, m_array->get_alloc()); + subindex.insert_with_offset(obj_key, index_data, value, offset + 4); + m_array->add(subindex.get_ref()); + } + return true; } - return true; - } - key_type k = key_type(keys.get(ins_pos)); + key_type k = key_type(keys.get(ins_pos)); - // If key is not present we add it at the correct location - if (k != key) { - if (noextend) - return false; + // If key is not present we add it at the correct location + if (k != key) { + if (noextend) + return false; - keys.insert(ins_pos, key); - if (!m_target_column.full_word() || is_at_string_end) { - int64_t shifted = int64_t((uint64_t(obj_key.value) << 1) + 1); // shift to indicate literal - m_array->insert(ins_pos_refs, shifted); - } - else { - // create subindex for rest of string - StringIndex subindex(m_target_column, m_array->get_alloc()); - subindex.insert_with_offset(obj_key, index_data, value, offset + 4); - m_array->insert(ins_pos_refs, subindex.get_ref()); + keys.insert(ins_pos, key); + if (!m_target_column.full_word() || is_at_string_end) { + int64_t shifted = int64_t((uint64_t(obj_key.value) << 1) + 1); // shift to indicate literal + m_array->insert(ins_pos_refs, shifted); + } + else { + // create subindex for rest of string + StringIndex subindex(m_target_column, m_array->get_alloc()); + subindex.insert_with_offset(obj_key, index_data, value, offset + 4); + m_array->insert(ins_pos_refs, subindex.get_ref()); + } + return true; } - return true; } // This leaf already has a slot for for the key @@ -1266,28 +1268,28 @@ bool StringIndex::leaf_insert(ObjKey obj_key, key_type key, size_t offset, Strin IntegerColumn sub(alloc, ref); // Throws sub.set_parent(m_array.get(), ins_pos_refs); - IntegerColumn::const_iterator it_end = sub.cend(); - IntegerColumn::const_iterator lower = it_end; + IntegerColumn::const_iterator lower = sub.cend(); - auto value_exists_in_list = [&]() { - if (m_target_column.full_word()) { - lower = sub.cbegin(); - return reconstruct_string(offset, key, index_data) == value.get_string(); - } + bool value_exists_in_list = false; + if (m_target_column.full_word()) { + lower = sub.cbegin(); + value_exists_in_list = reconstruct_string(offset, key, index_data) == value.get_string(); + } + else { SortedListComparator slc(m_target_column); + IntegerColumn::const_iterator it_end = lower; lower = slc.find_start_of_unsorted(value, sub); if (lower != it_end) { Mixed lower_value = get(ObjKey(*lower)); if (lower_value == value) { - return true; + value_exists_in_list = true; } } - return false; - }; + } // If we found the value in this list, add the duplicate to the list. - if (value_exists_in_list()) { + if (value_exists_in_list) { insert_to_existing_list_at_lower(obj_key, value, sub, lower); } else { diff --git a/src/realm/index_string.hpp b/src/realm/index_string.hpp index c8941989388..10ca1e70128 100644 --- a/src/realm/index_string.hpp +++ b/src/realm/index_string.hpp @@ -241,6 +241,7 @@ class StringIndex : public SearchIndex { // B-Tree functions void TreeInsert(ObjKey obj_key, key_type, size_t offset, StringData index_data, const Mixed& value); NodeChange do_insert(ObjKey, key_type, size_t offset, StringData index_data, const Mixed& value); + void new_node(const NodeChange&); /// Returns true if there is room or it can join existing entries bool leaf_insert(ObjKey obj_key, key_type, size_t offset, StringData index_data, const Mixed& value, bool noextend = false); From 2b1c3d451e2a44730420edfc10f198fb03760ebd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Edelbo?= Date: Mon, 26 Aug 2024 11:02:28 +0200 Subject: [PATCH 3/3] Remove some update_from_parent() functions It is a long time since there was a difference in how init_from_parent() and update_from_parent() should work. --- src/realm/array.cpp | 9 --------- src/realm/array.hpp | 6 ------ src/realm/array_blobs_small.cpp | 8 ++------ src/realm/array_blobs_small.hpp | 10 ---------- src/realm/cluster.cpp | 2 +- src/realm/cluster_tree.cpp | 2 +- src/realm/group.cpp | 4 ++-- src/realm/search_index.hpp | 2 +- src/realm/spec.cpp | 34 ++++----------------------------- src/realm/spec.hpp | 20 ++++--------------- src/realm/table.cpp | 10 +++++----- 11 files changed, 20 insertions(+), 87 deletions(-) diff --git a/src/realm/array.cpp b/src/realm/array.cpp index 25b0d9f5538..dd875ad51e2 100644 --- a/src/realm/array.cpp +++ b/src/realm/array.cpp @@ -220,15 +220,6 @@ void Array::init_from_mem(MemRef mem) noexcept update_width_cache_from_header(); } -void Array::update_from_parent() noexcept -{ - REALM_ASSERT_DEBUG(is_attached()); - ArrayParent* parent = get_parent(); - REALM_ASSERT_DEBUG(parent); - ref_type new_ref = get_ref_from_parent(); - init_from_ref(new_ref); -} - void Array::set_type(Type type) { REALM_ASSERT(is_attached()); diff --git a/src/realm/array.hpp b/src/realm/array.hpp index 54cec41b774..25022d2aa94 100644 --- a/src/realm/array.hpp +++ b/src/realm/array.hpp @@ -126,12 +126,6 @@ class Array : public Node, public ArrayParent { init_from_ref(ref); } - /// Called in the context of Group::commit() to ensure that attached - /// accessors stay valid across a commit. Please note that this works only - /// for non-transactional commits. Accessors obtained during a transaction - /// are always detached when the transaction ends. - void update_from_parent() noexcept; - /// Change the type of an already attached array node. /// /// The effect of calling this function on an unattached accessor is diff --git a/src/realm/array_blobs_small.cpp b/src/realm/array_blobs_small.cpp index bca4d012a1f..3ac3a131f98 100644 --- a/src/realm/array_blobs_small.cpp +++ b/src/realm/array_blobs_small.cpp @@ -29,15 +29,11 @@ void ArraySmallBlobs::init_from_mem(MemRef mem) noexcept Array::init_from_mem(mem); ref_type offsets_ref = get_as_ref(0); ref_type blob_ref = get_as_ref(1); + ref_type nulls_ref = get_as_ref(2); m_offsets.init_from_ref(offsets_ref); m_blob.init_from_ref(blob_ref); - - // In theory you could have an array that survived from ancient days where this array was not present - if (Array::size() > 2) { - ref_type nulls_ref = get_as_ref(2); - m_nulls.init_from_ref(nulls_ref); - } + m_nulls.init_from_ref(nulls_ref); } void ArraySmallBlobs::add(BinaryData value, bool add_zero_term) diff --git a/src/realm/array_blobs_small.hpp b/src/realm/array_blobs_small.hpp index 8db3467a209..77adf62b5fa 100644 --- a/src/realm/array_blobs_small.hpp +++ b/src/realm/array_blobs_small.hpp @@ -111,8 +111,6 @@ class ArraySmallBlobs : public Array { /// initialization value). static MemRef create_array(size_t size, Allocator&, BinaryData defaults); - void update_from_parent() noexcept; - private: friend class ArrayString; Array m_offsets; @@ -258,14 +256,6 @@ inline size_t ArraySmallBlobs::get_size_from_header(const char* header, Allocato return Array::get_size_from_header(offsets_header); } -inline void ArraySmallBlobs::update_from_parent() noexcept -{ - Array::update_from_parent(); - m_blob.update_from_parent(); - m_offsets.update_from_parent(); - m_nulls.update_from_parent(); -} - } // namespace realm #endif // REALM_ARRAY_BINARY_HPP diff --git a/src/realm/cluster.cpp b/src/realm/cluster.cpp index 69f22925543..8d3363d5396 100644 --- a/src/realm/cluster.cpp +++ b/src/realm/cluster.cpp @@ -218,7 +218,7 @@ void Cluster::init(MemRef mem) void Cluster::update_from_parent() noexcept { - Array::update_from_parent(); + Array::init_from_parent(); auto rot = Array::get_as_ref_or_tagged(0); if (!rot.is_tagged()) { m_keys.update_from_parent(); diff --git a/src/realm/cluster_tree.cpp b/src/realm/cluster_tree.cpp index 7cb1ee37cf2..1d57a9954ab 100644 --- a/src/realm/cluster_tree.cpp +++ b/src/realm/cluster_tree.cpp @@ -227,7 +227,7 @@ void ClusterNodeInner::init(MemRef mem) void ClusterNodeInner::update_from_parent() noexcept { - Array::update_from_parent(); + Array::init_from_parent(); ref_type ref = Array::get_as_ref(s_key_ref_index); if (ref) { m_keys.update_from_parent(); diff --git a/src/realm/group.cpp b/src/realm/group.cpp index 1938b2e54fb..4e48a21db8b 100644 --- a/src/realm/group.cpp +++ b/src/realm/group.cpp @@ -1163,8 +1163,8 @@ void Group::update_refs(ref_type top_ref) noexcept m_top.init_from_ref(top_ref); // Now we can update it's child arrays - m_table_names.update_from_parent(); - m_tables.update_from_parent(); + m_table_names.init_from_parent(); + m_tables.init_from_parent(); // Update all attached table accessors. for (auto& table_accessor : m_table_accessors) { diff --git a/src/realm/search_index.hpp b/src/realm/search_index.hpp index 4c040b8f85e..a6276b0b096 100644 --- a/src/realm/search_index.hpp +++ b/src/realm/search_index.hpp @@ -175,7 +175,7 @@ inline size_t SearchIndex::get_ndx_in_parent() const noexcept inline void SearchIndex::update_from_parent() noexcept { - m_root_array->update_from_parent(); + m_root_array->init_from_parent(); } } // namespace realm diff --git a/src/realm/spec.cpp b/src/realm/spec.cpp index d14e6e50bbf..4df5fe8f81e 100644 --- a/src/realm/spec.cpp +++ b/src/realm/spec.cpp @@ -30,11 +30,10 @@ void Spec::detach() noexcept m_top.detach(); } -bool Spec::init(ref_type ref) noexcept +void Spec::init(ref_type ref) noexcept { MemRef mem(ref, get_alloc()); init(mem); - return true; } void Spec::init(MemRef mem) noexcept @@ -44,9 +43,9 @@ void Spec::init(MemRef mem) noexcept // Since Core6 we will always have the column keys array REALM_ASSERT(top_size == s_spec_max_size); - m_types.init_from_ref(m_top.get_as_ref(s_types_ndx)); - m_names.init_from_ref(m_top.get_as_ref(s_names_ndx)); - m_attr.init_from_ref(m_top.get_as_ref(s_attributes_ndx)); + m_types.init_from_parent(); + m_names.init_from_parent(); + m_attr.init_from_parent(); // Enumkeys array is only there when there are StringEnum columns if (auto ref = m_top.get_as_ref(s_enum_keys_ndx)) { @@ -58,11 +57,6 @@ void Spec::init(MemRef mem) noexcept m_keys.init_from_parent(); - update_internals(); -} - -void Spec::update_internals() noexcept -{ size_t n = m_types.size(); m_num_public_columns = n; // We normally have fewer backlink columns than public columns, so quicker to go backwards @@ -75,26 +69,6 @@ void Spec::update_internals() noexcept } } -void Spec::update_from_parent() noexcept -{ - m_top.update_from_parent(); - m_types.update_from_parent(); - m_names.update_from_parent(); - m_attr.update_from_parent(); - - if (m_top.get_as_ref(s_enum_keys_ndx) != 0) { - m_enumkeys.update_from_parent(); - } - else { - m_enumkeys.detach(); - } - - m_keys.update_from_parent(); - - update_internals(); -} - - MemRef Spec::create_empty_spec(Allocator& alloc) { // The 'spec_set' contains the specification (types and names) of diff --git a/src/realm/spec.hpp b/src/realm/spec.hpp index bd0d830da3c..7d51d7c4f97 100644 --- a/src/realm/spec.hpp +++ b/src/realm/spec.hpp @@ -106,22 +106,13 @@ class Spec { Spec(Allocator&) noexcept; // Unattached - bool init(ref_type) noexcept; + void init(ref_type) noexcept; void init(MemRef) noexcept; - void update_internals() noexcept; - // Returns true in case the ref has changed. - bool init_from_parent() noexcept; + void init_from_parent() noexcept; ref_type get_ref() const noexcept; - /// Called in the context of Group::commit() to ensure that - /// attached table accessors stay valid across a commit. Please - /// note that this works only for non-transactional commits. Table - /// accessors obtained during a transaction are always detached - /// when the transaction ends. - void update_from_parent() noexcept; - void set_parent(ArrayParent*, size_t ndx_in_parent) noexcept; void set_column_attr(size_t column_ndx, ColumnAttrMask attr); @@ -160,10 +151,9 @@ inline Spec::Spec(Allocator& alloc) noexcept m_keys.set_parent(&m_top, s_col_keys_ndx); } -inline bool Spec::init_from_parent() noexcept +inline void Spec::init_from_parent() noexcept { - ref_type ref = m_top.get_ref_from_parent(); - return init(ref); + init(m_top.get_ref_from_parent()); } inline void Spec::destroy() noexcept @@ -235,8 +225,6 @@ inline void Spec::set_column_attr(size_t column_ndx, ColumnAttrMask attr) // so setting it will overwrite existing. In the future // we will allow combinations. m_attr.set(column_ndx, attr.m_value); - - update_internals(); } inline StringData Spec::get_column_name(size_t ndx) const noexcept diff --git a/src/realm/table.cpp b/src/realm/table.cpp index f41ec412ad5..f163988525b 100644 --- a/src/realm/table.cpp +++ b/src/realm/table.cpp @@ -1952,18 +1952,18 @@ void Table::update_from_parent() noexcept { // There is no top for sub-tables sharing spec if (m_top.is_attached()) { - m_top.update_from_parent(); - m_spec.update_from_parent(); + m_top.init_from_parent(); + m_spec.init_from_parent(); m_clusters.update_from_parent(); - m_index_refs.update_from_parent(); + m_index_refs.init_from_parent(); for (auto&& index : m_index_accessors) { if (index != nullptr) { index->update_from_parent(); } } - m_opposite_table.update_from_parent(); - m_opposite_column.update_from_parent(); + m_opposite_table.init_from_parent(); + m_opposite_column.init_from_parent(); if (m_top.size() > top_position_for_flags) { uint64_t flags = m_top.get_as_ref_or_tagged(top_position_for_flags).get_as_int(); m_table_type = Type(flags & table_type_mask);