[concurrency-interest] ConcurrentHashMapV8 insertion/update methods

Doug Lea dl at cs.oswego.edu
Mon Aug 6 20:25:47 EDT 2012

In the midst of putting together parallel bulk operation support
for ConcurrentHashMap, I noticed that in constructions
of form
   for each x in parallel { map.maybeInsertOrUpdate(...) }
we lack support for a few usages that may become common with
growing use of functional forms.

We have now:
* put(k, v) --
    always write (or replace)
* putIfAbsent(K, v) --
    skip if present, else write
* computeIfAbsent(k, f) --
    skip if present, else write result of f(k)
* compute(k, f) --
    write result of f(k, currentValue),
    where currentValue is null if absent

The missing cases are:
* computeIfPresent(k, f) --
    skip if absent, else write result of f(k, currentValue)
* merge(k, v, f)
    if absent, write v, else write results of f(currentValue, v)
* (keyed) merge(k, v, f)
    if absent, write v, else write results of f(k, currentValue, v)

The last two can be thought of as embedded reductions, where
the keyless-function version plugs into most reduction idioms, but
the keyed-function is needed elsewhere.

This hits all possible cases of atomically skipping,
writing a value, or apply a function when the key
is absent or present. In principle, all of these things
can be done solely with the "compute" method, but it would
often require the use of heavy functions that could tie up
mappings and lead to more contention, which we'd like to help
people avoid.

Aside: One nice thing about using ConcurrentHashMaps in
bulk-parallel programming is that you don't need clever
schemes to manage parallel updates. People can just
do them in parallel forEach loops. So it's worth ensuring
that all these per-mapping atomic-update methods are available
to use in this way.

Pending any further concerns, I plan to put out an update
with these soon.


More information about the Concurrency-interest mailing list