[concurrency-interest] How to implement a self populating memoizer cache?
Kevin Bourrillion
kevinb at google.com
Wed Nov 3 18:14:49 EDT 2010
Actually, I think he's looking at the GWT version of MapMaker, which is Java
code that is meant to be converted to Javascript and run -- single-threaded!
-- in the browser. Confusing, I know.
On Wed, Nov 3, 2010 at 1:59 PM, Charles Fry <fry at google.com> wrote:
> It looks like you're looking at an old version of MapMaker. Check out the
> version in the guava project:
>
>
> http://code.google.com/p/guava-libraries/source/browse/trunk/src/com/google/common/collect/ComputingConcurrentHashMap.java#76
>
> Charles
>
> On Wed, Nov 3, 2010 at 16:47, Nader Aeinehchi <nader at aeinehchi.com> wrote:
>
>> Dear Kevin,
>>
>> If I understand you correctly, MapMaker.ExpiringComputingMap (which I
>> believe you are referring to) is thread safe. Furthermore, it guarantees
>> that threads will wait until the first thread computes for a given key.
>>
>> Following is an excerpt of MapMaker.ExpiringComputingMap. Here, if the
>> result is null, the compute method is called and the calculated value is
>> put. How is it guaranteed that another thread does not concurrently perform
>> the latter (calculation and put operations)? Is not this a
>> read-modify-write scheme which according to JCiP book is a compound (not
>> atomic) operation?
>>
>>
>> In advance, thank you very much.
>>
>>
>> @Override
>> public V get(Object k) {
>> // from CustomConcurrentHashMap
>> V result = super.get(k);
>> if (result == null && computer != null) {
>> /*
>> * This cast isn't safe, but we can rely on the fact that K is
>> almost
>> * always passed to Map.get(), and tools like IDEs and Findbugs
>> can
>> * catch situations where this isn't the case.
>> *
>> * The alternative is to add an overloaded method, but the chances
>> of
>> * a user calling get() instead of the new API and the risks
>> inherent
>> * in adding a new API outweigh this little hole.
>> */
>> @SuppressWarnings("unchecked")
>> K key = (K) k;
>> result = compute(key);
>> }
>> return result;
>> }
>>
>> private V compute(K key) {
>> // from MapMaker
>> V value;
>> try {
>> value = computer.apply(key);
>> } catch (Throwable t) {
>> throw new ComputationException(t);
>> }
>>
>> if (value == null) {
>> String message = computer + " returned null for key " + key + ".";
>> throw new NullPointerException(message);
>> }
>> put(key, value);
>> return value;
>>
>> }
>>
>>
>>
>> On 11/03/2010 03:15 PM, Kevin Bourrillion wrote:
>>
>> On Wed, Nov 3, 2010 at 5:31 AM, Nader Aeinehchi <nader at aeinehchi.com>wrote:
>>
>> 1. Please forgive me for my ignorance, but ExpiringComputingMap does not
>>> guarantee that a computable to be calculated only once for concurrent
>>> threads?
>>>
>>
>> "Map.get(java.lang.Object)<http://java.sun.com/javase/6/docs/api/java/util/Map.html?is-external=true#get%28java.lang.Object%29>
>> either returns an already-computed value for the given key, atomically
>> computes it using the supplied function, or, if another thread is currently
>> computing the value for this key, simply waits for that thread to finish and
>> returns its computed value. Note that the function may be executed
>> concurrently by multiple threads, but only for distinct keys."
>>
>>
>> --
>> Kevin Bourrillion @ Google
>> http://guava-libraries.googlecode.com
>>
>>
>> _______________________________________________
>> Concurrency-interest mailing list
>> Concurrency-interest at cs.oswego.edu
>> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>>
>>
>
> _______________________________________________
> Concurrency-interest mailing list
> Concurrency-interest at cs.oswego.edu
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>
>
--
Kevin Bourrillion @ Google
http://guava-libraries.googlecode.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20101103/18f51791/attachment.html>
More information about the Concurrency-interest
mailing list