vmemcache icon indicating copy to clipboard operation
vmemcache copied to clipboard

FEAT: Atomic Put If Absent

Open pbalcer opened this issue 6 years ago • 3 comments

vmemcache_put_if_absent()

If the key is not present in the cache put the key to the cache atomically.

Value existingValue = vmemcache_get(key);
if (existingValue == null) {
      vmemcache_put(key, value);
      return null;
} else {
      return existingValue;
}

But combine the two steps atomically.

From: Xie, Qi [email protected]

pbalcer avatar Jun 21 '19 08:06 pbalcer

I don't quite see an use case here: put already throws EEXIST when the key exists, thus there are no overwrites — ie, two puts won't conflict.

As for get-put conflicts: the eviction policy is either none or LRU. With the former, you can do the put first (your proposed interface already requires calculating the value), while with LRU the cache may drop a key at any moment for unobvious reasons, thus atomicity between operations hardly matters.

Am I missing something?

kilobyte avatar Jun 21 '19 08:06 kilobyte

This is a common pattern in functional programming languages for idempotent inserts, where you have functions like map.get_or_else(), map.entry(xxx).or_insert(yyy). This is a way to avoid an extra lookup and have shorter code. Now, we already have something like that through our callbacks, but this may be more convenient to use in Java since there's no C->Java callback.

pbalcer avatar Jun 21 '19 08:06 pbalcer

on_miss callbacks are not atomic. Here's a scenario:

T1: get(KEY) → on_miss T2: put(KEY, VAL2) T1: on_miss → put(KEY, VAL1) → satisfies the get, then fails

So T1's get will receive VAL1 while the cache will have VAL2.

Whether this is a deficiency or not is up to debate, but that's how current code behaves. Any other puts are serialized wrt gets, only on_miss callbacks are affected.

kilobyte avatar Jun 21 '19 09:06 kilobyte