Skip to content
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

Merged
merged 6 commits into from
Sep 14, 2022
Merged

Refactor link tracing code #5796

merged 6 commits into from
Sep 14, 2022

Conversation

ironage
Copy link
Contributor

@ironage ironage commented Aug 30, 2022

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.

Copy link
Member

@nicola-cab nicola-cab left a 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 {
Copy link
Member

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 {
Copy link
Member

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 {
Copy link
Member

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 {
Copy link
Member

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.

@@ -333,6 +333,72 @@ void LinkChain::add(ColKey ck)
m_link_cols.push_back(ck);
}

LinkTranslator::LinkTranslator(Obj origin, ColKey origin_col_key)
Copy link
Member

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..

@ironage
Copy link
Contributor Author

ironage commented Aug 31, 2022

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

Copy link
Member

@nicola-cab nicola-cab left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@ironage
Copy link
Contributor Author

ironage commented Sep 6, 2022

I'd like to get another review on this one, pinging @finnschiermer or @jedelbo


namespace realm {

struct LinkTranslator {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not class?


namespace realm {

struct LinkTranslator {
Copy link
Contributor

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

@@ -1798,92 +1840,88 @@ inline void nullify_set(Obj& obj, ColKey origin_col_key, T target)
}
} // namespace

template <class ArrayType, class ValueType>
Copy link
Contributor

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

struct LinkTranslator {
LinkTranslator(Obj origin, ColKey origin_col_key);
void run();
virtual void on_list_of_links(LnkLst list) = 0;
Copy link
Contributor

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

@@ -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) {
Copy link
Contributor

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?

@nicola-cab nicola-cab mentioned this pull request Sep 12, 2022
3 tasks
@ironage ironage merged commit 267fa66 into master Sep 14, 2022
@ironage ironage deleted the js/backlink-types branch September 14, 2022 17:11
tgoyne added a commit that referenced this pull request Sep 16, 2022
…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)
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 21, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants