At 05:33 PM 8/4/2009, Dustin wrote:
On Aug 4, 5:16 pm, Bennett Haselton <[email protected]> wrote:
> Is there a way to change this behavior? Otherwise, I'll just have to
> write code with two branches every time I want to update a value
> using gets() and cas() -- first, check if the key already exists (and
> if so, update it using gets() and cas()), otherwise, update it using
> get() and set() (because I can't get gets() and cas() to work on a
> non-pre-existing key).
No, actually, if gets fails, you want to use add. If add fails, you
loop. If gets succeeds and cas fails, you loop. That's the only way
you can have atomicity.
Right, that makes sense.
But what I'm asking is whether there is some reason that gets() and
cas() aren't written so that they succeed if you call them on a key
that doesn't exist. If the key didn't exist when you called gets(),
and it still doesn't exist when you call cas(), then it "hasn't
changed", so why not just let cas() succeed in that case? It would
save the trouble of having to do two branches of code.
If you don't care about stepping over someone
else's value, then you can just take the set path.
Take a look at how I did it in spymemcached:
http://github.com/dustin/java-memcached-client/blob/master/src/main/java/net/spy/memcached/CASMutator.java
The CASMutation instance is responsible for performing a
transformation on the value when it succeeds. It has to be functional
as it may actually be called many times while racing for the CAS token.