javaconcurrencyberkeley-dbberkeley-db-je

Compare and swap in Berkeley DB JE?


I'm looking for an efficient way to implement compare-and-swap operation in Berkeley DB. Right now I'm using really old version, however at first glance even the latest one (distributed from Oracle website) does not have a single method for such operation.

I was looking for a some kind of method like

replace(Transaction, Key, ExpectedValue, NewValue) 

with the following semantics: DB gets value associated with a given key, if this value exists and it is equal to ExpectedValue then this value will be changed to NewValue, otherwise method returns unsuccessful OperationStatus.

Looks like there is no method like that, so I'm wondering how is this supposed to be done in the most efficient way.

Right now I'm using the following approach: I do

db.get(null, key) -> {currentValue, version}
db.put(null, key, {currentValue, newRandomIdVersion}) 
db.get(null, key)

I compare value and version, if they match I do final update erasing old version. If any step fail, the whole process restarts.

I feel that this is very suboptimal - am I wrong?


Solution

  • My solution in update to my question is wrong - however only slight modification is required to make it better.

    The solution might be as follows: create separate DB for storing locks that will hold associations of key to some counter. This DB should allow sorted duplicates (so that Database.get would return smallest value associated with a given key). Then use shared monotonically increasing counter. Multiple threads attempting to do CAS will get values from this counter and store key-value pairs in that lock DB. Thread that stored lowest value associated with a key, assumes that it has permission to write and goes ahead with compare-and-swap for desired record, then deletes its entry from the lock DB, other threads simply retry.