Skip to content

Commit 112bd2f

Browse files
committed
Make Obj trivial and add a separate ObjCollectionParent type
1 parent f7263ed commit 112bd2f

20 files changed

+486
-439
lines changed

src/realm/collection.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,4 +230,25 @@ void Collection::get_any(QueryCtrlBlock& ctrl, Mixed val, size_t index)
230230
}
231231
}
232232

233+
bool CollectionBase::do_init_from_parent(BPlusTreeBase* tree, ref_type ref, bool allow_create)
234+
{
235+
if (ref) {
236+
tree->init_from_ref(ref);
237+
}
238+
else {
239+
if (tree->init_from_parent()) {
240+
// All is well
241+
return true;
242+
}
243+
if (!allow_create) {
244+
tree->detach();
245+
return false;
246+
}
247+
// The ref in the column was NULL, create the tree in place.
248+
tree->create();
249+
REALM_ASSERT(tree->is_attached());
250+
}
251+
return true;
252+
}
253+
233254
} // namespace realm

src/realm/collection.hpp

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -53,18 +53,18 @@ class DummyParent : public CollectionParent {
5353
{
5454
return m_obj;
5555
}
56+
uint_fast64_t root_storage_version() const noexcept final
57+
{
58+
return 0;
59+
}
5660

5761
protected:
5862
Obj m_obj;
5963
ref_type m_ref;
60-
UpdateStatus update_if_needed_with_status() const final
64+
UpdateStatus update_if_needed() const final
6165
{
6266
return UpdateStatus::Updated;
6367
}
64-
bool update_if_needed() const final
65-
{
66-
return true;
67-
}
6868
ref_type get_collection_ref(Index, CollectionType) const final
6969
{
7070
return m_ref;
@@ -262,6 +262,7 @@ class CollectionBase : public Collection {
262262
CollectionBase& operator=(CollectionBase&&) noexcept = default;
263263

264264
void validate_index(const char* msg, size_t index, size_t size) const;
265+
static bool do_init_from_parent(BPlusTreeBase* tree, ref_type ref, bool allow_create);
265266
};
266267

267268
inline std::string_view collection_type_name(CollectionType col_type, bool uppercase = false)
@@ -499,7 +500,7 @@ class CollectionBaseImpl : public Interface, protected ArrayParent {
499500
if (m_parent) {
500501
try {
501502
// Update the parent. Will throw if parent is not existing.
502-
switch (m_parent->update_if_needed_with_status()) {
503+
switch (m_parent->update_if_needed()) {
503504
case UpdateStatus::Updated:
504505
// Make sure to update next time around
505506
m_content_version = 0;
@@ -531,7 +532,7 @@ class CollectionBaseImpl : public Interface, protected ArrayParent {
531532
{
532533
try {
533534
// `has_changed()` sneakily modifies internal state.
534-
update_if_needed_with_status();
535+
update_if_needed();
535536
if (m_last_content_version != m_content_version) {
536537
m_last_content_version = m_content_version;
537538
return true;
@@ -577,10 +578,10 @@ class CollectionBaseImpl : public Interface, protected ArrayParent {
577578
using Interface::get_target_table;
578579

579580
protected:
580-
Obj m_obj_mem;
581+
ObjCollectionParent m_obj_mem;
581582
std::shared_ptr<CollectionParent> m_col_parent;
582583
CollectionParent::Index m_index;
583-
mutable size_t m_my_version = 0;
584+
mutable size_t m_storage_version = 0;
584585
ColKey m_col_key;
585586
bool m_nullable = false;
586587

@@ -657,13 +658,14 @@ class CollectionBaseImpl : public Interface, protected ArrayParent {
657658

658659
UpdateStatus get_update_status() const
659660
{
660-
UpdateStatus status = m_parent ? m_parent->update_if_needed_with_status() : UpdateStatus::Detached;
661+
UpdateStatus status = m_parent ? m_parent->update_if_needed() : UpdateStatus::Detached;
661662

662663
if (status != UpdateStatus::Detached) {
663664
auto content_version = m_alloc->get_content_version();
664-
if (content_version != m_content_version || m_my_version != m_parent->m_parent_version) {
665+
auto storage_version = m_parent->root_storage_version();
666+
if (content_version != m_content_version || m_storage_version != storage_version) {
665667
m_content_version = content_version;
666-
m_my_version = m_parent->m_parent_version;
668+
m_storage_version = storage_version;
667669
status = UpdateStatus::Updated;
668670
}
669671
}
@@ -674,18 +676,14 @@ class CollectionBaseImpl : public Interface, protected ArrayParent {
674676
/// Refresh the parent object (if needed) and compare version numbers.
675677
/// Return true if the collection should initialize from parent
676678
/// Throws if the owning object no longer exists.
677-
bool should_update()
679+
bool should_update() const
678680
{
679681
check_parent();
680-
bool changed = m_parent->update_if_needed(); // Throws if the object does not exist.
681-
auto content_version = m_alloc->get_content_version();
682-
683-
if (changed || content_version != m_content_version || m_my_version != m_parent->m_parent_version) {
684-
m_content_version = content_version;
685-
m_my_version = m_parent->m_parent_version;
686-
return true;
682+
auto status = get_update_status();
683+
if (status == UpdateStatus::Detached) {
684+
throw StaleAccessor("Parent no longer exists");
687685
}
688-
return false;
686+
return status == UpdateStatus::Updated;
689687
}
690688

691689
void bump_content_version()
@@ -735,19 +733,19 @@ class CollectionBaseImpl : public Interface, protected ArrayParent {
735733
void set_backlink(ColKey col_key, ObjLink new_link) const
736734
{
737735
check_parent();
738-
m_parent->set_backlink(col_key, new_link);
736+
m_parent->set_backlink(m_parent->get_object(), col_key, new_link);
739737
}
740738
// Used when replacing a link, return true if CascadeState contains objects to remove
741739
bool replace_backlink(ColKey col_key, ObjLink old_link, ObjLink new_link, CascadeState& state) const
742740
{
743741
check_parent();
744-
return m_parent->replace_backlink(col_key, old_link, new_link, state);
742+
return m_parent->replace_backlink(m_parent->get_object(), col_key, old_link, new_link, state);
745743
}
746744
// Used when removing a backlink, return true if CascadeState contains objects to remove
747745
bool remove_backlink(ColKey col_key, ObjLink old_link, CascadeState& state) const
748746
{
749747
check_parent();
750-
return m_parent->remove_backlink(col_key, old_link, state);
748+
return m_parent->remove_backlink(m_parent->get_object(), col_key, old_link, state);
751749
}
752750

753751
/// Reset the accessor's tracking of the content version. Derived classes
@@ -803,7 +801,7 @@ class CollectionBaseImpl : public Interface, protected ArrayParent {
803801
///
804802
/// If no change has happened to the data, this function returns
805803
/// `UpdateStatus::NoChange`, and the caller is allowed to not do anything.
806-
virtual UpdateStatus update_if_needed_with_status() const = 0;
804+
virtual UpdateStatus update_if_needed() const = 0;
807805
};
808806

809807
namespace _impl {
@@ -891,7 +889,7 @@ class ObjCollectionBase : public Interface, public _impl::ObjListProxy {
891889
/// `BPlusTree<T>`.
892890
virtual BPlusTree<ObjKey>* get_mutable_tree() const = 0;
893891

894-
/// Implements update_if_needed() in a way that ensures the consistency of
892+
/// Implements `update_if_needed()` in a way that ensures the consistency of
895893
/// the unresolved list. Derived classes should call this instead of calling
896894
/// `update_if_needed()` on their inner accessor.
897895
UpdateStatus update_if_needed() const

0 commit comments

Comments
 (0)