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

Add ability to diff/patch states. Closes #36 #37

Merged
merged 18 commits into from
Sep 20, 2022
Merged

Conversation

umesh-timalsina
Copy link
Contributor

@umesh-timalsina umesh-timalsina commented Sep 9, 2022

  • Finalize and Test Diffs
    - Currently, nodes are compared according to their Ids. One of the things that makes a criss-cross comparison a bit difficult is because, we might not have access to the core api to find/search nodes while just diffing JSONs in one pass (Quicker and Synchronous). And applying only necessary changes in the next pass (Slower and Asynchronous) but only to the parts of the subtree with actual changes.
  • Strategy to patch?
  • Performance Benchmarks?
  • Add support for @id resolution

@umesh-timalsina umesh-timalsina marked this pull request as ready for review September 14, 2022 19:22
Copy link
Collaborator

@brollb brollb left a comment

Choose a reason for hiding this comment

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

I see a couple selector tests failing. Could you check them out?

src/common/JSONImporter.js Outdated Show resolved Hide resolved
await this.applyDiffs(diffs, resolvedSelectors);
}

async getDiffs(node, state, resolvedSelectors=new NodeSelections()) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I would just call this diff

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Since we have changesets.js already named diff. I am not sure, do we want to rename it to not create any confusion?

src/common/JSONImporter.js Outdated Show resolved Hide resolved
return diffs;
}

async applyDiffsForNode(node, diffs) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I would rename this to patch or patchNode. Maybe make the node argument optional and name it patch?

await this.applyDiffs(diffs, resolvedSelectors);
}

async applyDiffs(diffs, resolvedSelectors) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I would name this patch. It would be nice if we had patch and patchSync where the latter required resolvedSelectors to already contain all selectors used in the patch/changeset.

Copy link
Collaborator

Choose a reason for hiding this comment

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

However, this won't work if we want to support the lazy creation of subtrees (in which it diffs the subtree when the node is created).

await this._put(created, change, resolvedSelectors);
}));
await Promise.all((state.children || []).map(async child => {
await this.createStateSubTree(this.core.getPath(created), child, resolvedSelectors);
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think this might have problems with inherited children. I will put together a test and check.

Copy link
Collaborator

Choose a reason for hiding this comment

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

It looks like this is a problem in main, too, so probably not a deal breaker...

Currently, the resolveSelectors, doesn't record the node if the
state doesn't have ID. However, in `patchSync` we might need the
node info even if the state id is not present. This refactor tries
to handle it by adding the current node's path to cache as well.
}

async applyDiffs(diffs, resolvedSelectors) {
async patchSync(diffs, resolvedSelectors) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I was thinking that patchSync would be synchronous :)

Copy link
Collaborator

Choose a reason for hiding this comment

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

Maybe leave it async (named _patch or something and save the synchronous version for another PR.

Copy link
Collaborator

@brollb brollb left a comment

Choose a reason for hiding this comment

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

I think this should be good to merge. One minor thing is that it might be nice to try to more closely match the format of the patches for add_subtree and delete_subtree. For example:

{
  "type": "put",
  "key": ["children"],
  "value": childState
}
// and
{
  "type": "del",
  "key":  ["children"],
  "value": childPath
}

@brollb
Copy link
Collaborator

brollb commented Sep 20, 2022

Looks great! Thanks, @umesh-timalsina!

@brollb brollb merged commit f1b2f70 into main Sep 20, 2022
@brollb brollb deleted the 36-webgme-diff-patch branch September 20, 2022 16:20
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