Hi,
I've been looking at the problem of writing a concurrent multimap, and I have an implementation backed by AbstractSetMultimap and a MapMaker computing map that creates on demand the values-collections as a set view over a ConcurrentHashMap. With some care over the view collections and various wrappers, I think it gets pretty close.
The big problem, which has already been discussed by others who have tried this, appears to be that of removing the values-collection from the underlying map when they become empty, without introducing race conditions.
A couple of options appear to exist.
The other question that I'm slightly hesitant to ask: is this leak likely to be much of an issue in practice? Notable collections such as java.util.HashMap, juc.ConcurrentHashMap and ArrayDeque do not resize the backing store downwards, and ArrayList does not do so automatically. As long as we clear out the objects, I wonder whether this will matter too much.
Thanks,
Joe
The values collections our implementation uses are immutable. Every
put(), remove(), etc. requires creating a new collection containing
the other existing values. We then ConcurrentMap.replace(K, V, V) the
old immutable values with the new immutable values. Since the value
collection itself is never modified, we can ConcurrentMap.remove(K, V)
the values collection when removing the last element with the
knowledge that it will either (a) succeed, meaning that the collection
really is empty throughout the operation or (b) fail, meaning that
some modification occurred and we can start over with a
ConcurrentMap.replace(K, V, V).
This would be very inefficient for some use cases, possibly more so
than synchronizedMultimap(), and that's a big part of Jared's concerns
about releasing it.
> Has anyone done any better than this? Can we do any better composing bits of
> MapMaker, or does this need a specialised ConcurrentHashMultimap written
> from scratch?
I think we have a bug filed internally along the lines of "Think about
having a MultimapMaker," but even the thinking phase may be years off,
since it's likely to be complex and, of course, the remaining work on
MapMaker itself is a higher priority.
> The other question that I'm slightly hesitant to ask: is this leak likely to
> be much of an issue in practice? Notable collections such as
> java.util.HashMap, juc.ConcurrentHashMap and ArrayDeque do not resize the
> backing store downwards, and ArrayList does not do so automatically. As long
> as we clear out the objects, I wonder whether this will matter too much.
In most cases, I suspect that it's no problem. If someone skips over
the warnings, though (and I can easily see myself doing that unless
the class name is ConcurrentMultimapThatNeverShrinks), it's not hard
to imagine, say, a mapping from session ID to data that accumulates a
huge number of empty values collections.
--
guava-...@googlegroups.com.
http://groups.google.com/group/guava-discuss?hl=en
unsubscribe: guava-discus...@googlegroups.com
This list is for discussion; for help, post to Stack Overflow instead:
http://stackoverflow.com/questions/ask
Use the tag "guava".
Has anyone experimented with a striped-lock based implementation yet? That should be fairly simple, not have the copy overhead, and likely have less contention since concurrent updates in the immutable version still bang against the striped locks in ConcurrentHashMap.