The confusion about the replacement policy in CurrentlinkedHashMap

62 views
Skip to first unread message

NathanLiu

unread,
Oct 19, 2011, 11:37:10 PM10/19/11
to ConcurrentLinkedHashMap
hi !
According the "Weighted Values" in http://code.google.com/p/concurrentlinkedhashmap/wiki/Design:
"If all entries are assigned a weight of 1 then the LIRS policy can be
taken advantage of". The default implemented Weigher is
SingletonWeigher, and the weight is 1. So the default replacement
policy is LIRS in ConcurrentLinkedHashMap ?

but "If weights are specified then the cache can degrade to an LRU
policy to maintain a satisfactory hit rate", which means if weight is
assigned , the replacement policy will be LRU ?
--- If the weight is assigned as 1 .

I am confused in the "Weighted Values" chapter.

So how to find out which replacement policy is used ?

The example lru code:
/** the default weight is 1, why not lirs */
public void lruPage() {
ConcurrentLinkedHashMap<String, String> cache = new
ConcurrentLinkedHashMap.Builder<String, String>().
.initialCapacity(2).maximumWeightedCapacity(2).build();

cache.put("1", "1");
cache.put("2", "2");
cache.get("1");
cache.put("3", "3");
cache.get("1");
cache.put("4", "4");
cache.put("5", "4");
System.out.println("Weighed size = " + cache.weightedSize());
System.out.println("Capacity = " + cache.capacity());
System.out.println(cache);
}

Is there any example for LIRS in ConcurrentLinkedHashMap ?

I have 10w items , and the apache-common-LRUMap can't afford the
current scenario.

Thanks for the ConcurrentLinkedHashMap !
Thank you very much, too!

Ben Manes

unread,
Oct 20, 2011, 12:13:01 AM10/20/11
to ConcurrentLinkedHashMap
Hi Nathan,

Short answer:
The current release versions all use an LRU policy. LIRS support is
not provided and is intended to be in v2.

Long answer:
Unfortunately I seem to always get pulled away half-way through an
implementation, so I don't know when LIRS support will be provided.

The API intent is that usages should not concern themselves with what
eviction policy is used to provide a good hit, rate at high
concurrency, with low overhead. The class documentation does not leak
any of these implementation details to allow the policy to evolve
between releases. We decided to continue this approach when adding
caching capabilities into Guava.

In a prior attempt I realized that LIRS it was incompatible with
weights due to it using size characteristics in its policy management.
This results in a race condition where the LIRS policy resizes based
on a stale read of the entry's weight, which can be updated
independently. This would not be an issue in a per-segment cache like
what we added in Guava, where the segment lock guards all data.
Instead CLHM provides higher concurrency characteristics and a better
hit rate by removing locks from any critical path. It is more akin to
what may go into JSR-166 with the mostly lock-free ConcurrentHashMap
rewrite. It was my intention to use LIRS in the common case where
every entry is a fixed size (singleton weigher) as the data race is
benign, and an alternative policy otherwise.

The meaning of "assigned weights" is that the application is
determining them by not using the provided singleton weigher. If a
different weigher is used, then due to the race condition the v2
implementation will not use LIRS. This means that Builder.weigher() is
specified and is not the Weighers.singleton() instance.

There is no working examples of LIRS support. You can look at the
development branches if you are interested in seeing half-baked
implementations and tests.

Cheers,
Ben

On Oct 19, 8:37 pm, NathanLiu <nathan...@gmail.com> wrote:
> hi !
> According the "Weighted Values" inhttp://code.google.com/p/concurrentlinkedhashmap/wiki/Design:
Reply all
Reply to author
Forward
0 new messages