CHM: removing during a computeIfAbsent

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

CHM: removing during a computeIfAbsent

Ben Manes
When an absent value is being computed, this operation blocks a removal by the same key and clearing the map. This is interesting because a get(), contains(), and iterators do not block, so it could be argued that the values are not considered present yet. If that is agreed to then by the wording of the JavaDoc on remove() could return false immediately and clear() could skip those entries. Was this considered and, if so, why was that optimization rejected?

In the case of a cache, an invalidation doesn't require returning the previous value(s) and the caller may not expect a long delay waiting for every entry to materialize for removal. This could be resolved by a pre-screening phase to only discard entries that are present to minimize this hit, but I'd like to know arguments for why ConcurrentHashMap blocks first in case there is a scenario that I'm missing.

Thanks
-Ben

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: CHM: removing during a computeIfAbsent

Doug Lea
On 01/11/2015 07:51 PM, Ben Manes wrote:
> When an absent value is being computed, this operation blocks a removal by the
> same key and clearing the map. This is interesting because a get(), contains(),
> and iterators do not block, so it could be argued that the values are not
> considered present yet. If that is agreed to then by the wording of the JavaDoc
> on remove() could return false immediately and clear() could skip those entries.
> Was this considered and, if so, why was that optimization rejected?

Basically, it is another consequence of not having a fast tryLock for
builtin sync. Without this, the most common cases would require
more overhead. (And even with it, adding extra checks and code-paths
is an uncertain tradeoff.)


-Doug



_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: CHM: removing during a computeIfAbsent

Ben Manes
I was thinking that it could be done using a `if (node instanceOf ReservationNode) ...` check and probably a flag to replaceNode indicating that a fast fail is acceptable. I thought something similar might work on clear(). If that's valid then the overhead is small, but I agree it may not be that common.

In the caching case, I found an open bug in Guava indicating that some users wanted the blocking style (vs the clobbering approach implemented), so which approach is desired seems open for debate anyway.


On Tuesday, January 13, 2015 5:51 AM, Doug Lea <[hidden email]> wrote:


On 01/11/2015 07:51 PM, Ben Manes wrote:

> When an absent value is being computed, this operation blocks a removal by the
> same key and clearing the map. This is interesting because a get(), contains(),
> and iterators do not block, so it could be argued that the values are not
> considered present yet. If that is agreed to then by the wording of the JavaDoc
> on remove() could return false immediately and clear() could skip those entries.
> Was this considered and, if so, why was that optimization rejected?


Basically, it is another consequence of not having a fast tryLock for
builtin sync. Without this, the most common cases would require
more overhead. (And even with it, adding extra checks and code-paths
is an uncertain tradeoff.)


-Doug



_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest




_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest