11d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/* 21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Copyright (C) 2011 The Guava Authors 31d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 41d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Licensed under the Apache License, Version 2.0 (the "License"); 51d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * you may not use this file except in compliance with the License. 61d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * You may obtain a copy of the License at 71d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 81d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * http://www.apache.org/licenses/LICENSE-2.0 91d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Unless required by applicable law or agreed to in writing, software 111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * distributed under the License is distributed on an "AS IS" BASIS, 121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * See the License for the specific language governing permissions and 141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * limitations under the License. 151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpackage com.google.common.cache; 181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.cache.CacheBuilder.NULL_TICKER; 201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.cache.LocalCache.DISCARDING_QUEUE; 211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.cache.LocalCache.DRAIN_THRESHOLD; 221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.cache.LocalCache.nullEntry; 231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.cache.LocalCache.unset; 241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.cache.TestingCacheLoaders.identityLoader; 251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.cache.TestingRemovalListeners.countingRemovalListener; 261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.cache.TestingRemovalListeners.queuingRemovalListener; 271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.cache.TestingWeighers.constantWeigher; 281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.collect.Lists.newArrayList; 291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.collect.Maps.immutableEntry; 301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static java.util.concurrent.TimeUnit.NANOSECONDS; 311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static java.util.concurrent.TimeUnit.SECONDS; 321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Equivalence; 341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Ticker; 351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.cache.LocalCache.EntryFactory; 361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.cache.LocalCache.LoadingValueReference; 371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.cache.LocalCache.LocalLoadingCache; 381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.cache.LocalCache.LocalManualCache; 391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.cache.LocalCache.ReferenceEntry; 401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.cache.LocalCache.Segment; 411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.cache.LocalCache.Strength; 421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.cache.LocalCache.ValueReference; 431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.cache.TestingCacheLoaders.CountingLoader; 441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.cache.TestingRemovalListeners.CountingRemovalListener; 451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.cache.TestingRemovalListeners.QueuingRemovalListener; 461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.collect.ImmutableList; 471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.collect.ImmutableMap; 480888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport com.google.common.collect.ImmutableSet; 491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.collect.Lists; 501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.collect.Maps; 510888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport com.google.common.collect.testing.MapTestSuiteBuilder; 520888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport com.google.common.collect.testing.TestStringMapGenerator; 530888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport com.google.common.collect.testing.features.CollectionFeature; 540888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport com.google.common.collect.testing.features.CollectionSize; 550888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport com.google.common.collect.testing.features.MapFeature; 561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.testing.FakeTicker; 571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.testing.NullPointerTester; 581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.testing.SerializableTester; 591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.testing.TestLogHandler; 601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 610888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport junit.framework.Test; 621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport junit.framework.TestCase; 630888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport junit.framework.TestSuite; 641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.io.Serializable; 661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.lang.ref.Reference; 671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.lang.ref.ReferenceQueue; 681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Iterator; 691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.LinkedHashMap; 701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.List; 711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Map; 720888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport java.util.Map.Entry; 731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Random; 740888a09821a98ac0680fad765217302858e70fa4Paul Duffinimport java.util.Set; 751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.concurrent.CountDownLatch; 761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.concurrent.ExecutionException; 771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.concurrent.TimeUnit; 781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.concurrent.atomic.AtomicReferenceArray; 791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.logging.LogRecord; 801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/** 821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Charles Fry 831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpublic class LocalCacheTest extends TestCase { 851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 860888a09821a98ac0680fad765217302858e70fa4Paul Duffin public static Test suite() { 870888a09821a98ac0680fad765217302858e70fa4Paul Duffin TestSuite suite = new TestSuite(); 880888a09821a98ac0680fad765217302858e70fa4Paul Duffin suite.addTestSuite(LocalCacheTest.class); 890888a09821a98ac0680fad765217302858e70fa4Paul Duffin suite.addTest(MapTestSuiteBuilder.using(new TestStringMapGenerator() { 900888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public Map<String, String> create( 910888a09821a98ac0680fad765217302858e70fa4Paul Duffin Entry<String, String>[] entries) { 920888a09821a98ac0680fad765217302858e70fa4Paul Duffin LocalCache<String, String> map = makeLocalCache(createCacheBuilder()); 930888a09821a98ac0680fad765217302858e70fa4Paul Duffin for (Entry<String, String> entry : entries) { 940888a09821a98ac0680fad765217302858e70fa4Paul Duffin map.put(entry.getKey(), entry.getValue()); 950888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 960888a09821a98ac0680fad765217302858e70fa4Paul Duffin return map; 970888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 980888a09821a98ac0680fad765217302858e70fa4Paul Duffin 990888a09821a98ac0680fad765217302858e70fa4Paul Duffin }).named("LocalCache with defaults") 1000888a09821a98ac0680fad765217302858e70fa4Paul Duffin .withFeatures(CollectionSize.ANY, MapFeature.GENERAL_PURPOSE, 1010888a09821a98ac0680fad765217302858e70fa4Paul Duffin CollectionFeature.SUPPORTS_ITERATOR_REMOVE) 1020888a09821a98ac0680fad765217302858e70fa4Paul Duffin .createTestSuite()); 1030888a09821a98ac0680fad765217302858e70fa4Paul Duffin return suite; 1040888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 1050888a09821a98ac0680fad765217302858e70fa4Paul Duffin 1061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static final int SMALL_MAX_SIZE = DRAIN_THRESHOLD * 5; 1071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert TestLogHandler logHandler; 1091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 1111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void setUp() throws Exception { 1121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert super.setUp(); 1131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert logHandler = new TestLogHandler(); 1141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache.logger.addHandler(logHandler); 1151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 1181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void tearDown() throws Exception { 1191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert super.tearDown(); 1201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache.logger.removeHandler(logHandler); 1211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private Throwable popLoggedThrowable() { 1241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert List<LogRecord> logRecords = logHandler.getStoredLogRecords(); 1251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(1, logRecords.size()); 1261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LogRecord logRecord = logRecords.get(0); 1271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert logHandler.clear(); 1281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return logRecord.getThrown(); 1291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private void checkNothingLogged() { 1321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(logHandler.getStoredLogRecords().isEmpty()); 1331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private void checkLogged(Throwable t) { 1361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(t, popLoggedThrowable()); 1371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1390888a09821a98ac0680fad765217302858e70fa4Paul Duffin private static <K, V> LocalCache<K, V> makeLocalCache( 1400888a09821a98ac0680fad765217302858e70fa4Paul Duffin CacheBuilder<? super K, ? super V> builder) { 1411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new LocalCache<K, V>(builder, null); 1421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static CacheBuilder<Object, Object> createCacheBuilder() { 1451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new CacheBuilder<Object, Object>(); 1461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // constructor tests 1491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testDefaults() { 1511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> map = makeLocalCache(createCacheBuilder()); 1521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(Strength.STRONG, map.keyStrength); 1541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(Strength.STRONG, map.valueStrength); 1551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(map.keyStrength.defaultEquivalence(), map.keyEquivalence); 1561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(map.valueStrength.defaultEquivalence(), map.valueEquivalence); 1571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(0, map.expireAfterAccessNanos); 1591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(0, map.expireAfterWriteNanos); 1601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(0, map.refreshNanos); 1611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(CacheBuilder.UNSET_INT, map.maxWeight); 1621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(EntryFactory.STRONG, map.entryFactory); 1641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(CacheBuilder.NullListener.INSTANCE, map.removalListener); 1651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(DISCARDING_QUEUE, map.removalNotificationQueue); 1661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(NULL_TICKER, map.ticker); 1671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(4, map.concurrencyLevel); 1691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // concurrency level 1711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(4, map.segments.length); 1721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // initial capacity / concurrency level 1731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(16 / map.segments.length, map.segments[0].table.length()); 1741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(map.evictsBySize()); 1761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(map.expires()); 1771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(map.expiresAfterWrite()); 1781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(map.expiresAfterAccess()); 1791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(map.refreshes()); 1801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testSetKeyEquivalence() { 1831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Equivalence<Object> testEquivalence = new Equivalence<Object>() { 1841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 1851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert protected boolean doEquivalent(Object a, Object b) { 1861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 1871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 1901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert protected int doHash(Object t) { 1911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return 0; 1921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 1941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> map = 1961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert makeLocalCache(createCacheBuilder().keyEquivalence(testEquivalence)); 1971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(testEquivalence, map.keyEquivalence); 1981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(map.valueStrength.defaultEquivalence(), map.valueEquivalence); 1991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testSetValueEquivalence() { 2021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Equivalence<Object> testEquivalence = new Equivalence<Object>() { 2031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 2041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert protected boolean doEquivalent(Object a, Object b) { 2051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 2061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 2091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert protected int doHash(Object t) { 2101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return 0; 2111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 2131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> map = 2151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert makeLocalCache(createCacheBuilder().valueEquivalence(testEquivalence)); 2161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(testEquivalence, map.valueEquivalence); 2171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(map.keyStrength.defaultEquivalence(), map.keyEquivalence); 2181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testSetConcurrencyLevel() { 2211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // round up to nearest power of two 2221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkConcurrencyLevel(1, 1); 2241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkConcurrencyLevel(2, 2); 2251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkConcurrencyLevel(3, 4); 2261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkConcurrencyLevel(4, 4); 2271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkConcurrencyLevel(5, 8); 2281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkConcurrencyLevel(6, 8); 2291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkConcurrencyLevel(7, 8); 2301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkConcurrencyLevel(8, 8); 2311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static void checkConcurrencyLevel(int concurrencyLevel, int segmentCount) { 2341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> map = 2351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert makeLocalCache(createCacheBuilder().concurrencyLevel(concurrencyLevel)); 2361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(segmentCount, map.segments.length); 2371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testSetInitialCapacity() { 2401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // share capacity over each segment, then round up to nearest power of two 2411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkInitialCapacity(1, 0, 1); 2431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkInitialCapacity(1, 1, 1); 2441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkInitialCapacity(1, 2, 2); 2451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkInitialCapacity(1, 3, 4); 2461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkInitialCapacity(1, 4, 4); 2471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkInitialCapacity(1, 5, 8); 2481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkInitialCapacity(1, 6, 8); 2491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkInitialCapacity(1, 7, 8); 2501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkInitialCapacity(1, 8, 8); 2511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkInitialCapacity(2, 0, 1); 2531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkInitialCapacity(2, 1, 1); 2541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkInitialCapacity(2, 2, 1); 2551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkInitialCapacity(2, 3, 2); 2561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkInitialCapacity(2, 4, 2); 2571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkInitialCapacity(2, 5, 4); 2581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkInitialCapacity(2, 6, 4); 2591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkInitialCapacity(2, 7, 4); 2601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkInitialCapacity(2, 8, 4); 2611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkInitialCapacity(4, 0, 1); 2631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkInitialCapacity(4, 1, 1); 2641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkInitialCapacity(4, 2, 1); 2651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkInitialCapacity(4, 3, 1); 2661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkInitialCapacity(4, 4, 1); 2671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkInitialCapacity(4, 5, 2); 2681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkInitialCapacity(4, 6, 2); 2691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkInitialCapacity(4, 7, 2); 2701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkInitialCapacity(4, 8, 2); 2711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static void checkInitialCapacity( 2741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int concurrencyLevel, int initialCapacity, int segmentSize) { 2751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> map = makeLocalCache( 2761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert createCacheBuilder().concurrencyLevel(concurrencyLevel).initialCapacity(initialCapacity)); 2771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int i = 0; i < map.segments.length; i++) { 2781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(segmentSize, map.segments[i].table.length()); 2791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testSetMaximumSize() { 2831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // vary maximumSize wrt concurrencyLevel 2841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2857dd252788645e940eada959bdde927426e2531c9Paul Duffin for (int maxSize = 1; maxSize < 100; maxSize++) { 2861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkMaximumSize(1, 8, maxSize); 2871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkMaximumSize(2, 8, maxSize); 2881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkMaximumSize(4, 8, maxSize); 2891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkMaximumSize(8, 8, maxSize); 2901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkMaximumSize(1, 8, Long.MAX_VALUE); 2931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkMaximumSize(2, 8, Long.MAX_VALUE); 2941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkMaximumSize(4, 8, Long.MAX_VALUE); 2951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkMaximumSize(8, 8, Long.MAX_VALUE); 2961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // vary initial capacity wrt maximumSize 2981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int capacity = 0; capacity < 8; capacity++) { 3001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkMaximumSize(1, capacity, 4); 3011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkMaximumSize(2, capacity, 4); 3021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkMaximumSize(4, capacity, 4); 3031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkMaximumSize(8, capacity, 4); 3041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static void checkMaximumSize(int concurrencyLevel, int initialCapacity, long maxSize) { 3081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> map = makeLocalCache(createCacheBuilder() 3091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .concurrencyLevel(concurrencyLevel) 3101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .initialCapacity(initialCapacity) 3111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .maximumSize(maxSize)); 3121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert long totalCapacity = 0; 3137dd252788645e940eada959bdde927426e2531c9Paul Duffin assertTrue("segments=" + map.segments.length + ", maxSize=" + maxSize, 3147dd252788645e940eada959bdde927426e2531c9Paul Duffin map.segments.length <= Math.max(1, maxSize / 10)); 3151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int i = 0; i < map.segments.length; i++) { 3161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert totalCapacity += map.segments[i].maxSegmentWeight; 3171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue("totalCapacity=" + totalCapacity + ", maxSize=" + maxSize, totalCapacity == maxSize); 3191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map = makeLocalCache(createCacheBuilder() 3211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .concurrencyLevel(concurrencyLevel) 3221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .initialCapacity(initialCapacity) 3231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .maximumWeight(maxSize) 3241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .weigher(constantWeigher(1))); 3257dd252788645e940eada959bdde927426e2531c9Paul Duffin assertTrue("segments=" + map.segments.length + ", maxSize=" + maxSize, 3267dd252788645e940eada959bdde927426e2531c9Paul Duffin map.segments.length <= Math.max(1, maxSize / 10)); 3271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert totalCapacity = 0; 3281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int i = 0; i < map.segments.length; i++) { 3291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert totalCapacity += map.segments[i].maxSegmentWeight; 3301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue("totalCapacity=" + totalCapacity + ", maxSize=" + maxSize, totalCapacity == maxSize); 3321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testSetWeigher() { 3351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Weigher<Object, Object> testWeigher = new Weigher<Object, Object>() { 3361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 3371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public int weigh(Object key, Object value) { 3381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return 42; 3391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 3411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> map = 3421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert makeLocalCache(createCacheBuilder().maximumWeight(1).weigher(testWeigher)); 3431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(testWeigher, map.weigher); 3441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testSetWeakKeys() { 3471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> map = makeLocalCache(createCacheBuilder().weakKeys()); 3481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkStrength(map, Strength.WEAK, Strength.STRONG); 3491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(EntryFactory.WEAK, map.entryFactory); 3501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testSetWeakValues() { 3531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> map = makeLocalCache(createCacheBuilder().weakValues()); 3541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkStrength(map, Strength.STRONG, Strength.WEAK); 3551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(EntryFactory.STRONG, map.entryFactory); 3561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testSetSoftValues() { 3591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> map = makeLocalCache(createCacheBuilder().softValues()); 3601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkStrength(map, Strength.STRONG, Strength.SOFT); 3611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(EntryFactory.STRONG, map.entryFactory); 3621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static void checkStrength( 3651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> map, Strength keyStrength, Strength valueStrength) { 3661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(keyStrength, map.keyStrength); 3671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(valueStrength, map.valueStrength); 3681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(keyStrength.defaultEquivalence(), map.keyEquivalence); 3691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(valueStrength.defaultEquivalence(), map.valueEquivalence); 3701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testSetExpireAfterWrite() { 3731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert long duration = 42; 3741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert TimeUnit unit = TimeUnit.SECONDS; 3751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> map = 3761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert makeLocalCache(createCacheBuilder().expireAfterWrite(duration, unit)); 3771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(unit.toNanos(duration), map.expireAfterWriteNanos); 3781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testSetExpireAfterAccess() { 3811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert long duration = 42; 3821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert TimeUnit unit = TimeUnit.SECONDS; 3831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> map = 3841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert makeLocalCache(createCacheBuilder().expireAfterAccess(duration, unit)); 3851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(unit.toNanos(duration), map.expireAfterAccessNanos); 3861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testSetRefresh() { 3891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert long duration = 42; 3901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert TimeUnit unit = TimeUnit.SECONDS; 3911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> map = 3921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert makeLocalCache(createCacheBuilder().refreshAfterWrite(duration, unit)); 3931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(unit.toNanos(duration), map.refreshNanos); 3941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testSetRemovalListener() { 3971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert RemovalListener<Object, Object> testListener = TestingRemovalListeners.nullRemovalListener(); 3981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> map = 3991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert makeLocalCache(createCacheBuilder().removalListener(testListener)); 4001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(testListener, map.removalListener); 4011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testSetTicker() { 4041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Ticker testTicker = new Ticker() { 4051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 4061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public long read() { 4071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return 0; 4081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 4101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> map = makeLocalCache(createCacheBuilder().ticker(testTicker)); 4111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(testTicker, map.ticker); 4121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testEntryFactory() { 4151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(EntryFactory.STRONG, 4161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert EntryFactory.getFactory(Strength.STRONG, false, false)); 4171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(EntryFactory.STRONG_ACCESS, 4181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert EntryFactory.getFactory(Strength.STRONG, true, false)); 4191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(EntryFactory.STRONG_WRITE, 4201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert EntryFactory.getFactory(Strength.STRONG, false, true)); 4211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(EntryFactory.STRONG_ACCESS_WRITE, 4221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert EntryFactory.getFactory(Strength.STRONG, true, true)); 4231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(EntryFactory.WEAK, 4241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert EntryFactory.getFactory(Strength.WEAK, false, false)); 4251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(EntryFactory.WEAK_ACCESS, 4261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert EntryFactory.getFactory(Strength.WEAK, true, false)); 4271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(EntryFactory.WEAK_WRITE, 4281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert EntryFactory.getFactory(Strength.WEAK, false, true)); 4291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(EntryFactory.WEAK_ACCESS_WRITE, 4301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert EntryFactory.getFactory(Strength.WEAK, true, true)); 4311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // computation tests 4341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testCompute() throws ExecutionException { 4361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CountingLoader loader = new CountingLoader(); 4371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> map = makeLocalCache(createCacheBuilder()); 4381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(0, loader.getCount()); 4391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object key = new Object(); 4411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object value = map.get(key, loader); 4421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, loader.getCount()); 4431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(value, map.get(key, loader)); 4441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, loader.getCount()); 4451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testRecordReadOnCompute() throws ExecutionException { 4481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CountingLoader loader = new CountingLoader(); 4491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (CacheBuilder<Object, Object> builder : allEvictingMakers()) { 4501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> map = 4511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert makeLocalCache(builder.concurrencyLevel(1)); 4521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Segment<Object, Object> segment = map.segments[0]; 4531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert List<ReferenceEntry<Object, Object>> writeOrder = Lists.newLinkedList(); 4541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert List<ReferenceEntry<Object, Object>> readOrder = Lists.newLinkedList(); 4551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int i = 0; i < SMALL_MAX_SIZE; i++) { 4561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object key = new Object(); 4571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int hash = map.hash(key); 4581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map.get(key, loader); 4601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ReferenceEntry<Object, Object> entry = segment.getEntry(key, hash); 4611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert writeOrder.add(entry); 4621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert readOrder.add(entry); 4631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkEvictionQueues(map, segment, readOrder, writeOrder); 4661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkExpirationTimes(map); 4671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(segment.recencyQueue.isEmpty()); 4681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // access some of the elements 4701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Random random = new Random(); 4711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert List<ReferenceEntry<Object, Object>> reads = Lists.newArrayList(); 4721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Iterator<ReferenceEntry<Object, Object>> i = readOrder.iterator(); 4731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert while (i.hasNext()) { 4741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ReferenceEntry<Object, Object> entry = i.next(); 4751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (random.nextBoolean()) { 4761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map.get(entry.getKey(), loader); 4771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert reads.add(entry); 4781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert i.remove(); 4791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(segment.recencyQueue.size() <= DRAIN_THRESHOLD); 4801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int undrainedIndex = reads.size() - segment.recencyQueue.size(); 4831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkAndDrainRecencyQueue(map, segment, reads.subList(undrainedIndex, reads.size())); 4841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert readOrder.addAll(reads); 4851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkEvictionQueues(map, segment, readOrder, writeOrder); 4871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkExpirationTimes(map); 4881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testComputeExistingEntry() throws ExecutionException { 4921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CountingLoader loader = new CountingLoader(); 4931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> map = makeLocalCache(createCacheBuilder()); 4941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(0, loader.getCount()); 4951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object key = new Object(); 4971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object value = new Object(); 4981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map.put(key, value); 4991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(value, map.get(key, loader)); 5011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(0, loader.getCount()); 5021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testComputePartiallyCollectedKey() throws ExecutionException { 5051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CacheBuilder<Object, Object> builder = createCacheBuilder().concurrencyLevel(1); 5061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CountingLoader loader = new CountingLoader(); 5071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> map = makeLocalCache(builder); 5081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Segment<Object, Object> segment = map.segments[0]; 5091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert AtomicReferenceArray<ReferenceEntry<Object, Object>> table = segment.table; 5101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(0, loader.getCount()); 5111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object key = new Object(); 5131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int hash = map.hash(key); 5141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object value = new Object(); 5151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int index = hash & (table.length() - 1); 5161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert DummyEntry<Object, Object> entry = DummyEntry.create(key, hash, null); 5187dd252788645e940eada959bdde927426e2531c9Paul Duffin DummyValueReference<Object, Object> valueRef = DummyValueReference.create(value); 5191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert entry.setValueReference(valueRef); 5201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert table.set(index, entry); 5211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert segment.count++; 5221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(value, map.get(key, loader)); 5241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(0, loader.getCount()); 5251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, segment.count); 5261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert entry.clearKey(); 5281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNotSame(value, map.get(key, loader)); 5291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, loader.getCount()); 5301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(2, segment.count); 5311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testComputePartiallyCollectedValue() throws ExecutionException { 5341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CacheBuilder<Object, Object> builder = createCacheBuilder().concurrencyLevel(1); 5351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CountingLoader loader = new CountingLoader(); 5361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> map = makeLocalCache(builder); 5371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Segment<Object, Object> segment = map.segments[0]; 5381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert AtomicReferenceArray<ReferenceEntry<Object, Object>> table = segment.table; 5391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(0, loader.getCount()); 5401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object key = new Object(); 5421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int hash = map.hash(key); 5431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object value = new Object(); 5441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int index = hash & (table.length() - 1); 5451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert DummyEntry<Object, Object> entry = DummyEntry.create(key, hash, null); 5477dd252788645e940eada959bdde927426e2531c9Paul Duffin DummyValueReference<Object, Object> valueRef = DummyValueReference.create(value); 5481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert entry.setValueReference(valueRef); 5491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert table.set(index, entry); 5501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert segment.count++; 5511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(value, map.get(key, loader)); 5531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(0, loader.getCount()); 5541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, segment.count); 5551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert valueRef.clear(); 5571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNotSame(value, map.get(key, loader)); 5581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, loader.getCount()); 5591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, segment.count); 5601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testComputeExpiredEntry() throws ExecutionException { 5631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CacheBuilder<Object, Object> builder = createCacheBuilder() 5641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .expireAfterWrite(1, TimeUnit.NANOSECONDS); 5651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CountingLoader loader = new CountingLoader(); 5661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> map = makeLocalCache(builder); 5671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(0, loader.getCount()); 5681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object key = new Object(); 5701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object one = map.get(key, loader); 5711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, loader.getCount()); 5721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object two = map.get(key, loader); 5741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNotSame(one, two); 5751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(2, loader.getCount()); 5761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5780888a09821a98ac0680fad765217302858e70fa4Paul Duffin public void testValues() { 5790888a09821a98ac0680fad765217302858e70fa4Paul Duffin LocalCache<Object, Object> map = makeLocalCache(createCacheBuilder()); 5800888a09821a98ac0680fad765217302858e70fa4Paul Duffin map.put("foo", "bar"); 5810888a09821a98ac0680fad765217302858e70fa4Paul Duffin map.put("baz", "bar"); 5820888a09821a98ac0680fad765217302858e70fa4Paul Duffin map.put("quux", "quux"); 5830888a09821a98ac0680fad765217302858e70fa4Paul Duffin assertFalse(map.values() instanceof Set); 5840888a09821a98ac0680fad765217302858e70fa4Paul Duffin assertTrue(map.values().removeAll(ImmutableSet.of("bar"))); 5850888a09821a98ac0680fad765217302858e70fa4Paul Duffin assertEquals(1, map.size()); 5860888a09821a98ac0680fad765217302858e70fa4Paul Duffin } 5870888a09821a98ac0680fad765217302858e70fa4Paul Duffin 5881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testCopyEntry_computing() { 5891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final CountDownLatch startSignal = new CountDownLatch(1); 5901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final CountDownLatch computingSignal = new CountDownLatch(1); 5911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final CountDownLatch doneSignal = new CountDownLatch(2); 5921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Object computedObject = new Object(); 5931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final CacheLoader<Object, Object> loader = new CacheLoader<Object, Object>() { 5951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 5961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public Object load(Object key) throws Exception { 5971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert computingSignal.countDown(); 5981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert startSignal.await(); 5991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return computedObject; 6001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 6021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert QueuingRemovalListener<Object, Object> listener = queuingRemovalListener(); 6041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CacheBuilder<Object, Object> builder = createCacheBuilder() 6051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .concurrencyLevel(1) 6061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .removalListener(listener); 6071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final LocalCache<Object, Object> map = makeLocalCache(builder); 6081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Segment<Object, Object> segment = map.segments[0]; 6091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert AtomicReferenceArray<ReferenceEntry<Object, Object>> table = segment.table; 6101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(listener.isEmpty()); 6111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Object one = new Object(); 6131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int hash = map.hash(one); 6141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int index = hash & (table.length() - 1); 6151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert new Thread() { 6171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 6181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void run() { 6191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 6201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map.get(one, loader); 6211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (ExecutionException e) { 6221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new RuntimeException(e); 6231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert doneSignal.countDown(); 6251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }.start(); 6271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 6291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert computingSignal.await(); 6301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (InterruptedException e) { 6311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new RuntimeException(e); 6321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert new Thread() { 6351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 6361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void run() { 6371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 6381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map.get(one, loader); 6391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (ExecutionException e) { 6401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new RuntimeException(e); 6411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert doneSignal.countDown(); 6431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }.start(); 6451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ReferenceEntry<Object, Object> entry = segment.getEntry(one, hash); 6471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ReferenceEntry<Object, Object> newEntry = segment.copyEntry(entry, null); 6481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert table.set(index, newEntry); 6491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @SuppressWarnings("unchecked") 6511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LoadingValueReference<Object, Object> valueReference = 6521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert (LoadingValueReference) newEntry.getValueReference(); 6531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(valueReference.futureValue.isDone()); 6541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert startSignal.countDown(); 6551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 6571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert doneSignal.await(); 6581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (InterruptedException e) { 6591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new RuntimeException(e); 6601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map.cleanUp(); // force notifications 6631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(listener.isEmpty()); 6641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(map.containsKey(one)); 6651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, map.size()); 6661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(computedObject, map.get(one)); 6671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testRemovalListenerCheckedException() { 6701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final RuntimeException e = new RuntimeException(); 6711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert RemovalListener<Object, Object> listener = new RemovalListener<Object, Object>() { 6721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 6731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void onRemoval(RemovalNotification<Object, Object> notification) { 6741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw e; 6751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 6771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CacheBuilder<Object, Object> builder = createCacheBuilder().removalListener(listener); 6791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final LocalCache<Object, Object> cache = makeLocalCache(builder); 6801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object key = new Object(); 6811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert cache.put(key, new Object()); 6821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNothingLogged(); 6831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert cache.remove(key); 6851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkLogged(e); 6861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testRemovalListener_replaced_computing() { 6891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final CountDownLatch startSignal = new CountDownLatch(1); 6901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final CountDownLatch computingSignal = new CountDownLatch(1); 6911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final CountDownLatch doneSignal = new CountDownLatch(1); 6921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Object computedObject = new Object(); 6931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final CacheLoader<Object, Object> loader = new CacheLoader<Object, Object>() { 6951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 6961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public Object load(Object key) throws Exception { 6971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert computingSignal.countDown(); 6981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert startSignal.await(); 6991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return computedObject; 7001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 7021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert QueuingRemovalListener<Object, Object> listener = queuingRemovalListener(); 7041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CacheBuilder<Object, Object> builder = createCacheBuilder().removalListener(listener); 7051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final LocalCache<Object, Object> map = makeLocalCache(builder); 7061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(listener.isEmpty()); 7071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Object one = new Object(); 7091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Object two = new Object(); 7101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert new Thread() { 7121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 7131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void run() { 7141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 7151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map.get(one, loader); 7161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (ExecutionException e) { 7171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new RuntimeException(e); 7181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert doneSignal.countDown(); 7201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }.start(); 7221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 7241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert computingSignal.await(); 7251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (InterruptedException e) { 7261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new RuntimeException(e); 7271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map.put(one, two); 7301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(two, map.get(one)); 7311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert startSignal.countDown(); 7321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 7341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert doneSignal.await(); 7351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (InterruptedException e) { 7361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new RuntimeException(e); 7371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map.cleanUp(); // force notifications 7401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNotified(listener, one, computedObject, RemovalCause.REPLACED); 7411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(listener.isEmpty()); 7421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testSegmentRefresh_duplicate() throws ExecutionException { 7451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> map = makeLocalCache(createCacheBuilder() 7461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .concurrencyLevel(1)); 7471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Segment<Object, Object> segment = map.segments[0]; 7481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object key = new Object(); 7501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int hash = map.hash(key); 7511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert AtomicReferenceArray<ReferenceEntry<Object, Object>> table = segment.table; 7521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int index = hash & (table.length() - 1); 7531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // already loading 7551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert DummyEntry<Object, Object> entry = DummyEntry.create(key, hash, null); 7567dd252788645e940eada959bdde927426e2531c9Paul Duffin DummyValueReference<Object, Object> valueRef = DummyValueReference.create(null); 7571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert valueRef.setLoading(true); 7581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert entry.setValueReference(valueRef); 7591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert table.set(index, entry); 7607dd252788645e940eada959bdde927426e2531c9Paul Duffin assertNull(segment.refresh(key, hash, identityLoader(), false)); 7611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // Removal listener tests 7641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testRemovalListener_explicit() { 7661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert QueuingRemovalListener<Object, Object> listener = queuingRemovalListener(); 7671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> map = makeLocalCache(createCacheBuilder() 7681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .removalListener(listener)); 7691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(listener.isEmpty()); 7701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object one = new Object(); 7721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object two = new Object(); 7731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object three = new Object(); 7741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object four = new Object(); 7751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object five = new Object(); 7761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object six = new Object(); 7771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map.put(one, two); 7791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map.remove(one); 7801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNotified(listener, one, two, RemovalCause.EXPLICIT); 7811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map.put(two, three); 7831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map.remove(two, three); 7841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNotified(listener, two, three, RemovalCause.EXPLICIT); 7851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map.put(three, four); 7871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Iterator<?> i = map.entrySet().iterator(); 7881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert i.next(); 7891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert i.remove(); 7901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNotified(listener, three, four, RemovalCause.EXPLICIT); 7911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map.put(four, five); 7931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert i = map.keySet().iterator(); 7941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert i.next(); 7951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert i.remove(); 7961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNotified(listener, four, five, RemovalCause.EXPLICIT); 7971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map.put(five, six); 7991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert i = map.values().iterator(); 8001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert i.next(); 8011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert i.remove(); 8021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNotified(listener, five, six, RemovalCause.EXPLICIT); 8031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(listener.isEmpty()); 8051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testRemovalListener_replaced() { 8081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert QueuingRemovalListener<Object, Object> listener = queuingRemovalListener(); 8091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> map = makeLocalCache(createCacheBuilder() 8101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .removalListener(listener)); 8111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(listener.isEmpty()); 8121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object one = new Object(); 8141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object two = new Object(); 8151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object three = new Object(); 8161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object four = new Object(); 8171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object five = new Object(); 8181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object six = new Object(); 8191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map.put(one, two); 8211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map.put(one, three); 8221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNotified(listener, one, two, RemovalCause.REPLACED); 8231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Map<Object, Object> newMap = ImmutableMap.of(one, four); 8251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map.putAll(newMap); 8261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNotified(listener, one, three, RemovalCause.REPLACED); 8271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map.replace(one, five); 8291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNotified(listener, one, four, RemovalCause.REPLACED); 8301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map.replace(one, five, six); 8321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNotified(listener, one, five, RemovalCause.REPLACED); 8331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testRemovalListener_collected() { 8361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert QueuingRemovalListener<Object, Object> listener = queuingRemovalListener(); 8371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> map = makeLocalCache(createCacheBuilder() 8381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .concurrencyLevel(1) 8391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .softValues() 8401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .removalListener(listener)); 8411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Segment<Object, Object> segment = map.segments[0]; 8421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(listener.isEmpty()); 8431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object one = new Object(); 8451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object two = new Object(); 8461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object three = new Object(); 8471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map.put(one, two); 8491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map.put(two, three); 8501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(listener.isEmpty()); 8511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int hash = map.hash(one); 8531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ReferenceEntry<Object, Object> entry = segment.getEntry(one, hash); 8541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map.reclaimValue(entry.getValueReference()); 8551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNotified(listener, one, two, RemovalCause.COLLECTED); 8561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(listener.isEmpty()); 8581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testRemovalListener_expired() { 8611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert FakeTicker ticker = new FakeTicker(); 8621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert QueuingRemovalListener<Object, Object> listener = queuingRemovalListener(); 8631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> map = makeLocalCache(createCacheBuilder() 8641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .concurrencyLevel(1) 8657dd252788645e940eada959bdde927426e2531c9Paul Duffin .expireAfterWrite(3, TimeUnit.NANOSECONDS) 8661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .ticker(ticker) 8671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .removalListener(listener)); 8681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(listener.isEmpty()); 8691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object one = new Object(); 8711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object two = new Object(); 8721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object three = new Object(); 8731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object four = new Object(); 8741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object five = new Object(); 8751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map.put(one, two); 8771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ticker.advance(1); 8781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map.put(two, three); 8791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ticker.advance(1); 8801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map.put(three, four); 8811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(listener.isEmpty()); 8821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ticker.advance(1); 8831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map.put(four, five); 8841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNotified(listener, one, two, RemovalCause.EXPIRED); 8851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(listener.isEmpty()); 8871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testRemovalListener_size() { 8901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert QueuingRemovalListener<Object, Object> listener = queuingRemovalListener(); 8911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> map = makeLocalCache(createCacheBuilder() 8921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .concurrencyLevel(1) 8931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .maximumSize(2) 8941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .removalListener(listener)); 8951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(listener.isEmpty()); 8961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object one = new Object(); 8981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object two = new Object(); 8991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object three = new Object(); 9001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object four = new Object(); 9011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map.put(one, two); 9031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map.put(two, three); 9041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(listener.isEmpty()); 9051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map.put(three, four); 9061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNotified(listener, one, two, RemovalCause.SIZE); 9071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(listener.isEmpty()); 9091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static <K, V> void assertNotified( 9121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert QueuingRemovalListener<K, V> listener, K key, V value, RemovalCause cause) { 9131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert RemovalNotification<K, V> notification = listener.remove(); 9141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(key, notification.getKey()); 9151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(value, notification.getValue()); 9161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(cause, notification.getCause()); 9171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // Segment core tests 9201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testNewEntry() { 9221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (CacheBuilder<Object, Object> builder : allEntryTypeMakers()) { 9231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> map = makeLocalCache(builder); 9241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object keyOne = new Object(); 9261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object valueOne = new Object(); 9271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int hashOne = map.hash(keyOne); 9281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ReferenceEntry<Object, Object> entryOne = map.newEntry(keyOne, hashOne, null); 9291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ValueReference<Object, Object> valueRefOne = map.newValueReference(entryOne, valueOne, 1); 9301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(valueOne, valueRefOne.get()); 9311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert entryOne.setValueReference(valueRefOne); 9321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(keyOne, entryOne.getKey()); 9341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(hashOne, entryOne.getHash()); 9351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNull(entryOne.getNext()); 9361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(valueRefOne, entryOne.getValueReference()); 9371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object keyTwo = new Object(); 9391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object valueTwo = new Object(); 9401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int hashTwo = map.hash(keyTwo); 9411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ReferenceEntry<Object, Object> entryTwo = map.newEntry(keyTwo, hashTwo, entryOne); 9421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ValueReference<Object, Object> valueRefTwo = map.newValueReference(entryTwo, valueTwo, 1); 9431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(valueTwo, valueRefTwo.get()); 9441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert entryTwo.setValueReference(valueRefTwo); 9451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(keyTwo, entryTwo.getKey()); 9471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(hashTwo, entryTwo.getHash()); 9481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(entryOne, entryTwo.getNext()); 9491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(valueRefTwo, entryTwo.getValueReference()); 9501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testCopyEntry() { 9541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (CacheBuilder<Object, Object> builder : allEntryTypeMakers()) { 9551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> map = makeLocalCache(builder); 9561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object keyOne = new Object(); 9581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object valueOne = new Object(); 9591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int hashOne = map.hash(keyOne); 9601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ReferenceEntry<Object, Object> entryOne = map.newEntry(keyOne, hashOne, null); 9611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert entryOne.setValueReference(map.newValueReference(entryOne, valueOne, 1)); 9621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object keyTwo = new Object(); 9641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object valueTwo = new Object(); 9651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int hashTwo = map.hash(keyTwo); 9661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ReferenceEntry<Object, Object> entryTwo = map.newEntry(keyTwo, hashTwo, entryOne); 9671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert entryTwo.setValueReference(map.newValueReference(entryTwo, valueTwo, 1)); 9681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (map.usesAccessQueue()) { 9691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache.connectAccessOrder(entryOne, entryTwo); 9701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (map.usesWriteQueue()) { 9721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache.connectWriteOrder(entryOne, entryTwo); 9731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertConnected(map, entryOne, entryTwo); 9751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ReferenceEntry<Object, Object> copyOne = map.copyEntry(entryOne, null); 9771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(keyOne, entryOne.getKey()); 9781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(hashOne, entryOne.getHash()); 9791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNull(entryOne.getNext()); 9801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(valueOne, copyOne.getValueReference().get()); 9811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertConnected(map, copyOne, entryTwo); 9821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ReferenceEntry<Object, Object> copyTwo = map.copyEntry(entryTwo, copyOne); 9841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(keyTwo, copyTwo.getKey()); 9851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(hashTwo, copyTwo.getHash()); 9861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(copyOne, copyTwo.getNext()); 9871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(valueTwo, copyTwo.getValueReference().get()); 9881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertConnected(map, copyOne, copyTwo); 9891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 9921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static <K, V> void assertConnected( 9931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<K, V> map, ReferenceEntry<K, V> one, ReferenceEntry<K, V> two) { 9941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (map.usesWriteQueue()) { 9951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(two, one.getNextInWriteQueue()); 9961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 9971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (map.usesAccessQueue()) { 9981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(two, one.getNextInAccessQueue()); 9991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testSegmentGetAndContains() { 10031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert FakeTicker ticker = new FakeTicker(); 10041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> map = makeLocalCache(createCacheBuilder() 10051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .concurrencyLevel(1) 10061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .ticker(ticker) 10071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .expireAfterAccess(1, TimeUnit.NANOSECONDS)); 10081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Segment<Object, Object> segment = map.segments[0]; 10091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // TODO(fry): check recency ordering 10101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object key = new Object(); 10121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int hash = map.hash(key); 10131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object value = new Object(); 10141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert AtomicReferenceArray<ReferenceEntry<Object, Object>> table = segment.table; 10151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int index = hash & (table.length() - 1); 10161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ReferenceEntry<Object, Object> entry = map.newEntry(key, hash, null); 10181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ValueReference<Object, Object> valueRef = map.newValueReference(entry, value, 1); 10191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert entry.setValueReference(valueRef); 10201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNull(segment.get(key, hash)); 10221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // count == 0 10241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert table.set(index, entry); 10251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNull(segment.get(key, hash)); 10261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(segment.containsKey(key, hash)); 10271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(segment.containsValue(value)); 10281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // count == 1 10301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert segment.count++; 10311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(value, segment.get(key, hash)); 10321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(segment.containsKey(key, hash)); 10331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(segment.containsValue(value)); 10341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // don't see absent values now that count > 0 10351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNull(segment.get(new Object(), hash)); 10361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // null key 10381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert DummyEntry<Object, Object> nullEntry = DummyEntry.create(null, hash, entry); 10391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object nullValue = new Object(); 10401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ValueReference<Object, Object> nullValueRef = map.newValueReference(nullEntry, nullValue, 1); 10411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert nullEntry.setValueReference(nullValueRef); 10421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert table.set(index, nullEntry); 10431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // skip the null key 10441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(value, segment.get(key, hash)); 10451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(segment.containsKey(key, hash)); 10461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(segment.containsValue(value)); 10471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(segment.containsValue(nullValue)); 10481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // hash collision 10501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert DummyEntry<Object, Object> dummy = DummyEntry.create(new Object(), hash, entry); 10511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object dummyValue = new Object(); 10521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ValueReference<Object, Object> dummyValueRef = map.newValueReference(dummy, dummyValue, 1); 10531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert dummy.setValueReference(dummyValueRef); 10541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert table.set(index, dummy); 10551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(value, segment.get(key, hash)); 10561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(segment.containsKey(key, hash)); 10571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(segment.containsValue(value)); 10581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(segment.containsValue(dummyValue)); 10591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // key collision 10611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert dummy = DummyEntry.create(key, hash, entry); 10621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert dummyValue = new Object(); 10631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert dummyValueRef = map.newValueReference(dummy, dummyValue, 1); 10641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert dummy.setValueReference(dummyValueRef); 10651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert table.set(index, dummy); 10661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // returns the most recent entry 10671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(dummyValue, segment.get(key, hash)); 10681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(segment.containsKey(key, hash)); 10691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(segment.containsValue(value)); 10701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(segment.containsValue(dummyValue)); 10711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // expired 10731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert dummy.setAccessTime(ticker.read() - 2); 10741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNull(segment.get(key, hash)); 10751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(segment.containsKey(key, hash)); 10761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(segment.containsValue(value)); 10771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(segment.containsValue(dummyValue)); 10781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 10791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testSegmentReplaceValue() { 10811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> map = 10821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert makeLocalCache(createCacheBuilder().concurrencyLevel(1).expireAfterAccess(99999, SECONDS)); 10831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Segment<Object, Object> segment = map.segments[0]; 10841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // TODO(fry): check recency ordering 10851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object key = new Object(); 10871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int hash = map.hash(key); 10881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object oldValue = new Object(); 10891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object newValue = new Object(); 10901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert AtomicReferenceArray<ReferenceEntry<Object, Object>> table = segment.table; 10911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int index = hash & (table.length() - 1); 10921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert DummyEntry<Object, Object> entry = DummyEntry.create(key, hash, null); 10947dd252788645e940eada959bdde927426e2531c9Paul Duffin DummyValueReference<Object, Object> oldValueRef = DummyValueReference.create(oldValue); 10951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert entry.setValueReference(oldValueRef); 10961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 10971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // no entry 10981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(segment.replace(key, hash, oldValue, newValue)); 10991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(0, segment.count); 11001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // same value 11021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert table.set(index, entry); 11031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert segment.count++; 11041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, segment.count); 11051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(oldValue, segment.get(key, hash)); 11061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(segment.replace(key, hash, oldValue, newValue)); 11071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, segment.count); 11081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(newValue, segment.get(key, hash)); 11091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // different value 11111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(segment.replace(key, hash, oldValue, newValue)); 11121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, segment.count); 11131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(newValue, segment.get(key, hash)); 11141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // cleared 11161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert entry.setValueReference(oldValueRef); 11171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(oldValue, segment.get(key, hash)); 11181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert oldValueRef.clear(); 11191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(segment.replace(key, hash, oldValue, newValue)); 11201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(0, segment.count); 11211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNull(segment.get(key, hash)); 11221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testSegmentReplace() { 11251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> map = 11261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert makeLocalCache(createCacheBuilder().concurrencyLevel(1).expireAfterAccess(99999, SECONDS)); 11271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Segment<Object, Object> segment = map.segments[0]; 11281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // TODO(fry): check recency ordering 11291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object key = new Object(); 11311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int hash = map.hash(key); 11321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object oldValue = new Object(); 11331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object newValue = new Object(); 11341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert AtomicReferenceArray<ReferenceEntry<Object, Object>> table = segment.table; 11351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int index = hash & (table.length() - 1); 11361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert DummyEntry<Object, Object> entry = DummyEntry.create(key, hash, null); 11387dd252788645e940eada959bdde927426e2531c9Paul Duffin DummyValueReference<Object, Object> oldValueRef = DummyValueReference.create(oldValue); 11391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert entry.setValueReference(oldValueRef); 11401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // no entry 11421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNull(segment.replace(key, hash, newValue)); 11431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(0, segment.count); 11441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // same key 11461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert table.set(index, entry); 11471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert segment.count++; 11481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, segment.count); 11491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(oldValue, segment.get(key, hash)); 11501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(oldValue, segment.replace(key, hash, newValue)); 11511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, segment.count); 11521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(newValue, segment.get(key, hash)); 11531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // cleared 11551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert entry.setValueReference(oldValueRef); 11561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(oldValue, segment.get(key, hash)); 11571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert oldValueRef.clear(); 11581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNull(segment.replace(key, hash, newValue)); 11591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(0, segment.count); 11601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNull(segment.get(key, hash)); 11611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testSegmentPut() { 11641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> map = 11651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert makeLocalCache(createCacheBuilder().concurrencyLevel(1).expireAfterAccess(99999, SECONDS)); 11661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Segment<Object, Object> segment = map.segments[0]; 11671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // TODO(fry): check recency ordering 11681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object key = new Object(); 11701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int hash = map.hash(key); 11711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object oldValue = new Object(); 11721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object newValue = new Object(); 11731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // no entry 11751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(0, segment.count); 11761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNull(segment.put(key, hash, oldValue, false)); 11771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, segment.count); 11781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // same key 11801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(oldValue, segment.put(key, hash, newValue, false)); 11811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, segment.count); 11821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(newValue, segment.get(key, hash)); 11831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // cleared 11851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ReferenceEntry<Object, Object> entry = segment.getEntry(key, hash); 11867dd252788645e940eada959bdde927426e2531c9Paul Duffin DummyValueReference<Object, Object> oldValueRef = DummyValueReference.create(oldValue); 11871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert entry.setValueReference(oldValueRef); 11881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(oldValue, segment.get(key, hash)); 11891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert oldValueRef.clear(); 11901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNull(segment.put(key, hash, newValue, false)); 11911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, segment.count); 11921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(newValue, segment.get(key, hash)); 11931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 11941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 11951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testSegmentPutIfAbsent() { 11961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> map = 11971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert makeLocalCache(createCacheBuilder().concurrencyLevel(1).expireAfterAccess(99999, SECONDS)); 11981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Segment<Object, Object> segment = map.segments[0]; 11991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // TODO(fry): check recency ordering 12001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 12011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object key = new Object(); 12021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int hash = map.hash(key); 12031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object oldValue = new Object(); 12041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object newValue = new Object(); 12051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 12061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // no entry 12071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(0, segment.count); 12081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNull(segment.put(key, hash, oldValue, true)); 12091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, segment.count); 12101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 12111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // same key 12121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(oldValue, segment.put(key, hash, newValue, true)); 12131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, segment.count); 12141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(oldValue, segment.get(key, hash)); 12151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 12161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // cleared 12171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ReferenceEntry<Object, Object> entry = segment.getEntry(key, hash); 12187dd252788645e940eada959bdde927426e2531c9Paul Duffin DummyValueReference<Object, Object> oldValueRef = DummyValueReference.create(oldValue); 12191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert entry.setValueReference(oldValueRef); 12201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(oldValue, segment.get(key, hash)); 12211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert oldValueRef.clear(); 12221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNull(segment.put(key, hash, newValue, true)); 12231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, segment.count); 12241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(newValue, segment.get(key, hash)); 12251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 12271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testSegmentPut_expand() { 12281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> map = 12291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert makeLocalCache(createCacheBuilder().concurrencyLevel(1).initialCapacity(1)); 12301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Segment<Object, Object> segment = map.segments[0]; 12311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, segment.table.length()); 12321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 12331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int count = 1024; 12341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int i = 0; i < count; i++) { 12351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object key = new Object(); 12361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object value = new Object(); 12371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int hash = map.hash(key); 12381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNull(segment.put(key, hash, value, false)); 12391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(segment.table.length() > i); 12401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 12431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testSegmentPut_evict() { 12441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int maxSize = 10; 12451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> map = 12461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert makeLocalCache(createCacheBuilder().concurrencyLevel(1).maximumSize(maxSize)); 12471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 12481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // manually add elements to avoid eviction 12491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int originalCount = 1024; 12501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LinkedHashMap<Object, Object> originalMap = Maps.newLinkedHashMap(); 12511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int i = 0; i < originalCount; i++) { 12521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object key = new Object(); 12531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object value = new Object(); 12541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map.put(key, value); 12551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert originalMap.put(key, value); 12561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (i >= maxSize) { 12571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Iterator<Object> it = originalMap.keySet().iterator(); 12581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert it.next(); 12591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert it.remove(); 12601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(originalMap, map); 12621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 12641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 12651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testSegmentStoreComputedValue() { 12661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert QueuingRemovalListener<Object, Object> listener = queuingRemovalListener(); 12671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> map = makeLocalCache(createCacheBuilder() 12681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .concurrencyLevel(1) 12691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .removalListener(listener)); 12701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Segment<Object, Object> segment = map.segments[0]; 12711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 12721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object key = new Object(); 12731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int hash = map.hash(key); 12741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert AtomicReferenceArray<ReferenceEntry<Object, Object>> table = segment.table; 12751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int index = hash & (table.length() - 1); 12761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 12771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert DummyEntry<Object, Object> entry = DummyEntry.create(key, hash, null); 12781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LoadingValueReference<Object, Object> valueRef = new LoadingValueReference<Object, Object>(); 12791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert entry.setValueReference(valueRef); 12801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 12811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // absent 12821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object value = new Object(); 12831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(listener.isEmpty()); 12841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(0, segment.count); 12851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNull(segment.get(key, hash)); 12861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(segment.storeLoadedValue(key, hash, valueRef, value)); 12871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(value, segment.get(key, hash)); 12881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, segment.count); 12891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(listener.isEmpty()); 12901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 12911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // clobbered 12921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object value2 = new Object(); 12931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(segment.storeLoadedValue(key, hash, valueRef, value2)); 12941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, segment.count); 12951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(value, segment.get(key, hash)); 12961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert RemovalNotification<Object, Object> notification = listener.remove(); 12971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(immutableEntry(key, value2), notification); 12981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(RemovalCause.REPLACED, notification.getCause()); 12991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(listener.isEmpty()); 13001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 13011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // inactive 13021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object value3 = new Object(); 13031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map.clear(); 13041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert listener.clear(); 13051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(0, segment.count); 13061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert table.set(index, entry); 13071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(segment.storeLoadedValue(key, hash, valueRef, value3)); 13081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(value3, segment.get(key, hash)); 13091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, segment.count); 13101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(listener.isEmpty()); 13111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 13121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // replaced 13131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object value4 = new Object(); 13147dd252788645e940eada959bdde927426e2531c9Paul Duffin DummyValueReference<Object, Object> value3Ref = DummyValueReference.create(value3); 13151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert valueRef = new LoadingValueReference<Object, Object>(value3Ref); 13161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert entry.setValueReference(valueRef); 13171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert table.set(index, entry); 13181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(value3, segment.get(key, hash)); 13191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, segment.count); 13201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(segment.storeLoadedValue(key, hash, valueRef, value4)); 13211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(value4, segment.get(key, hash)); 13221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, segment.count); 13231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert notification = listener.remove(); 13241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(immutableEntry(key, value3), notification); 13251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(RemovalCause.REPLACED, notification.getCause()); 13261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(listener.isEmpty()); 13271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 13281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // collected 13291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert entry.setValueReference(valueRef); 13301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert table.set(index, entry); 13311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(value3, segment.get(key, hash)); 13321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, segment.count); 13331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert value3Ref.clear(); 13341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(segment.storeLoadedValue(key, hash, valueRef, value4)); 13351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(value4, segment.get(key, hash)); 13361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, segment.count); 13371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert notification = listener.remove(); 13381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(immutableEntry(key, null), notification); 13391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(RemovalCause.COLLECTED, notification.getCause()); 13401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(listener.isEmpty()); 13411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 13421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 13431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testSegmentRemove() { 13441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> map = makeLocalCache(createCacheBuilder().concurrencyLevel(1)); 13451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Segment<Object, Object> segment = map.segments[0]; 13461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 13471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object key = new Object(); 13481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int hash = map.hash(key); 13491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object oldValue = new Object(); 13501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert AtomicReferenceArray<ReferenceEntry<Object, Object>> table = segment.table; 13511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int index = hash & (table.length() - 1); 13521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 13531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert DummyEntry<Object, Object> entry = DummyEntry.create(key, hash, null); 13547dd252788645e940eada959bdde927426e2531c9Paul Duffin DummyValueReference<Object, Object> oldValueRef = DummyValueReference.create(oldValue); 13551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert entry.setValueReference(oldValueRef); 13561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 13571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // no entry 13581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(0, segment.count); 13591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNull(segment.remove(key, hash)); 13601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(0, segment.count); 13611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 13621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // same key 13631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert table.set(index, entry); 13641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert segment.count++; 13651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, segment.count); 13661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(oldValue, segment.get(key, hash)); 13671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(oldValue, segment.remove(key, hash)); 13681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(0, segment.count); 13691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNull(segment.get(key, hash)); 13701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 13711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // cleared 13721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert table.set(index, entry); 13731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert segment.count++; 13741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, segment.count); 13751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(oldValue, segment.get(key, hash)); 13761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert oldValueRef.clear(); 13771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNull(segment.remove(key, hash)); 13781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(0, segment.count); 13791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNull(segment.get(key, hash)); 13801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 13811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 13821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testSegmentRemoveValue() { 13831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> map = makeLocalCache(createCacheBuilder().concurrencyLevel(1)); 13841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Segment<Object, Object> segment = map.segments[0]; 13851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 13861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object key = new Object(); 13871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int hash = map.hash(key); 13881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object oldValue = new Object(); 13891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object newValue = new Object(); 13901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert AtomicReferenceArray<ReferenceEntry<Object, Object>> table = segment.table; 13911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int index = hash & (table.length() - 1); 13921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 13931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert DummyEntry<Object, Object> entry = DummyEntry.create(key, hash, null); 13947dd252788645e940eada959bdde927426e2531c9Paul Duffin DummyValueReference<Object, Object> oldValueRef = DummyValueReference.create(oldValue); 13951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert entry.setValueReference(oldValueRef); 13961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 13971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // no entry 13981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(0, segment.count); 13991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNull(segment.remove(key, hash)); 14001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(0, segment.count); 14011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 14021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // same value 14031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert table.set(index, entry); 14041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert segment.count++; 14051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, segment.count); 14061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(oldValue, segment.get(key, hash)); 14071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(segment.remove(key, hash, oldValue)); 14081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(0, segment.count); 14091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNull(segment.get(key, hash)); 14101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 14111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // different value 14121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert table.set(index, entry); 14131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert segment.count++; 14141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, segment.count); 14151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(oldValue, segment.get(key, hash)); 14161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(segment.remove(key, hash, newValue)); 14171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, segment.count); 14181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(oldValue, segment.get(key, hash)); 14191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 14201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // cleared 14211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(oldValue, segment.get(key, hash)); 14221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert oldValueRef.clear(); 14231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(segment.remove(key, hash, oldValue)); 14241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(0, segment.count); 14251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNull(segment.get(key, hash)); 14261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 14271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 14281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testExpand() { 14291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> map = 14301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert makeLocalCache(createCacheBuilder().concurrencyLevel(1).initialCapacity(1)); 14311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Segment<Object, Object> segment = map.segments[0]; 14321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, segment.table.length()); 14331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 14341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // manually add elements to avoid expansion 14351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int originalCount = 1024; 14361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ReferenceEntry<Object, Object> entry = null; 14371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int i = 0; i < originalCount; i++) { 14381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object key = new Object(); 14391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object value = new Object(); 14401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int hash = map.hash(key); 14411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // chain all entries together as we only have a single bucket 14421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert entry = map.newEntry(key, hash, entry); 14431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ValueReference<Object, Object> valueRef = map.newValueReference(entry, value, 1); 14441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert entry.setValueReference(valueRef); 14451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 14461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert segment.table.set(0, entry); 14471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert segment.count = originalCount; 14481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ImmutableMap<Object, Object> originalMap = ImmutableMap.copyOf(map); 14491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(originalCount, originalMap.size()); 14501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(originalMap, map); 14511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 14521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int i = 1; i <= originalCount * 2; i *= 2) { 14531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (i > 1) { 14541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert segment.expand(); 14551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 14561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(i, segment.table.length()); 14571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(originalCount, countLiveEntries(map, 0)); 14581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(originalCount, segment.count); 14591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(originalMap, map); 14601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 14611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 14621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 14637dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testGetCausesExpansion() throws ExecutionException { 14647dd252788645e940eada959bdde927426e2531c9Paul Duffin for (int count = 1; count <= 100; count++) { 14657dd252788645e940eada959bdde927426e2531c9Paul Duffin LocalCache<Object, Object> map = 14667dd252788645e940eada959bdde927426e2531c9Paul Duffin makeLocalCache(createCacheBuilder().concurrencyLevel(1).initialCapacity(1)); 14677dd252788645e940eada959bdde927426e2531c9Paul Duffin Segment<Object, Object> segment = map.segments[0]; 14687dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals(1, segment.table.length()); 14697dd252788645e940eada959bdde927426e2531c9Paul Duffin 14707dd252788645e940eada959bdde927426e2531c9Paul Duffin for (int i = 0; i < count; i++) { 14717dd252788645e940eada959bdde927426e2531c9Paul Duffin Object key = new Object(); 14727dd252788645e940eada959bdde927426e2531c9Paul Duffin final Object value = new Object(); 14737dd252788645e940eada959bdde927426e2531c9Paul Duffin segment.get(key, key.hashCode(), new CacheLoader<Object, Object>() { 14747dd252788645e940eada959bdde927426e2531c9Paul Duffin @Override 14757dd252788645e940eada959bdde927426e2531c9Paul Duffin public Object load(Object key) { 14767dd252788645e940eada959bdde927426e2531c9Paul Duffin return value; 14777dd252788645e940eada959bdde927426e2531c9Paul Duffin } 14787dd252788645e940eada959bdde927426e2531c9Paul Duffin }); 14797dd252788645e940eada959bdde927426e2531c9Paul Duffin } 14807dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals(count, segment.count); 14817dd252788645e940eada959bdde927426e2531c9Paul Duffin assertTrue(count <= segment.threshold); 14827dd252788645e940eada959bdde927426e2531c9Paul Duffin assertTrue(count <= (segment.table.length() * 3 / 4)); 14837dd252788645e940eada959bdde927426e2531c9Paul Duffin assertTrue(count > (segment.table.length() * 3 / 8)); 14847dd252788645e940eada959bdde927426e2531c9Paul Duffin } 14857dd252788645e940eada959bdde927426e2531c9Paul Duffin } 14867dd252788645e940eada959bdde927426e2531c9Paul Duffin 14877dd252788645e940eada959bdde927426e2531c9Paul Duffin public void testPutCausesExpansion() { 14887dd252788645e940eada959bdde927426e2531c9Paul Duffin for (int count = 1; count <= 100; count++) { 14897dd252788645e940eada959bdde927426e2531c9Paul Duffin LocalCache<Object, Object> map = 14907dd252788645e940eada959bdde927426e2531c9Paul Duffin makeLocalCache(createCacheBuilder().concurrencyLevel(1).initialCapacity(1)); 14917dd252788645e940eada959bdde927426e2531c9Paul Duffin Segment<Object, Object> segment = map.segments[0]; 14927dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals(1, segment.table.length()); 14937dd252788645e940eada959bdde927426e2531c9Paul Duffin 14947dd252788645e940eada959bdde927426e2531c9Paul Duffin for (int i = 0; i < count; i++) { 14957dd252788645e940eada959bdde927426e2531c9Paul Duffin Object key = new Object(); 14967dd252788645e940eada959bdde927426e2531c9Paul Duffin Object value = new Object(); 14977dd252788645e940eada959bdde927426e2531c9Paul Duffin segment.put(key, key.hashCode(), value, true); 14987dd252788645e940eada959bdde927426e2531c9Paul Duffin } 14997dd252788645e940eada959bdde927426e2531c9Paul Duffin assertEquals(count, segment.count); 15007dd252788645e940eada959bdde927426e2531c9Paul Duffin assertTrue(count <= segment.threshold); 15017dd252788645e940eada959bdde927426e2531c9Paul Duffin assertTrue(count <= (segment.table.length() * 3 / 4)); 15027dd252788645e940eada959bdde927426e2531c9Paul Duffin assertTrue(count > (segment.table.length() * 3 / 8)); 15037dd252788645e940eada959bdde927426e2531c9Paul Duffin } 15047dd252788645e940eada959bdde927426e2531c9Paul Duffin } 15057dd252788645e940eada959bdde927426e2531c9Paul Duffin 15061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testReclaimKey() { 15071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CountingRemovalListener<Object, Object> listener = countingRemovalListener(); 15081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> map = makeLocalCache(createCacheBuilder() 15091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .concurrencyLevel(1) 15101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .initialCapacity(1) 15111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .maximumSize(SMALL_MAX_SIZE) 15121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .expireAfterWrite(99999, SECONDS) 15131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .removalListener(listener)); 15141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Segment<Object, Object> segment = map.segments[0]; 15151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert AtomicReferenceArray<ReferenceEntry<Object, Object>> table = segment.table; 15161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, table.length()); 15171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // create 3 objects and chain them together 15191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object keyOne = new Object(); 15201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object valueOne = new Object(); 15211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int hashOne = map.hash(keyOne); 15221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert DummyEntry<Object, Object> entryOne = createDummyEntry(keyOne, hashOne, valueOne, null); 15231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object keyTwo = new Object(); 15241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object valueTwo = new Object(); 15251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int hashTwo = map.hash(keyTwo); 15261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert DummyEntry<Object, Object> entryTwo = createDummyEntry(keyTwo, hashTwo, valueTwo, entryOne); 15271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object keyThree = new Object(); 15281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object valueThree = new Object(); 15291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int hashThree = map.hash(keyThree); 15301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert DummyEntry<Object, Object> entryThree = 15311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert createDummyEntry(keyThree, hashThree, valueThree, entryTwo); 15321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // absent 15341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(0, listener.getCount()); 15351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(segment.reclaimKey(entryOne, hashOne)); 15361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(0, listener.getCount()); 15371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert table.set(0, entryOne); 15381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(segment.reclaimKey(entryTwo, hashTwo)); 15391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(0, listener.getCount()); 15401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert table.set(0, entryTwo); 15411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(segment.reclaimKey(entryThree, hashThree)); 15421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(0, listener.getCount()); 15431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // present 15451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert table.set(0, entryOne); 15461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert segment.count = 1; 15471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(segment.reclaimKey(entryOne, hashOne)); 15481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, listener.getCount()); 15491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(keyOne, listener.getLastEvictedKey()); 15501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(valueOne, listener.getLastEvictedValue()); 15511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(map.removalNotificationQueue.isEmpty()); 15521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(segment.accessQueue.contains(entryOne)); 15531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(segment.writeQueue.contains(entryOne)); 15541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(0, segment.count); 15551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNull(table.get(0)); 15561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 15571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testRemoveEntryFromChain() { 15591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> map = makeLocalCache(createCacheBuilder().concurrencyLevel(1)); 15601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Segment<Object, Object> segment = map.segments[0]; 15611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // create 3 objects and chain them together 15631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object keyOne = new Object(); 15641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object valueOne = new Object(); 15651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int hashOne = map.hash(keyOne); 15661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert DummyEntry<Object, Object> entryOne = createDummyEntry(keyOne, hashOne, valueOne, null); 15671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object keyTwo = new Object(); 15681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object valueTwo = new Object(); 15691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int hashTwo = map.hash(keyTwo); 15701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert DummyEntry<Object, Object> entryTwo = createDummyEntry(keyTwo, hashTwo, valueTwo, entryOne); 15711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object keyThree = new Object(); 15721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object valueThree = new Object(); 15731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int hashThree = map.hash(keyThree); 15741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert DummyEntry<Object, Object> entryThree = 15751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert createDummyEntry(keyThree, hashThree, valueThree, entryTwo); 15761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // alone 15781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNull(segment.removeEntryFromChain(entryOne, entryOne)); 15791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // head 15811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(entryOne, segment.removeEntryFromChain(entryTwo, entryTwo)); 15821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // middle 15841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ReferenceEntry<Object, Object> newFirst = segment.removeEntryFromChain(entryThree, entryTwo); 15851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(keyThree, newFirst.getKey()); 15861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(valueThree, newFirst.getValueReference().get()); 15871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(hashThree, newFirst.getHash()); 15881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(entryOne, newFirst.getNext()); 15891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 15901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // tail (remaining entries are copied in reverse order) 15911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert newFirst = segment.removeEntryFromChain(entryThree, entryOne); 15921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(keyTwo, newFirst.getKey()); 15931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(valueTwo, newFirst.getValueReference().get()); 15941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(hashTwo, newFirst.getHash()); 15951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert newFirst = newFirst.getNext(); 15961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(keyThree, newFirst.getKey()); 15971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(valueThree, newFirst.getValueReference().get()); 15981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(hashThree, newFirst.getHash()); 15991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNull(newFirst.getNext()); 16001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 16021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testExpand_cleanup() { 16031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> map = 16041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert makeLocalCache(createCacheBuilder().concurrencyLevel(1).initialCapacity(1)); 16051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Segment<Object, Object> segment = map.segments[0]; 16061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, segment.table.length()); 16071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 16081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // manually add elements to avoid expansion 16091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // 1/3 null keys, 1/3 null values 16101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int originalCount = 1024; 16111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ReferenceEntry<Object, Object> entry = null; 16121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int i = 0; i < originalCount; i++) { 16131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object key = new Object(); 16141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object value = (i % 3 == 0) ? null : new Object(); 16151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int hash = map.hash(key); 16161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (i % 3 == 1) { 16171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert key = null; 16181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // chain all entries together as we only have a single bucket 16201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert entry = DummyEntry.create(key, hash, entry); 16217dd252788645e940eada959bdde927426e2531c9Paul Duffin ValueReference<Object, Object> valueRef = DummyValueReference.create(value); 16221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert entry.setValueReference(valueRef); 16231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert segment.table.set(0, entry); 16251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert segment.count = originalCount; 16261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int liveCount = originalCount / 3; 16271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, segment.table.length()); 16281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(liveCount, countLiveEntries(map, 0)); 16291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ImmutableMap<Object, Object> originalMap = ImmutableMap.copyOf(map); 16301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(liveCount, originalMap.size()); 16311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // can't compare map contents until cleanup occurs 16321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 16331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int i = 1; i <= originalCount * 2; i *= 2) { 16341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (i > 1) { 16351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert segment.expand(); 16361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(i, segment.table.length()); 16381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(liveCount, countLiveEntries(map, 0)); 16391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // expansion cleanup is sloppy, with a goal of avoiding unnecessary copies 16401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(segment.count >= liveCount); 16411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(segment.count <= originalCount); 16421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(originalMap, ImmutableMap.copyOf(map)); 16431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 16461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static <K, V> int countLiveEntries(LocalCache<K, V> map, long now) { 16471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int result = 0; 16481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Segment<K, V> segment : map.segments) { 16491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert AtomicReferenceArray<ReferenceEntry<K, V>> table = segment.table; 16501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int i = 0; i < table.length(); i++) { 16511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (ReferenceEntry<K, V> e = table.get(i); e != null; e = e.getNext()) { 16521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (map.isLive(e, now)) { 16531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert result++; 16541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return result; 16591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 16611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testClear() { 16621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> map = makeLocalCache(createCacheBuilder() 16631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .concurrencyLevel(1) 16641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .initialCapacity(1) 16651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .maximumSize(SMALL_MAX_SIZE) 16661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .expireAfterWrite(99999, SECONDS)); 16671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Segment<Object, Object> segment = map.segments[0]; 16681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert AtomicReferenceArray<ReferenceEntry<Object, Object>> table = segment.table; 16691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, table.length()); 16701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 16711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object key = new Object(); 16721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object value = new Object(); 16731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int hash = map.hash(key); 16741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert DummyEntry<Object, Object> entry = createDummyEntry(key, hash, value, null); 16751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert segment.recordWrite(entry, 1, map.ticker.read()); 16761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert segment.table.set(0, entry); 16771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert segment.readCount.incrementAndGet(); 16781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert segment.count = 1; 16791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert segment.totalWeight = 1; 16801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 16811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(entry, table.get(0)); 16821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(entry, segment.accessQueue.peek()); 16831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(entry, segment.writeQueue.peek()); 16841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 16851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert segment.clear(); 16861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNull(table.get(0)); 16871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(segment.accessQueue.isEmpty()); 16881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(segment.writeQueue.isEmpty()); 16891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(0, segment.readCount.get()); 16901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(0, segment.count); 16911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(0, segment.totalWeight); 16921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 16931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 16941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testClear_notification() { 16951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert QueuingRemovalListener<Object, Object> listener = queuingRemovalListener(); 16961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> map = makeLocalCache(createCacheBuilder() 16971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .concurrencyLevel(1) 16981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .initialCapacity(1) 16991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .maximumSize(SMALL_MAX_SIZE) 17001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .expireAfterWrite(99999, SECONDS) 17011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .removalListener(listener)); 17021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Segment<Object, Object> segment = map.segments[0]; 17031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert AtomicReferenceArray<ReferenceEntry<Object, Object>> table = segment.table; 17041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, table.length()); 17051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 17061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object key = new Object(); 17071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object value = new Object(); 17081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int hash = map.hash(key); 17091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert DummyEntry<Object, Object> entry = createDummyEntry(key, hash, value, null); 17101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert segment.recordWrite(entry, 1, map.ticker.read()); 17111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert segment.table.set(0, entry); 17121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert segment.readCount.incrementAndGet(); 17131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert segment.count = 1; 17141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert segment.totalWeight = 1; 17151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 17161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(entry, table.get(0)); 17171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(entry, segment.accessQueue.peek()); 17181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(entry, segment.writeQueue.peek()); 17191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 17201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert segment.clear(); 17211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNull(table.get(0)); 17221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(segment.accessQueue.isEmpty()); 17231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(segment.writeQueue.isEmpty()); 17241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(0, segment.readCount.get()); 17251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(0, segment.count); 17261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(0, segment.totalWeight); 17271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNotified(listener, key, value, RemovalCause.EXPLICIT); 17281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 17291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 17301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testRemoveEntry() { 17311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> map = makeLocalCache(createCacheBuilder() 17321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .concurrencyLevel(1) 17331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .initialCapacity(1) 17341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .maximumSize(SMALL_MAX_SIZE) 17351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .expireAfterWrite(99999, SECONDS) 17361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .removalListener(countingRemovalListener())); 17371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Segment<Object, Object> segment = map.segments[0]; 17381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert AtomicReferenceArray<ReferenceEntry<Object, Object>> table = segment.table; 17391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, table.length()); 17401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 17411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object key = new Object(); 17421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object value = new Object(); 17431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int hash = map.hash(key); 17441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert DummyEntry<Object, Object> entry = createDummyEntry(key, hash, value, null); 17451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 17461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // remove absent 17471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(segment.removeEntry(entry, hash, RemovalCause.COLLECTED)); 17481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 17491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // remove live 17501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert segment.recordWrite(entry, 1, map.ticker.read()); 17511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert table.set(0, entry); 17521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert segment.count = 1; 17531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(segment.removeEntry(entry, hash, RemovalCause.COLLECTED)); 17541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNotificationEnqueued(map, key, value, hash); 17551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(map.removalNotificationQueue.isEmpty()); 17561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(segment.accessQueue.contains(entry)); 17571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(segment.writeQueue.contains(entry)); 17581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(0, segment.count); 17591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNull(table.get(0)); 17601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 17611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 17621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testReclaimValue() { 17631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CountingRemovalListener<Object, Object> listener = 17641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert countingRemovalListener(); 17651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> map = makeLocalCache(createCacheBuilder() 17661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .concurrencyLevel(1) 17671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .initialCapacity(1) 17681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .maximumSize(SMALL_MAX_SIZE) 17691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .expireAfterWrite(99999, SECONDS) 17701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .removalListener(listener)); 17711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Segment<Object, Object> segment = map.segments[0]; 17721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert AtomicReferenceArray<ReferenceEntry<Object, Object>> table = segment.table; 17731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, table.length()); 17741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 17751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object key = new Object(); 17761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object value = new Object(); 17771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int hash = map.hash(key); 17781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert DummyEntry<Object, Object> entry = DummyEntry.create(key, hash, null); 17797dd252788645e940eada959bdde927426e2531c9Paul Duffin DummyValueReference<Object, Object> valueRef = DummyValueReference.create(value); 17801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert entry.setValueReference(valueRef); 17811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 17821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // reclaim absent 17831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(segment.reclaimValue(key, hash, valueRef)); 17841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 17851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // reclaim live 17861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert segment.recordWrite(entry, 1, map.ticker.read()); 17871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert table.set(0, entry); 17881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert segment.count = 1; 17891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(segment.reclaimValue(key, hash, valueRef)); 17901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, listener.getCount()); 17911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(key, listener.getLastEvictedKey()); 17921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(value, listener.getLastEvictedValue()); 17931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(map.removalNotificationQueue.isEmpty()); 17941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(segment.accessQueue.contains(entry)); 17951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(segment.writeQueue.contains(entry)); 17961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(0, segment.count); 17971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNull(table.get(0)); 17981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 17991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // reclaim wrong value reference 18001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert table.set(0, entry); 18017dd252788645e940eada959bdde927426e2531c9Paul Duffin DummyValueReference<Object, Object> otherValueRef = DummyValueReference.create(value); 18021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert entry.setValueReference(otherValueRef); 18031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(segment.reclaimValue(key, hash, valueRef)); 18041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, listener.getCount()); 18051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(segment.reclaimValue(key, hash, otherValueRef)); 18061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(2, listener.getCount()); 18071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(key, listener.getLastEvictedKey()); 18081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(value, listener.getLastEvictedValue()); 18091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 18101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 18111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testRemoveComputingValue() { 18121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> map = makeLocalCache(createCacheBuilder() 18131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .concurrencyLevel(1) 18141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .initialCapacity(1) 18151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .maximumSize(SMALL_MAX_SIZE) 18161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .expireAfterWrite(99999, SECONDS) 18171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .removalListener(countingRemovalListener())); 18181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Segment<Object, Object> segment = map.segments[0]; 18191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert AtomicReferenceArray<ReferenceEntry<Object, Object>> table = segment.table; 18201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, table.length()); 18211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 18221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object key = new Object(); 18231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int hash = map.hash(key); 18241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert DummyEntry<Object, Object> entry = DummyEntry.create(key, hash, null); 18251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LoadingValueReference<Object, Object> valueRef = new LoadingValueReference<Object, Object>(); 18261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert entry.setValueReference(valueRef); 18271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 18281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // absent 18291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(segment.removeLoadingValue(key, hash, valueRef)); 18301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 18311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // live 18321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert table.set(0, entry); 18331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // don't increment count; this is used during computation 18341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(segment.removeLoadingValue(key, hash, valueRef)); 18351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // no notification sent with removeLoadingValue 18361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(map.removalNotificationQueue.isEmpty()); 18371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(0, segment.count); 18381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNull(table.get(0)); 18391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 18401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // active 18411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object value = new Object(); 18427dd252788645e940eada959bdde927426e2531c9Paul Duffin DummyValueReference<Object, Object> previousRef = DummyValueReference.create(value); 18431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert valueRef = new LoadingValueReference<Object, Object>(previousRef); 18441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert entry.setValueReference(valueRef); 18451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert table.set(0, entry); 18461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert segment.count = 1; 18471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(segment.removeLoadingValue(key, hash, valueRef)); 18481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(entry, table.get(0)); 18491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(value, segment.get(key, hash)); 18501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 18511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // wrong value reference 18521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert table.set(0, entry); 18537dd252788645e940eada959bdde927426e2531c9Paul Duffin DummyValueReference<Object, Object> otherValueRef = DummyValueReference.create(value); 18541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert entry.setValueReference(otherValueRef); 18551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(segment.removeLoadingValue(key, hash, valueRef)); 18561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert entry.setValueReference(valueRef); 18571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(segment.removeLoadingValue(key, hash, valueRef)); 18581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 18591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 18601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static <K, V> void assertNotificationEnqueued( 18611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<K, V> map, K key, V value, int hash) { 18621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert RemovalNotification<K, V> notification = map.removalNotificationQueue.poll(); 18631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(key, notification.getKey()); 18641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(value, notification.getValue()); 18651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 18661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 18671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // Segment eviction tests 18681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 18691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testDrainRecencyQueueOnWrite() { 18701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (CacheBuilder<Object, Object> builder : allEvictingMakers()) { 18711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> map = makeLocalCache(builder.concurrencyLevel(1)); 18721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Segment<Object, Object> segment = map.segments[0]; 18731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 18741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (segment.recencyQueue != DISCARDING_QUEUE) { 18751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object keyOne = new Object(); 18761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object valueOne = new Object(); 18771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object keyTwo = new Object(); 18781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object valueTwo = new Object(); 18791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 18801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map.put(keyOne, valueOne); 18811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(segment.recencyQueue.isEmpty()); 18821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 18831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int i = 0; i < DRAIN_THRESHOLD / 2; i++) { 18841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map.get(keyOne); 18851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 18861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(segment.recencyQueue.isEmpty()); 18871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 18881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map.put(keyTwo, valueTwo); 18891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(segment.recencyQueue.isEmpty()); 18901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 18911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 18921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 18931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 18941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testDrainRecencyQueueOnRead() { 18951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (CacheBuilder<Object, Object> builder : allEvictingMakers()) { 18961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> map = makeLocalCache(builder.concurrencyLevel(1)); 18971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Segment<Object, Object> segment = map.segments[0]; 18981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 18991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (segment.recencyQueue != DISCARDING_QUEUE) { 19001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object keyOne = new Object(); 19011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object valueOne = new Object(); 19021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 19031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // repeated get of the same key 19041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 19051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map.put(keyOne, valueOne); 19061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(segment.recencyQueue.isEmpty()); 19071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 19081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int i = 0; i < DRAIN_THRESHOLD / 2; i++) { 19091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map.get(keyOne); 19101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 19111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(segment.recencyQueue.isEmpty()); 19121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 19131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int i = 0; i < DRAIN_THRESHOLD * 2; i++) { 19141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map.get(keyOne); 19151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(segment.recencyQueue.size() <= DRAIN_THRESHOLD); 19161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 19171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 19181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // get over many different keys 19191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 19201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int i = 0; i < DRAIN_THRESHOLD * 2; i++) { 19211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map.put(new Object(), new Object()); 19221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 19231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(segment.recencyQueue.isEmpty()); 19241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 19251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int i = 0; i < DRAIN_THRESHOLD / 2; i++) { 19261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map.get(keyOne); 19271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 19281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(segment.recencyQueue.isEmpty()); 19291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 19301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Object key : map.keySet()) { 19311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map.get(key); 19321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(segment.recencyQueue.size() <= DRAIN_THRESHOLD); 19331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 19341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 19351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 19361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 19371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 19381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testRecordRead() { 19391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (CacheBuilder<Object, Object> builder : allEvictingMakers()) { 19401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> map = makeLocalCache(builder.concurrencyLevel(1)); 19411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Segment<Object, Object> segment = map.segments[0]; 19421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert List<ReferenceEntry<Object, Object>> writeOrder = Lists.newLinkedList(); 19431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert List<ReferenceEntry<Object, Object>> readOrder = Lists.newLinkedList(); 19441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int i = 0; i < DRAIN_THRESHOLD * 2; i++) { 19451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object key = new Object(); 19461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int hash = map.hash(key); 19471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object value = new Object(); 19481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 19491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ReferenceEntry<Object, Object> entry = createDummyEntry(key, hash, value, null); 19501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // must recordRead for drainRecencyQueue to believe this entry is live 19511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert segment.recordWrite(entry, 1, map.ticker.read()); 19521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert writeOrder.add(entry); 19531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert readOrder.add(entry); 19541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 19551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 19561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkEvictionQueues(map, segment, readOrder, writeOrder); 19571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkExpirationTimes(map); 19581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 19591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // access some of the elements 19601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Random random = new Random(); 19611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert List<ReferenceEntry<Object, Object>> reads = Lists.newArrayList(); 19621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Iterator<ReferenceEntry<Object, Object>> i = readOrder.iterator(); 19631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert while (i.hasNext()) { 19641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ReferenceEntry<Object, Object> entry = i.next(); 19651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (random.nextBoolean()) { 19661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert segment.recordRead(entry, map.ticker.read()); 19671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert reads.add(entry); 19681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert i.remove(); 19691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 19701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 19711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkAndDrainRecencyQueue(map, segment, reads); 19721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert readOrder.addAll(reads); 19731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 19741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkEvictionQueues(map, segment, readOrder, writeOrder); 19751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkExpirationTimes(map); 19761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 19771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 19781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 19791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testRecordReadOnGet() { 19801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (CacheBuilder<Object, Object> builder : allEvictingMakers()) { 19811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> map = makeLocalCache(builder.concurrencyLevel(1)); 19821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Segment<Object, Object> segment = map.segments[0]; 19831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert List<ReferenceEntry<Object, Object>> writeOrder = Lists.newLinkedList(); 19841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert List<ReferenceEntry<Object, Object>> readOrder = Lists.newLinkedList(); 19851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int i = 0; i < DRAIN_THRESHOLD * 2; i++) { 19861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object key = new Object(); 19871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int hash = map.hash(key); 19881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object value = new Object(); 19891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 19901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map.put(key, value); 19911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ReferenceEntry<Object, Object> entry = segment.getEntry(key, hash); 19921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert writeOrder.add(entry); 19931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert readOrder.add(entry); 19941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 19951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 19961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkEvictionQueues(map, segment, readOrder, writeOrder); 19971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkExpirationTimes(map); 19981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(segment.recencyQueue.isEmpty()); 19991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 20001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // access some of the elements 20011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Random random = new Random(); 20021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert List<ReferenceEntry<Object, Object>> reads = Lists.newArrayList(); 20031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Iterator<ReferenceEntry<Object, Object>> i = readOrder.iterator(); 20041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert while (i.hasNext()) { 20051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ReferenceEntry<Object, Object> entry = i.next(); 20061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (random.nextBoolean()) { 20071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map.get(entry.getKey()); 20081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert reads.add(entry); 20091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert i.remove(); 20101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(segment.recencyQueue.size() <= DRAIN_THRESHOLD); 20111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int undrainedIndex = reads.size() - segment.recencyQueue.size(); 20141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkAndDrainRecencyQueue(map, segment, reads.subList(undrainedIndex, reads.size())); 20151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert readOrder.addAll(reads); 20161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 20171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkEvictionQueues(map, segment, readOrder, writeOrder); 20181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkExpirationTimes(map); 20191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 20221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testRecordWrite() { 20231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (CacheBuilder<Object, Object> builder : allEvictingMakers()) { 20241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> map = makeLocalCache(builder.concurrencyLevel(1)); 20251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Segment<Object, Object> segment = map.segments[0]; 20261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert List<ReferenceEntry<Object, Object>> writeOrder = Lists.newLinkedList(); 20271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int i = 0; i < DRAIN_THRESHOLD * 2; i++) { 20281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object key = new Object(); 20291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int hash = map.hash(key); 20301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object value = new Object(); 20311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 20321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ReferenceEntry<Object, Object> entry = createDummyEntry(key, hash, value, null); 20331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // must recordRead for drainRecencyQueue to believe this entry is live 20341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert segment.recordWrite(entry, 1, map.ticker.read()); 20351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert writeOrder.add(entry); 20361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 20381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkEvictionQueues(map, segment, writeOrder, writeOrder); 20391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkExpirationTimes(map); 20401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 20411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // access some of the elements 20421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Random random = new Random(); 20431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert List<ReferenceEntry<Object, Object>> writes = Lists.newArrayList(); 20441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Iterator<ReferenceEntry<Object, Object>> i = writeOrder.iterator(); 20451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert while (i.hasNext()) { 20461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ReferenceEntry<Object, Object> entry = i.next(); 20471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (random.nextBoolean()) { 20481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert segment.recordWrite(entry, 1, map.ticker.read()); 20491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert writes.add(entry); 20501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert i.remove(); 20511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert writeOrder.addAll(writes); 20541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 20551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkEvictionQueues(map, segment, writeOrder, writeOrder); 20561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkExpirationTimes(map); 20571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 20601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static <K, V> void checkAndDrainRecencyQueue(LocalCache<K, V> map, 20611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Segment<K, V> segment, List<ReferenceEntry<K, V>> reads) { 20621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (map.evictsBySize() || map.expiresAfterAccess()) { 20631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSameEntries(reads, ImmutableList.copyOf(segment.recencyQueue)); 20641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert segment.drainRecencyQueue(); 20661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 20681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static <K, V> void checkEvictionQueues(LocalCache<K, V> map, 20691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Segment<K, V> segment, List<ReferenceEntry<K, V>> readOrder, 20701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert List<ReferenceEntry<K, V>> writeOrder) { 20711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (map.evictsBySize() || map.expiresAfterAccess()) { 20721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSameEntries(readOrder, ImmutableList.copyOf(segment.accessQueue)); 20731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (map.expiresAfterWrite()) { 20751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSameEntries(writeOrder, ImmutableList.copyOf(segment.writeQueue)); 20761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 20791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static <K, V> void assertSameEntries(List<ReferenceEntry<K, V>> expectedEntries, 20801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert List<ReferenceEntry<K, V>> actualEntries) { 20811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int size = expectedEntries.size(); 20821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(size, actualEntries.size()); 20831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int i = 0; i < size; i++) { 20840888a09821a98ac0680fad765217302858e70fa4Paul Duffin ReferenceEntry<K, V> expectedEntry = expectedEntries.get(i); 20850888a09821a98ac0680fad765217302858e70fa4Paul Duffin ReferenceEntry<K, V> actualEntry = actualEntries.get(i); 20861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(expectedEntry.getKey(), actualEntry.getKey()); 20871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(expectedEntry.getValueReference().get(), actualEntry.getValueReference().get()); 20881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 20911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static <K, V> void checkExpirationTimes(LocalCache<K, V> map) { 20921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (!map.expires()) { 20931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return; 20941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 20951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 20961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Segment<K, V> segment : map.segments) { 20971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert long lastAccessTime = 0; 20981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert long lastWriteTime = 0; 20991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (ReferenceEntry<K, V> e : segment.recencyQueue) { 21001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert long accessTime = e.getAccessTime(); 21011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(accessTime >= lastAccessTime); 21021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert lastAccessTime = accessTime; 21031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert long writeTime = e.getWriteTime(); 21041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(writeTime >= lastWriteTime); 21051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert lastWriteTime = writeTime; 21061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 21081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert lastAccessTime = 0; 21091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert lastWriteTime = 0; 21101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (ReferenceEntry<K, V> e : segment.accessQueue) { 21111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert long accessTime = e.getAccessTime(); 21121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(accessTime >= lastAccessTime); 21131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert lastAccessTime = accessTime; 21141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (ReferenceEntry<K, V> e : segment.writeQueue) { 21161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert long writeTime = e.getWriteTime(); 21171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(writeTime >= lastWriteTime); 21181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert lastWriteTime = writeTime; 21191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 21231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testExpireAfterWrite() { 21241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert FakeTicker ticker = new FakeTicker(); 21251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> map = makeLocalCache(createCacheBuilder() 21261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .concurrencyLevel(1) 21271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .ticker(ticker) 21287dd252788645e940eada959bdde927426e2531c9Paul Duffin .expireAfterWrite(2, TimeUnit.NANOSECONDS)); 21291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Segment<Object, Object> segment = map.segments[0]; 21301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 21311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object key = new Object(); 21321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object value = new Object(); 21331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map.put(key, value); 21341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ReferenceEntry<Object, Object> entry = map.getEntry(key); 21351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(map.isLive(entry, ticker.read())); 21361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 21371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert segment.writeQueue.add(entry); 21381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(value, map.get(key)); 21391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(entry, segment.writeQueue.peek()); 21401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, segment.writeQueue.size()); 21411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 21421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert segment.recordRead(entry, ticker.read()); 21431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert segment.expireEntries(ticker.read()); 21441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(value, map.get(key)); 21451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(entry, segment.writeQueue.peek()); 21461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, segment.writeQueue.size()); 21471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 21481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ticker.advance(1); 21491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert segment.recordRead(entry, ticker.read()); 21501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert segment.expireEntries(ticker.read()); 21511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(value, map.get(key)); 21521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(entry, segment.writeQueue.peek()); 21531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, segment.writeQueue.size()); 21541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 21551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ticker.advance(1); 21561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNull(map.get(key)); 21571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert segment.expireEntries(ticker.read()); 21581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNull(map.get(key)); 21591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(segment.writeQueue.isEmpty()); 21601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 21611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 21621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testExpireAfterAccess() { 21631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert FakeTicker ticker = new FakeTicker(); 21641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> map = makeLocalCache(createCacheBuilder() 21651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .concurrencyLevel(1) 21661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .ticker(ticker) 21677dd252788645e940eada959bdde927426e2531c9Paul Duffin .expireAfterAccess(2, TimeUnit.NANOSECONDS)); 21681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Segment<Object, Object> segment = map.segments[0]; 21691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 21701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object key = new Object(); 21711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object value = new Object(); 21721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map.put(key, value); 21731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ReferenceEntry<Object, Object> entry = map.getEntry(key); 21741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(map.isLive(entry, ticker.read())); 21751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 21761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert segment.accessQueue.add(entry); 21771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(value, map.get(key)); 21781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(entry, segment.accessQueue.peek()); 21791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, segment.accessQueue.size()); 21801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 21811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert segment.recordRead(entry, ticker.read()); 21821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert segment.expireEntries(ticker.read()); 21831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(map.containsKey(key)); 21841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(entry, segment.accessQueue.peek()); 21851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, segment.accessQueue.size()); 21861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 21871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ticker.advance(1); 21881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert segment.recordRead(entry, ticker.read()); 21891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert segment.expireEntries(ticker.read()); 21901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(map.containsKey(key)); 21911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(entry, segment.accessQueue.peek()); 21921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, segment.accessQueue.size()); 21931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 21941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ticker.advance(1); 21951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert segment.recordRead(entry, ticker.read()); 21961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert segment.expireEntries(ticker.read()); 21971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(map.containsKey(key)); 21981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(entry, segment.accessQueue.peek()); 21991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, segment.accessQueue.size()); 22001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 22011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ticker.advance(1); 22021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert segment.expireEntries(ticker.read()); 22031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(map.containsKey(key)); 22041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertSame(entry, segment.accessQueue.peek()); 22051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, segment.accessQueue.size()); 22061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 22071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ticker.advance(1); 22081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(map.containsKey(key)); 22091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNull(map.get(key)); 22101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert segment.expireEntries(ticker.read()); 22111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(map.containsKey(key)); 22121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNull(map.get(key)); 22131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(segment.accessQueue.isEmpty()); 22141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 22151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 22161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testEvictEntries() { 22171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int maxSize = 10; 22181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> map = 22191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert makeLocalCache(createCacheBuilder().concurrencyLevel(1).maximumSize(maxSize)); 22201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Segment<Object, Object> segment = map.segments[0]; 22211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 22221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // manually add elements to avoid eviction 22231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int originalCount = 1024; 22241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ReferenceEntry<Object, Object> entry = null; 22251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LinkedHashMap<Object, Object> originalMap = Maps.newLinkedHashMap(); 22261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int i = 0; i < originalCount; i++) { 22271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object key = new Object(); 22281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object value = new Object(); 22291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert AtomicReferenceArray<ReferenceEntry<Object, Object>> table = segment.table; 22301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int hash = map.hash(key); 22311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int index = hash & (table.length() - 1); 22321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ReferenceEntry<Object, Object> first = table.get(index); 22331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert entry = map.newEntry(key, hash, first); 22341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ValueReference<Object, Object> valueRef = map.newValueReference(entry, value, 1); 22351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert entry.setValueReference(valueRef); 22361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert segment.recordWrite(entry, 1, map.ticker.read()); 22371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert table.set(index, entry); 22381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert originalMap.put(key, value); 22391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 22401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert segment.count = originalCount; 22411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert segment.totalWeight = originalCount; 22421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(originalCount, map.size()); 22431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(originalMap, map); 22441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 22451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Iterator<Object> it = originalMap.keySet().iterator(); 22461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int i = 0; i < originalCount - maxSize; i++) { 22471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert it.next(); 22481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert it.remove(); 22491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 22501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert segment.evictEntries(); 22511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(maxSize, map.size()); 22521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(originalMap, map); 22531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 22541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 22551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // reference queues 22561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 22571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testDrainKeyReferenceQueueOnWrite() { 22581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (CacheBuilder<Object, Object> builder : allKeyValueStrengthMakers()) { 22591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> map = 22601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert makeLocalCache(builder.concurrencyLevel(1)); 22611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (map.usesKeyReferences()) { 22621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Segment<Object, Object> segment = map.segments[0]; 22631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 22641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object keyOne = new Object(); 22651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int hashOne = map.hash(keyOne); 22661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object valueOne = new Object(); 22671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object keyTwo = new Object(); 22681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object valueTwo = new Object(); 22691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 22701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map.put(keyOne, valueOne); 22711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ReferenceEntry<Object, Object> entry = segment.getEntry(keyOne, hashOne); 22721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 22731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @SuppressWarnings("unchecked") 22741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Reference<Object> reference = (Reference) entry; 22751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert reference.enqueue(); 22761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 22771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map.put(keyTwo, valueTwo); 22781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(map.containsKey(keyOne)); 22791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(map.containsValue(valueOne)); 22801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNull(map.get(keyOne)); 22811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, map.size()); 22821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNull(segment.keyReferenceQueue.poll()); 22831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 22841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 22851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 22861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 22871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testDrainValueReferenceQueueOnWrite() { 22881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (CacheBuilder<Object, Object> builder : allKeyValueStrengthMakers()) { 22891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> map = 22901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert makeLocalCache(builder.concurrencyLevel(1)); 22911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (map.usesValueReferences()) { 22921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Segment<Object, Object> segment = map.segments[0]; 22931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 22941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object keyOne = new Object(); 22951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int hashOne = map.hash(keyOne); 22961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object valueOne = new Object(); 22971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object keyTwo = new Object(); 22981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object valueTwo = new Object(); 22991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 23001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map.put(keyOne, valueOne); 23011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ReferenceEntry<Object, Object> entry = segment.getEntry(keyOne, hashOne); 23021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ValueReference<Object, Object> valueReference = entry.getValueReference(); 23031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 23041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @SuppressWarnings("unchecked") 23051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Reference<Object> reference = (Reference) valueReference; 23061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert reference.enqueue(); 23071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 23081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map.put(keyTwo, valueTwo); 23091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(map.containsKey(keyOne)); 23101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(map.containsValue(valueOne)); 23111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNull(map.get(keyOne)); 23121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, map.size()); 23131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNull(segment.valueReferenceQueue.poll()); 23141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 23151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 23161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 23171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 23181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testDrainKeyReferenceQueueOnRead() { 23191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (CacheBuilder<Object, Object> builder : allKeyValueStrengthMakers()) { 23201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> map = 23211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert makeLocalCache(builder.concurrencyLevel(1)); 23221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (map.usesKeyReferences()) { 23231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Segment<Object, Object> segment = map.segments[0]; 23241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 23251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object keyOne = new Object(); 23261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int hashOne = map.hash(keyOne); 23271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object valueOne = new Object(); 23281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object keyTwo = new Object(); 23291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 23301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map.put(keyOne, valueOne); 23311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ReferenceEntry<Object, Object> entry = segment.getEntry(keyOne, hashOne); 23321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 23331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @SuppressWarnings("unchecked") 23341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Reference<Object> reference = (Reference) entry; 23351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert reference.enqueue(); 23361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 23371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int i = 0; i < SMALL_MAX_SIZE; i++) { 23381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map.get(keyTwo); 23391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 23401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(map.containsKey(keyOne)); 23411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(map.containsValue(valueOne)); 23421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNull(map.get(keyOne)); 23431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(0, map.size()); 23441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNull(segment.keyReferenceQueue.poll()); 23451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 23461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 23471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 23481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 23491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testDrainValueReferenceQueueOnRead() { 23501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (CacheBuilder<Object, Object> builder : allKeyValueStrengthMakers()) { 23511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> map = 23521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert makeLocalCache(builder.concurrencyLevel(1)); 23531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (map.usesValueReferences()) { 23541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Segment<Object, Object> segment = map.segments[0]; 23551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 23561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object keyOne = new Object(); 23571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int hashOne = map.hash(keyOne); 23581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object valueOne = new Object(); 23591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Object keyTwo = new Object(); 23601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 23611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map.put(keyOne, valueOne); 23621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ReferenceEntry<Object, Object> entry = segment.getEntry(keyOne, hashOne); 23631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ValueReference<Object, Object> valueReference = entry.getValueReference(); 23641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 23651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @SuppressWarnings("unchecked") 23661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Reference<Object> reference = (Reference) valueReference; 23671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert reference.enqueue(); 23681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 23691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int i = 0; i < SMALL_MAX_SIZE; i++) { 23701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert map.get(keyTwo); 23711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 23721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(map.containsKey(keyOne)); 23731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(map.containsValue(valueOne)); 23741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNull(map.get(keyOne)); 23751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(0, map.size()); 23761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertNull(segment.valueReferenceQueue.poll()); 23771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 23781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 23791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 23801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 23811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testNullParameters() throws Exception { 23821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert NullPointerTester tester = new NullPointerTester(); 23831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert tester.testAllPublicInstanceMethods(makeLocalCache(createCacheBuilder())); 23841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CacheLoader<Object, Object> loader = identityLoader(); 23851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert tester.testAllPublicInstanceMethods(makeLocalCache(createCacheBuilder())); 23861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 23871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 23881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testSerializationProxyLoading() { 23891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CacheLoader<Object, Object> loader = new SerializableCacheLoader(); 23901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert RemovalListener<Object, Object> listener = new SerializableRemovalListener<Object, Object>(); 23911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert SerializableWeigher<Object, Object> weigher = new SerializableWeigher<Object, Object>(); 23921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Ticker ticker = new SerializableTicker(); 23931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @SuppressWarnings("unchecked") // createMock 23941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalLoadingCache<Object, Object> one = (LocalLoadingCache) CacheBuilder.newBuilder() 23951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .weakKeys() 23961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .softValues() 23971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .expireAfterAccess(123, SECONDS) 23987dd252788645e940eada959bdde927426e2531c9Paul Duffin .expireAfterWrite(60 * 456, SECONDS) // 456 minutes 23991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .maximumWeight(789) 24001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .weigher(weigher) 24011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .concurrencyLevel(12) 24021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .removalListener(listener) 24031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .ticker(ticker) 24041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .build(loader); 24051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // add a non-serializable entry 24061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert one.getUnchecked(new Object()); 24071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, one.size()); 24081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(one.asMap().isEmpty()); 24091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalLoadingCache<Object, Object> two = SerializableTester.reserialize(one); 24101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(0, two.size()); 24111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(two.asMap().isEmpty()); 24121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 24131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> localCacheOne = one.localCache; 24141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> localCacheTwo = two.localCache; 24151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 24161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(localCacheOne.keyStrength, localCacheTwo.keyStrength); 24171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(localCacheOne.keyStrength, localCacheTwo.keyStrength); 24181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(localCacheOne.valueEquivalence, localCacheTwo.valueEquivalence); 24191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(localCacheOne.valueEquivalence, localCacheTwo.valueEquivalence); 24201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(localCacheOne.maxWeight, localCacheTwo.maxWeight); 24211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(localCacheOne.weigher, localCacheTwo.weigher); 24221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(localCacheOne.expireAfterAccessNanos, localCacheTwo.expireAfterAccessNanos); 24231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(localCacheOne.expireAfterWriteNanos, localCacheTwo.expireAfterWriteNanos); 24241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(localCacheOne.refreshNanos, localCacheTwo.refreshNanos); 24251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(localCacheOne.removalListener, localCacheTwo.removalListener); 24261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(localCacheOne.ticker, localCacheTwo.ticker); 24271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 24281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // serialize the reconstituted version to be sure we haven't lost the ability to reserialize 24291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalLoadingCache<Object, Object> three = SerializableTester.reserialize(two); 24301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> localCacheThree = three.localCache; 24311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 24321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(localCacheTwo.defaultLoader, localCacheThree.defaultLoader); 24331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(localCacheTwo.keyStrength, localCacheThree.keyStrength); 24341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(localCacheTwo.keyStrength, localCacheThree.keyStrength); 24351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(localCacheTwo.valueEquivalence, localCacheThree.valueEquivalence); 24361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(localCacheTwo.valueEquivalence, localCacheThree.valueEquivalence); 24371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(localCacheTwo.maxWeight, localCacheThree.maxWeight); 24381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(localCacheTwo.weigher, localCacheThree.weigher); 24391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(localCacheTwo.expireAfterAccessNanos, localCacheThree.expireAfterAccessNanos); 24401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(localCacheTwo.expireAfterWriteNanos, localCacheThree.expireAfterWriteNanos); 24411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(localCacheTwo.removalListener, localCacheThree.removalListener); 24421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(localCacheTwo.ticker, localCacheThree.ticker); 24431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 24441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 24451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void testSerializationProxyManual() { 24461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert RemovalListener<Object, Object> listener = new SerializableRemovalListener<Object, Object>(); 24471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert SerializableWeigher<Object, Object> weigher = new SerializableWeigher<Object, Object>(); 24481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Ticker ticker = new SerializableTicker(); 24491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @SuppressWarnings("unchecked") // createMock 24501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalManualCache<Object, Object> one = (LocalManualCache) CacheBuilder.newBuilder() 24511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .weakKeys() 24521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .softValues() 24531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .expireAfterAccess(123, NANOSECONDS) 24541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .maximumWeight(789) 24551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .weigher(weigher) 24561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .concurrencyLevel(12) 24571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .removalListener(listener) 24581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .ticker(ticker) 24591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .build(); 24601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // add a non-serializable entry 24611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert one.put(new Object(), new Object()); 24621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(1, one.size()); 24631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertFalse(one.asMap().isEmpty()); 24641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalManualCache<Object, Object> two = SerializableTester.reserialize(one); 24651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(0, two.size()); 24661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertTrue(two.asMap().isEmpty()); 24671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 24681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> localCacheOne = one.localCache; 24691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> localCacheTwo = two.localCache; 24701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 24711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(localCacheOne.keyStrength, localCacheTwo.keyStrength); 24721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(localCacheOne.keyStrength, localCacheTwo.keyStrength); 24731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(localCacheOne.valueEquivalence, localCacheTwo.valueEquivalence); 24741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(localCacheOne.valueEquivalence, localCacheTwo.valueEquivalence); 24751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(localCacheOne.maxWeight, localCacheTwo.maxWeight); 24761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(localCacheOne.weigher, localCacheTwo.weigher); 24771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(localCacheOne.expireAfterAccessNanos, localCacheTwo.expireAfterAccessNanos); 24781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(localCacheOne.expireAfterWriteNanos, localCacheTwo.expireAfterWriteNanos); 24791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(localCacheOne.removalListener, localCacheTwo.removalListener); 24801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(localCacheOne.ticker, localCacheTwo.ticker); 24811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 24821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // serialize the reconstituted version to be sure we haven't lost the ability to reserialize 24831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalManualCache<Object, Object> three = SerializableTester.reserialize(two); 24841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert LocalCache<Object, Object> localCacheThree = three.localCache; 24851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 24861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(localCacheTwo.keyStrength, localCacheThree.keyStrength); 24871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(localCacheTwo.keyStrength, localCacheThree.keyStrength); 24881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(localCacheTwo.valueEquivalence, localCacheThree.valueEquivalence); 24891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(localCacheTwo.valueEquivalence, localCacheThree.valueEquivalence); 24901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(localCacheTwo.maxWeight, localCacheThree.maxWeight); 24911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(localCacheTwo.weigher, localCacheThree.weigher); 24921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(localCacheTwo.expireAfterAccessNanos, localCacheThree.expireAfterAccessNanos); 24931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(localCacheTwo.expireAfterWriteNanos, localCacheThree.expireAfterWriteNanos); 24941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(localCacheTwo.removalListener, localCacheThree.removalListener); 24951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert assertEquals(localCacheTwo.ticker, localCacheThree.ticker); 24961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 24971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 24981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // utility methods 24991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 25001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 25011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns an iterable containing all combinations of maximumSize, expireAfterAccess/Write, 25021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * weakKeys and weak/softValues. 25031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 25041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @SuppressWarnings("unchecked") // varargs 25051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static Iterable<CacheBuilder<Object, Object>> allEntryTypeMakers() { 25061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert List<CacheBuilder<Object, Object>> result = 25071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert newArrayList(allKeyValueStrengthMakers()); 25081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (CacheBuilder<Object, Object> builder : allKeyValueStrengthMakers()) { 25091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert result.add(builder.maximumSize(SMALL_MAX_SIZE)); 25101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 25111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (CacheBuilder<Object, Object> builder : allKeyValueStrengthMakers()) { 25121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert result.add(builder.expireAfterAccess(99999, SECONDS)); 25131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 25141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (CacheBuilder<Object, Object> builder : allKeyValueStrengthMakers()) { 25151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert result.add(builder.expireAfterWrite(99999, SECONDS)); 25161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 25171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (CacheBuilder<Object, Object> builder : allKeyValueStrengthMakers()) { 25181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert result.add(builder.maximumSize(SMALL_MAX_SIZE).expireAfterAccess(99999, SECONDS)); 25191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 25201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (CacheBuilder<Object, Object> builder : allKeyValueStrengthMakers()) { 25211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert result.add(builder.maximumSize(SMALL_MAX_SIZE).expireAfterWrite(99999, SECONDS)); 25221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 25231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return result; 25241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 25251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 25261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 25271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns an iterable containing all combinations of maximumSize and expireAfterAccess/Write. 25281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 25291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @SuppressWarnings("unchecked") // varargs 25301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static Iterable<CacheBuilder<Object, Object>> allEvictingMakers() { 25311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return ImmutableList.of(createCacheBuilder().maximumSize(SMALL_MAX_SIZE), 25321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert createCacheBuilder().expireAfterAccess(99999, SECONDS), 25331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert createCacheBuilder().expireAfterWrite(99999, SECONDS), 25341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert createCacheBuilder() 25351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .maximumSize(SMALL_MAX_SIZE) 25361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .expireAfterAccess(SMALL_MAX_SIZE, TimeUnit.SECONDS), 25371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert createCacheBuilder() 25381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .maximumSize(SMALL_MAX_SIZE) 25391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert .expireAfterWrite(SMALL_MAX_SIZE, TimeUnit.SECONDS)); 25401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 25411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 25421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 25431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns an iterable containing all combinations weakKeys and weak/softValues. 25441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 25451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @SuppressWarnings("unchecked") // varargs 25461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static Iterable<CacheBuilder<Object, Object>> allKeyValueStrengthMakers() { 25471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return ImmutableList.of(createCacheBuilder(), 25481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert createCacheBuilder().weakValues(), 25491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert createCacheBuilder().softValues(), 25501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert createCacheBuilder().weakKeys(), 25511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert createCacheBuilder().weakKeys().weakValues(), 25521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert createCacheBuilder().weakKeys().softValues()); 25531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 25541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 25551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // entries and values 25561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 25571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static <K, V> DummyEntry<K, V> createDummyEntry( 25581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert K key, int hash, V value, ReferenceEntry<K, V> next) { 25591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert DummyEntry<K, V> entry = DummyEntry.create(key, hash, next); 25607dd252788645e940eada959bdde927426e2531c9Paul Duffin DummyValueReference<K, V> valueRef = DummyValueReference.create(value); 25611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert entry.setValueReference(valueRef); 25621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return entry; 25631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 25641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 25651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static class DummyEntry<K, V> implements ReferenceEntry<K, V> { 25661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private K key; 25671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private final int hash; 25681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private final ReferenceEntry<K, V> next; 25691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 25701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public DummyEntry(K key, int hash, ReferenceEntry<K, V> next) { 25711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.key = key; 25721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.hash = hash; 25731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.next = next; 25741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 25751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 25761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <K, V> DummyEntry<K, V> create(K key, int hash, ReferenceEntry<K, V> next) { 25771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new DummyEntry<K, V>(key, hash, next); 25781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 25791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 25801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void clearKey() { 25811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.key = null; 25821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 25831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 25841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private ValueReference<K, V> valueReference = unset(); 25851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 25861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 25871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public ValueReference<K, V> getValueReference() { 25881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return valueReference; 25891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 25901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 25911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 25921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void setValueReference(ValueReference<K, V> valueReference) { 25931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.valueReference = valueReference; 25941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 25951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 25961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 25971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public ReferenceEntry<K, V> getNext() { 25981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return next; 25991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 26001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 26011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 26021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public int getHash() { 26031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return hash; 26041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 26051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 26061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 26071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public K getKey() { 26081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return key; 26091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 26101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 26111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private long accessTime = Long.MAX_VALUE; 26121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 26131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 26141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public long getAccessTime() { 26151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return accessTime; 26161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 26171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 26181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 26191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void setAccessTime(long time) { 26201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.accessTime = time; 26211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 26221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 26231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private ReferenceEntry<K, V> nextAccess = nullEntry(); 26241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 26251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 26261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public ReferenceEntry<K, V> getNextInAccessQueue() { 26271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return nextAccess; 26281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 26291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 26301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 26311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void setNextInAccessQueue(ReferenceEntry<K, V> next) { 26321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.nextAccess = next; 26331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 26341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 26351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private ReferenceEntry<K, V> previousAccess = nullEntry(); 26361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 26371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 26381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public ReferenceEntry<K, V> getPreviousInAccessQueue() { 26391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return previousAccess; 26401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 26411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 26421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 26431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void setPreviousInAccessQueue(ReferenceEntry<K, V> previous) { 26441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.previousAccess = previous; 26451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 26461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 26471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private long writeTime = Long.MAX_VALUE; 26481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 26491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 26501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public long getWriteTime() { 26511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return writeTime; 26521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 26531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 26541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 26551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void setWriteTime(long time) { 26561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.writeTime = time; 26571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 26581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 26591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private ReferenceEntry<K, V> nextWrite = nullEntry(); 26601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 26611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 26621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public ReferenceEntry<K, V> getNextInWriteQueue() { 26631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return nextWrite; 26641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 26651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 26661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 26671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void setNextInWriteQueue(ReferenceEntry<K, V> next) { 26681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.nextWrite = next; 26691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 26701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 26711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private ReferenceEntry<K, V> previousWrite = nullEntry(); 26721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 26731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 26741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public ReferenceEntry<K, V> getPreviousInWriteQueue() { 26751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return previousWrite; 26761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 26771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 26781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 26791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void setPreviousInWriteQueue(ReferenceEntry<K, V> previous) { 26801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.previousWrite = previous; 26811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 26821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 26831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 26841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static class DummyValueReference<K, V> implements ValueReference<K, V> { 26851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private V value; 26861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert boolean loading = false; 26871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 26887dd252788645e940eada959bdde927426e2531c9Paul Duffin public DummyValueReference() { 26891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.loading = true; 26901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 26911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 26927dd252788645e940eada959bdde927426e2531c9Paul Duffin public DummyValueReference(V value) { 26931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.value = value; 26941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 26951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 26967dd252788645e940eada959bdde927426e2531c9Paul Duffin public static <K, V> DummyValueReference<K, V> create(V value) { 26977dd252788645e940eada959bdde927426e2531c9Paul Duffin return new DummyValueReference<K, V>(value); 26981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 26991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 27007dd252788645e940eada959bdde927426e2531c9Paul Duffin public static <K, V> DummyValueReference<K, V> createLoading() { 27017dd252788645e940eada959bdde927426e2531c9Paul Duffin return new DummyValueReference<K, V>(); 27021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 27031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 27041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 27051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public V get() { 27061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return value; 27071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 27081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 27091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 27101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public int getWeight() { 27111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return 1; 27121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 27131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 27141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 27151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public ReferenceEntry<K, V> getEntry() { 27167dd252788645e940eada959bdde927426e2531c9Paul Duffin return null; 27171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 27181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 27191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 27207dd252788645e940eada959bdde927426e2531c9Paul Duffin public ValueReference<K, V> copyFor( 27217dd252788645e940eada959bdde927426e2531c9Paul Duffin ReferenceQueue<V> queue, V value, ReferenceEntry<K, V> entry) { 27227dd252788645e940eada959bdde927426e2531c9Paul Duffin return this; 27231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 27241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 27251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void setLoading(boolean loading) { 27261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.loading = loading; 27271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 27281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 27291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 27301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public boolean isLoading() { 27311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return loading; 27321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 27331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 27341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 27351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public boolean isActive() { 27361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return !loading; 27371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 27381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 27391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 27401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public V waitForValue() { 27411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return get(); 27421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 27431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 27441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 27451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void notifyNewValue(V newValue) {} 27461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 27471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void clear() { 27481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert value = null; 27491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 27501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 27511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 27521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static class SerializableCacheLoader 27531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert extends CacheLoader<Object, Object> implements Serializable { 27541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 27551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public Object load(Object key) { 27561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new Object(); 27571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 27581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 27591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 27601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public int hashCode() { 27611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return 42; 27621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 27631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 27641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 27651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public boolean equals(Object o) { 27661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (o instanceof SerializableCacheLoader); 27671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 27681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 27691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 27701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static class SerializableRemovalListener<K, V> 27711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert implements RemovalListener<K, V>, Serializable { 27721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 27731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void onRemoval(RemovalNotification<K, V> notification) {} 27741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 27751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 27761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public int hashCode() { 27771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return 42; 27781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 27791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 27801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 27811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public boolean equals(Object o) { 27821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (o instanceof SerializableRemovalListener); 27831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 27841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 27851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 27861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static class SerializableTicker extends Ticker implements Serializable { 27871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 27881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public long read() { 27891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return 42; 27901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 27911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 27921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 27931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public int hashCode() { 27941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return 42; 27951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 27961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 27971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 27981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public boolean equals(Object o) { 27991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (o instanceof SerializableTicker); 28001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 28011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 28021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 28031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static class SerializableWeigher<K, V> implements Weigher<K, V>, Serializable { 28041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 28051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public int weigh(K key, V value) { 28061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return 42; 28071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 28081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 28091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 28101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public int hashCode() { 28111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return 42; 28121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 28131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 28141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 28151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public boolean equals(Object o) { 28161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (o instanceof SerializableWeigher); 28171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 28181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 28191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 28201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert} 2821