Skip to content

Reset-remove semantic on Map#93

Merged
borshop merged 10 commits intodevelopfrom
feature-bug/rdb/removes-remove
May 29, 2014
Merged

Reset-remove semantic on Map#93
borshop merged 10 commits intodevelopfrom
feature-bug/rdb/removes-remove

Conversation

@russelldb
Copy link
Copy Markdown
Contributor

With a shared causal context for the map and the CRDTs it embeds, removing a field, and then re-adding it has the effect of removing all the additions to that field when merging with a concurrent update to the field. For example:

Add 'X' to set in field F at A
Merge with B
Add 'Y' to set in field F at B
remove field F at A
Add 'Z' to field F at A
merge A and B

The set contains only 'Y' and 'Z', since the remove of the field at A containing 'X' constitutes a remove of 'X'.

However, if the field was not re-added by A the semantic was different, and the result would contain 'X, Y, Z'. This seemed counter-intuitive and confusing. These changes add a temporary tombstone to present fields, so that the removal of a field effects a removal of all dots seen by the field at removal time. But you don't have to re-add the field to see this effect. Neat.

One intuitive way to think of it as like an offline sync of a file system like Dropbox. With this semantic, removing a directory on one machine, and adding a file to that directory on another, merges to the directory being present, with only the added file in it.

There is some oddness with counters, though.

I added a new counter type, riak_dt_emcntr (see it's docs for more details) that stores a dot as latest event against each actors increments and decrements. This is so a field removal can reset the counter value. However, we don't store a dot per increment (that would be crazy inefficient). Counters work will in this scenario

A increments counter at field F by 10
B merges A
A removes field F
B increments counter at field F by 5
A and B merge

Counter is at 5 (A's dot for the increment is dropped)

However there is an anomaly

A increments counter at field F by 10
B merges A
A increments counter by 5
B removes field F
A and B merge

The counter is at 15.

Now, technically, A's first increment should be dropped (should it??) and only the second stand, but that does not happen, as we don't keep a dot per increment. This, too, can be spun in the filesystem sense. If you updated a file and concurrently removed it, you wouldn't expect only the diff to survive, but the whole file.

Personally I'm happy enough with the semantic, to enable reset-remove on counters requires a dot per increment (a counter as set of increments) and that is not worth the overhead.

Happy to rebase once the full round of reviewing is done.

OOOOOOOH, And I removed add from the Map API. Problem?

@russelldb russelldb added this to the 2.0-RC milestone May 14, 2014
@russelldb
Copy link
Copy Markdown
Contributor Author

This is kind of WIP, in that there is still W to do. But I thought it prudent to get eyes on early.

Still todo:-

  • docs for map (see todo in riak_dt_map)
  • riak_test for semantic
  • remove copypasta test from riak_dt_emcntr
  • riak_kv support of riak_dt_emcntr
  • riak_kv removal of map add (or re-add add to map with better semantic)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

You could short-circuit the case where one clock dominates the other, returning only the dominant one. Right?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

That requires more analytical thinking than I'm capable of right now (thinking embedded maps more than the container.) Maybe…?

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Oh, right. I'll ponder it a while too, maybe we can figure it out tomorrow.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Well, tomorrow came and went and we didn't come to any conclusion. That said, I can't see why it isn't safe to ignore one map entirely if its clock is dominated (or even just descended). My intuition says that these no-op merges would be mostly at the get_fsm where replicas are already in-sync, and so there would still be value there, by way of reduced latency.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@russelldb On second thought, could deferred removes happen without incrementing the clock? If so, then my suggestion is moot.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Going to let eqc tell me. Deferreds are applied in merge, which merges the clocks.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

OK, deferring this TODO for another branch. Want to get this semantic into the next Beta, optimisation comes after.

@seancribbs
Copy link
Copy Markdown

Can you rebase or merge develop into this so it will merge cleanly (and make borshop happy)?

@russelldb
Copy link
Copy Markdown
Contributor Author

After the review I can.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Nitpick: This doesn't handle the subtly-evil user who increments or decrements by a negative amount.

@seancribbs
Copy link
Copy Markdown

Is it ok that the map_eqc tends to have 0 as the most common actor count? Ran it for 6 minutes and got this output:

19.94% 0
11.44% 4
8.55% 3
8.31% 2
8.15% 6
[...]

@russelldb
Copy link
Copy Markdown
Contributor Author

@seancribbs good question, I need to look at that some more. I mean, that's a high percentage, I think I need further metrics to see what size the map is, 'cos I suspect that there is still an issue with the state for this test. Luckily I have some expert eyes tomorrow.

@seancribbs seancribbs self-assigned this May 23, 2014
russelldb added 8 commits May 28, 2014 15:13
The problem with an embedded
pn-counter is when the field is removed and added again. PN-Counter
merge takes the max of P and N as the merged value. In the case
that a field was removed and re-added P and N maybe be _lower_ than
their removed values, and when merged with a replica that has not
seen the remove, the remove is lost. This counter adds some
causality by storing a `dot` with P and N. Merge takes the max
event for each actor, so newer values win over old ones. The rest
of the mechanics are the same.
As well as ensuring correct shrinking and fixing generators
replace sets with lists for ease of reading when a counter
example is found
@seancribbs
Copy link
Copy Markdown

@russelldb I've rebased your branch, cleaning up a duplicate commit and grouping similar work. To get your local copy working:

  1. git stash any unsaved changes you have
  2. git fetch origin to get the latest head of the branch
  3. git reset --hard origin/feature-bug/rdb/removes-remove to move your local branch to the rebased one
  4. git stash apply to reapply your local changes

Ping me if you have trouble with this.

Disallow negative arguments to embedded counter
Document the map semantics
@russelldb
Copy link
Copy Markdown
Contributor Author

OK. Addressed review comments and pushed. Just going to remove add from kv api, then ready for final review.

@russelldb
Copy link
Copy Markdown
Contributor Author

Removed "add" from PB and HTTP APIs basho/riak_pb#93, basho/riak_kv#951

@seancribbs
Copy link
Copy Markdown

👍 ffce004

borshop added a commit that referenced this pull request May 29, 2014
Reset-remove semantic on Map

Reviewed-by: seancribbs
@seancribbs
Copy link
Copy Markdown

@borshop merge

@borshop borshop merged commit ffce004 into develop May 29, 2014
@seancribbs seancribbs deleted the feature-bug/rdb/removes-remove branch May 29, 2014 17:41
seancribbs pushed a commit to basho/riak-python-client that referenced this pull request Jun 2, 2014
seancribbs pushed a commit to basho/riak-python-client that referenced this pull request Jun 5, 2014
seancribbs pushed a commit to basho/riak-python-client that referenced this pull request Jun 18, 2014
@seancribbs seancribbs removed their assignment May 8, 2015
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.

3 participants