Skip to content

Merge Reconciliation#142

Open
Aryan-Naveen wants to merge 15 commits into
developfrom
apn/feature/node_merging_reconciliation
Open

Merge Reconciliation#142
Aryan-Naveen wants to merge 15 commits into
developfrom
apn/feature/node_merging_reconciliation

Conversation

@Aryan-Naveen

Copy link
Copy Markdown
Contributor

No description provided.

@Aryan-Naveen Aryan-Naveen marked this pull request as draft April 15, 2026 15:31
@Aryan-Naveen Aryan-Naveen changed the title initial header Merge Reconciliation Apr 15, 2026
@Aryan-Naveen

Copy link
Copy Markdown
Contributor Author

Initial pass through for node merging logic.

Implemented simple LatestAttribute merge logic.

Currently we "merge" current object attributes and new attributes. Future we want to track all previous proposed attributes but the current logic should reproduce existing behaviors.

@Aryan-Naveen Aryan-Naveen marked this pull request as ready for review April 15, 2026 17:17

@nathanhhughes nathanhhughes left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This is on the right track / is roughly what I was thinking! We should talk about the logic for updateNode if my comment isn't clear (and I can talk you through how to implement the logic for how to maintain the set of merges and cached attributes which can be tricky to get right the first time you do it)

Comment thread include/hydra/common/attribute_merger.h Outdated

struct AttributeMerger {
virtual ~AttributeMerger() = default;
virtual std::unique_ptr<spark_dsg::NodeAttributes> merge(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

(minor) this is better as spark_dsg::NodeAttributes::Ptr. Other places in the code have to be explicit to preserve the inner type of the unique pointer, e.g., std::unique_ptr<KhronosObjectAttributes> is different than KhronosObjectAttributes::Ptr (unless Lukas overrode the base class typedef with a derived variant)

Comment thread src/common/attribute_merger.cpp Outdated

} // namespace

std::unique_ptr<spark_dsg::NodeAttributes> LatestAttributeMerger::merge(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

(minor) okay to do using spark_dsg::NodeAttributes> somewhere in this file, avoiding these line breaks would be good

Comment thread include/hydra/common/attribute_merger.h Outdated
const std::vector<const spark_dsg::NodeAttributes*>& attrs) const = 0;
};

struct LatestAttributeMerger : public AttributeMerger {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Technically we would want an "Earliest" variant as well (which I think you mentioned in slack but might not have implemented), that actually matches the current behavior without these merge functors

Comment thread include/hydra/common/graph_update.h Outdated
char prefix = 0;
std::optional<spark_dsg::LayerId> target_layer;
config::VirtualConfig<NodeMatcher> matcher;
config::VirtualConfig<AttributeMerger> merger;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I think it would help to clean up the implementation of addNode and updateNode to actually require that a merger is specified and that it defaults to EarliestAttributeMerger::Config to match the current behavior

Comment thread src/common/graph_update.cpp Outdated
Comment on lines +201 to +207
if (tracker.merger) {
const auto* existing = graph.findNode(map_iter->second);
if (existing) {
updated =
tracker.merger->merge({&existing->attributes(), entry.attributes.get()});
}
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

We should talk about this implementation, this is where things actually get tricky. For any node that is updated, we should always take the updated attributes over the previous ones (in some attribute cache local to the graph updater). After that, we look to see if the updated node id was involved in any merge and then (i) check if the merge is still valid for all the involved nodes given the updated attributes and (ii) recompute the merged attributes given all the nodes involved in the merge and add them to the scene graph

@nathanhhughes nathanhhughes left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM, thanks! Let's merge this in and we can spend more time on the actual logic later as it makes sense

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants