-
Notifications
You must be signed in to change notification settings - Fork 171
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactor link tracing code #5796
Conversation
4a66261
to
728503e
Compare
728503e
to
0634e94
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is wonderful. Just, I believe we should move all the utilities you wrote within new header/source files in order to avoid treating them as "additions" to Obj/Table. Essentially, you have introduced a standard way to deal with links.
@@ -696,6 +696,61 @@ size_t Obj::get_backlink_cnt(ColKey backlink_col) const | |||
|
|||
void Obj::traverse_path(Visitor v, PathSizer ps, size_t path_length) const | |||
{ | |||
struct BacklinkTraverser : public LinkTranslator { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Personally, I think this belongs to some other compilation unit (new header + source file). This applies to all the other classes you defined within a method.
if (attr.test(col_attr_List)) { | ||
if (origin_col_key.get_type() == col_type_LinkList) { | ||
nullify_linklist(*this, origin_col_key, target_link.get_obj_key()); | ||
struct LinkNullifier : public LinkTranslator { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above.
@@ -1934,6 +1971,80 @@ bool Obj::remove_backlink(ColKey col_key, ObjLink old_link, CascadeState& state) | |||
return false; | |||
} | |||
|
|||
struct EmbeddedObjectLinkMigrator : public LinkTranslator { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
needs to be moved into a separate header/source file IMO.
@@ -2049,6 +2121,83 @@ LinkCollectionPtr Obj::get_linkcollection_ptr(ColKey col_key) const | |||
|
|||
void Obj::assign_pk_and_backlinks(const Obj& other) | |||
{ | |||
struct LinkReplacer : LinkTranslator { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same as per above comments.
src/realm/table.cpp
Outdated
@@ -333,6 +333,72 @@ void LinkChain::add(ColKey ck) | |||
m_link_cols.push_back(ck); | |||
} | |||
|
|||
LinkTranslator::LinkTranslator(Obj origin, ColKey origin_col_key) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would have this defined into a separate header/source file, this is basically a basic class to deal with links from now on..
@nicola-cab I've moved the base LinkTranslator into separate files. But I would prefer to keep the specialized classes close to where they are used in the code for readability; those classes are not meant to be reused by anything else. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
I'd like to get another review on this one, pinging @finnschiermer or @jedelbo |
src/realm/link_translator.hpp
Outdated
|
||
namespace realm { | ||
|
||
struct LinkTranslator { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not class?
src/realm/link_translator.hpp
Outdated
|
||
namespace realm { | ||
|
||
struct LinkTranslator { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you add a comment on how and where this class is supposed to be used
src/realm/obj.cpp
Outdated
@@ -1798,92 +1840,88 @@ inline void nullify_set(Obj& obj, ColKey origin_col_key, T target) | |||
} | |||
} // namespace | |||
|
|||
template <class ArrayType, class ValueType> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ArrayType can be deducted from ColumnTypeTraits<ValueType>::cluster_leaf_type
src/realm/link_translator.hpp
Outdated
struct LinkTranslator { | ||
LinkTranslator(Obj origin, ColKey origin_col_key); | ||
void run(); | ||
virtual void on_list_of_links(LnkLst list) = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should use references for the collection types
src/realm/list.cpp
Outdated
@@ -280,6 +280,8 @@ void Lst<ObjKey>::do_clear() | |||
target_obj.remove_one_backlink(backlink_col, m_obj.get_key()); // Throws | |||
size_t num_remaining = target_obj.get_backlink_count(*origin_table, m_col_key); | |||
if (num_remaining == 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps the above check can be removed?
…nification * origin/master: Stop forcing enums to be 64 bits unnecessarily clean up documentation of internal fields in config structs SyncConfig should be default constructible Traversal functions use IteratorControl values rather than true/false which is more expressive (#5857) Fix handling of 4-byte UTF8 values on Windows (#5803) Encode links in a way the server can understand (#5835) expose `Group::remove_table` in the C API (#5860) Disable auto refresh for old realm during migration (#5856) Expose `list_find` in the c api (#5848) Do not allow asymmetric tables in pbs (#5853) Refactor link tracing code (#5796) Expose `Obj::get_parent_object` in the C API (#5851) Update app.hpp (#5854) Fix appending to list ignores existing query (#5850)
It is a common pattern to iterate through all backlinks of an object to do something with the associated forward links. But it is far too easy to forget about handling a link type and we have had several bugs due to this in the past. Using the new
LinkTranslator
type ensures that all link types are explicitly handled by overriding the appropriate method. This also makes it clear when reading the code, that if a certain type of link was not handled, it was intentional and not an error.There is one functional change, which is to disallow migrating to an embedded table if we have links from a Mixed property. We do not handle this in many places yet so we should not allow these types of objects to sneak in until we add official support.