Closed
Description
When attempting to implement an atomic removeIf
operation for AsyncLoadingCache i found out that LoadingCacheView
computeIfPresent seems to block, while remove doesn't. (computeIfPresent
calls Async.getWhenSuccessful(oldValueFuture)
while remove
calls Async.getIfReady(oldValueFuture)
)
This is surprising to me because semantic-wise, I should be able to implement remove in terms of computeIfPresent (Neither of them should block)
Is there a reason for the blocking semantics for computeIfPresent?
Example (Excuse the pseudo Scala here):
// ... somewhere else
val asyncLoadingCache: AsyncLoadingCache
def removeIf(key: K, predicate: V => Boolean) = {
val valueCacheView = asyncLoadingCache.synchronous().asMap()
// I want to remove a cached value if it exists and matches a predicate
// Since there's no `removeIf` method on ConcurrentMap interface I have to implement this method using either `computeIfPresent` or `remove`
// Implementation using remove - doesn't block for future to complete but doesn't feel as clean
val future = asyncLoadingCache.getIfPresent(key)
if (future != null && future.isDone() && predicate(future.get())) {
valueCacheView.remove(key, value)
}
else {
// no value to check the predicate with at this instant - continue
}
// Or using getIfPresent - This blocks! :(
valueCacheView.getIfPresent(key, (k: K, value: V) =>
if (predicate(value)) {
return null // returning null removes it from the
}
else {
return value // don't modify the value - this probably has the problem of refreshing the write time of this entry
}
)
}
Metadata
Metadata
Assignees
Labels
No labels