ReferenceEntry<Object, Object> entry = segment.getEntry(key, hash); writeOrder.add(entry); readOrder.add(entry);
ReferenceEntry<Object, Object> entry = segment.getEntry(key, hash); writeOrder.add(entry); readOrder.add(entry);
static void checkEviction(LocalCache<?, ?> map) { if (map.evictsBySize()) { for (Segment<?, ?> segment : map.segments) { drainRecencyQueue(segment); assertEquals(0, segment.recencyQueue.size()); assertEquals(0, segment.readCount.get()); ReferenceEntry<?, ?> prev = null; for (ReferenceEntry<?, ?> current : segment.accessQueue) { if (prev != null) { assertSame(prev, current.getPreviousInAccessQueue()); assertSame(prev.getNextInAccessQueue(), current); } Object key = current.getKey(); if (key != null) { assertSame(current, segment.getEntry(key, current.getHash())); } prev = current; } } } else { for (Segment<?, ?> segment : map.segments) { assertEquals(0, segment.recencyQueue.size()); } } }
@Nullable ReferenceEntry<K, V> getLiveEntry(Object key, int hash, long now) { ReferenceEntry<K, V> e = getEntry(key, hash); if (e == null) { return null; } else if (map.isExpired(e, now)) { tryExpireEntries(now); return null; } return e; }
if (count != 0) { // read-volatile ReferenceEntry<K, V> e = getEntry(key, hash); if (e != null) { long now = map.ticker.read();
if (count != 0) { // read-volatile ReferenceEntry<K, V> e = getEntry(key, hash); if (e != null) { long now = map.ticker.read();
ReferenceEntry<Object, Object> entry = segment.getEntry(one, hash); ReferenceEntry<Object, Object> newEntry = segment.copyEntry(entry, null); table.set(index, newEntry);
@NullableDecl ReferenceEntry<K, V> getLiveEntry(Object key, int hash, long now) { ReferenceEntry<K, V> e = getEntry(key, hash); if (e == null) { return null; } else if (map.isExpired(e, now)) { tryExpireEntries(now); return null; } return e; }
/** * Returns the internal entry for the specified key. The entry may be loading, expired, or * partially collected. */ ReferenceEntry<K, V> getEntry(@NullableDecl Object key) { // does not impact recency ordering if (key == null) { return null; } int hash = hash(key); return segmentFor(hash).getEntry(key, hash); }
if (count != 0) { // read-volatile ReferenceEntry<K, V> e = getEntry(key, hash); if (e != null) { long now = map.ticker.read();
public void testSegmentPut() { LocalCache<Object, Object> map = makeLocalCache(createCacheBuilder().concurrencyLevel(1).expireAfterAccess(99999, SECONDS)); Segment<Object, Object> segment = map.segments[0]; // TODO(fry): check recency ordering Object key = new Object(); int hash = map.hash(key); Object oldValue = new Object(); Object newValue = new Object(); // no entry assertEquals(0, segment.count); assertNull(segment.put(key, hash, oldValue, false)); assertEquals(1, segment.count); // same key assertSame(oldValue, segment.put(key, hash, newValue, false)); assertEquals(1, segment.count); assertSame(newValue, segment.get(key, hash)); // cleared ReferenceEntry<Object, Object> entry = segment.getEntry(key, hash); DummyValueReference<Object, Object> oldValueRef = DummyValueReference.create(oldValue); entry.setValueReference(oldValueRef); assertSame(oldValue, segment.get(key, hash)); oldValueRef.clear(); assertNull(segment.put(key, hash, newValue, false)); assertEquals(1, segment.count); assertSame(newValue, segment.get(key, hash)); }
public void testSegmentPutIfAbsent() { LocalCache<Object, Object> map = makeLocalCache(createCacheBuilder().concurrencyLevel(1).expireAfterAccess(99999, SECONDS)); Segment<Object, Object> segment = map.segments[0]; // TODO(fry): check recency ordering Object key = new Object(); int hash = map.hash(key); Object oldValue = new Object(); Object newValue = new Object(); // no entry assertEquals(0, segment.count); assertNull(segment.put(key, hash, oldValue, true)); assertEquals(1, segment.count); // same key assertSame(oldValue, segment.put(key, hash, newValue, true)); assertEquals(1, segment.count); assertSame(oldValue, segment.get(key, hash)); // cleared ReferenceEntry<Object, Object> entry = segment.getEntry(key, hash); DummyValueReference<Object, Object> oldValueRef = DummyValueReference.create(oldValue); entry.setValueReference(oldValueRef); assertSame(oldValue, segment.get(key, hash)); oldValueRef.clear(); assertNull(segment.put(key, hash, newValue, true)); assertEquals(1, segment.count); assertSame(newValue, segment.get(key, hash)); }
public void testDrainValueReferenceQueueOnRead() { for (CacheBuilder<Object, Object> builder : allKeyValueStrengthMakers()) { LocalCache<Object, Object> map = makeLocalCache(builder.concurrencyLevel(1)); if (map.usesValueReferences()) { Segment<Object, Object> segment = map.segments[0]; Object keyOne = new Object(); int hashOne = map.hash(keyOne); Object valueOne = new Object(); Object keyTwo = new Object(); map.put(keyOne, valueOne); ReferenceEntry<Object, Object> entry = segment.getEntry(keyOne, hashOne); ValueReference<Object, Object> valueReference = entry.getValueReference(); @SuppressWarnings("unchecked") Reference<Object> reference = (Reference) valueReference; reference.enqueue(); for (int i = 0; i < SMALL_MAX_SIZE; i++) { map.get(keyTwo); } assertFalse(map.containsKey(keyOne)); assertFalse(map.containsValue(valueOne)); assertNull(map.get(keyOne)); assertEquals(0, map.size()); assertNull(segment.valueReferenceQueue.poll()); } } }
public void testDrainKeyReferenceQueueOnRead() { for (CacheBuilder<Object, Object> builder : allKeyValueStrengthMakers()) { LocalCache<Object, Object> map = makeLocalCache(builder.concurrencyLevel(1)); if (map.usesKeyReferences()) { Segment<Object, Object> segment = map.segments[0]; Object keyOne = new Object(); int hashOne = map.hash(keyOne); Object valueOne = new Object(); Object keyTwo = new Object(); map.put(keyOne, valueOne); ReferenceEntry<Object, Object> entry = segment.getEntry(keyOne, hashOne); @SuppressWarnings("unchecked") Reference<Object> reference = (Reference) entry; reference.enqueue(); for (int i = 0; i < SMALL_MAX_SIZE; i++) { map.get(keyTwo); } assertFalse(map.containsKey(keyOne)); assertFalse(map.containsValue(valueOne)); assertNull(map.get(keyOne)); assertEquals(0, map.size()); assertNull(segment.keyReferenceQueue.poll()); } } }
public void testDrainValueReferenceQueueOnWrite() { for (CacheBuilder<Object, Object> builder : allKeyValueStrengthMakers()) { LocalCache<Object, Object> map = makeLocalCache(builder.concurrencyLevel(1)); if (map.usesValueReferences()) { Segment<Object, Object> segment = map.segments[0]; Object keyOne = new Object(); int hashOne = map.hash(keyOne); Object valueOne = new Object(); Object keyTwo = new Object(); Object valueTwo = new Object(); map.put(keyOne, valueOne); ReferenceEntry<Object, Object> entry = segment.getEntry(keyOne, hashOne); ValueReference<Object, Object> valueReference = entry.getValueReference(); @SuppressWarnings("unchecked") Reference<Object> reference = (Reference) valueReference; reference.enqueue(); map.put(keyTwo, valueTwo); assertFalse(map.containsKey(keyOne)); assertFalse(map.containsValue(valueOne)); assertNull(map.get(keyOne)); assertEquals(1, map.size()); assertNull(segment.valueReferenceQueue.poll()); } } }
public void testDrainKeyReferenceQueueOnWrite() { for (CacheBuilder<Object, Object> builder : allKeyValueStrengthMakers()) { LocalCache<Object, Object> map = makeLocalCache(builder.concurrencyLevel(1)); if (map.usesKeyReferences()) { Segment<Object, Object> segment = map.segments[0]; Object keyOne = new Object(); int hashOne = map.hash(keyOne); Object valueOne = new Object(); Object keyTwo = new Object(); Object valueTwo = new Object(); map.put(keyOne, valueOne); ReferenceEntry<Object, Object> entry = segment.getEntry(keyOne, hashOne); @SuppressWarnings("unchecked") Reference<Object> reference = (Reference) entry; reference.enqueue(); map.put(keyTwo, valueTwo); assertFalse(map.containsKey(keyOne)); assertFalse(map.containsValue(valueOne)); assertNull(map.get(keyOne)); assertEquals(1, map.size()); assertNull(segment.keyReferenceQueue.poll()); } } }
public void testRemovalListener_collected() { QueuingRemovalListener<Object, Object> listener = queuingRemovalListener(); LocalCache<Object, Object> map = makeLocalCache( createCacheBuilder().concurrencyLevel(1).softValues().removalListener(listener)); Segment<Object, Object> segment = map.segments[0]; assertTrue(listener.isEmpty()); Object one = new Object(); Object two = new Object(); Object three = new Object(); map.put(one, two); map.put(two, three); assertTrue(listener.isEmpty()); int hash = map.hash(one); ReferenceEntry<Object, Object> entry = segment.getEntry(one, hash); map.reclaimValue(entry.getValueReference()); assertNotified(listener, one, two, RemovalCause.COLLECTED); assertTrue(listener.isEmpty()); }
/** * Returns the internal entry for the specified key. The entry may be loading, expired, or * partially collected. */ ReferenceEntry<K, V> getEntry(@Nullable Object key) { // does not impact recency ordering if (key == null) { return null; } int hash = hash(key); return segmentFor(hash).getEntry(key, hash); }
@Nullable ReferenceEntry<K, V> getLiveEntry(Object key, int hash, long now) { ReferenceEntry<K, V> e = getEntry(key, hash); if (e == null) { return null; } else if (map.isExpired(e, now)) { tryExpireEntries(now); return null; } return e; }