Search in sources :

Example 6 with ReferenceEntry

use of com.google.common.cache.LocalCache.ReferenceEntry in project guava by google.

the class LocalCacheTest method testRecordWrite.

public void testRecordWrite() {
    for (CacheBuilder<Object, Object> builder : allEvictingMakers()) {
        LocalCache<Object, Object> map = makeLocalCache(builder.concurrencyLevel(1));
        Segment<Object, Object> segment = map.segments[0];
        List<ReferenceEntry<Object, Object>> writeOrder = Lists.newLinkedList();
        for (int i = 0; i < DRAIN_THRESHOLD * 2; i++) {
            Object key = new Object();
            int hash = map.hash(key);
            Object value = new Object();
            ReferenceEntry<Object, Object> entry = createDummyEntry(key, hash, value, null);
            // must recordRead for drainRecencyQueue to believe this entry is live
            segment.recordWrite(entry, 1, map.ticker.read());
            writeOrder.add(entry);
        }
        checkEvictionQueues(map, segment, writeOrder, writeOrder);
        checkExpirationTimes(map);
        // access some of the elements
        Random random = new Random();
        List<ReferenceEntry<Object, Object>> writes = Lists.newArrayList();
        Iterator<ReferenceEntry<Object, Object>> i = writeOrder.iterator();
        while (i.hasNext()) {
            ReferenceEntry<Object, Object> entry = i.next();
            if (random.nextBoolean()) {
                segment.recordWrite(entry, 1, map.ticker.read());
                writes.add(entry);
                i.remove();
            }
        }
        writeOrder.addAll(writes);
        checkEvictionQueues(map, segment, writeOrder, writeOrder);
        checkExpirationTimes(map);
    }
}
Also used : ReferenceEntry(com.google.common.cache.LocalCache.ReferenceEntry) Random(java.util.Random)

Example 7 with ReferenceEntry

use of com.google.common.cache.LocalCache.ReferenceEntry in project guava by hceylan.

the class LocalCacheTest method testCopyEntry_computing.

public void testCopyEntry_computing() {
    final CountDownLatch startSignal = new CountDownLatch(1);
    final CountDownLatch computingSignal = new CountDownLatch(1);
    final CountDownLatch doneSignal = new CountDownLatch(2);
    final Object computedObject = new Object();
    final CacheLoader<Object, Object> loader = new CacheLoader<Object, Object>() {

        @Override
        public Object load(Object key) throws Exception {
            computingSignal.countDown();
            startSignal.await();
            return computedObject;
        }
    };
    QueuingRemovalListener<Object, Object> listener = queuingRemovalListener();
    CacheBuilder<Object, Object> builder = createCacheBuilder().concurrencyLevel(1).removalListener(listener);
    final LocalCache<Object, Object> map = makeLocalCache(builder);
    Segment<Object, Object> segment = map.segments[0];
    AtomicReferenceArray<ReferenceEntry<Object, Object>> table = segment.table;
    assertTrue(listener.isEmpty());
    final Object one = new Object();
    int hash = map.hash(one);
    int index = hash & (table.length() - 1);
    new Thread() {

        @Override
        public void run() {
            try {
                map.get(one, loader);
            } catch (ExecutionException e) {
                throw new RuntimeException(e);
            }
            doneSignal.countDown();
        }
    }.start();
    try {
        computingSignal.await();
    } catch (InterruptedException e) {
        throw new RuntimeException(e);
    }
    new Thread() {

        @Override
        public void run() {
            try {
                map.get(one, loader);
            } catch (ExecutionException e) {
                throw new RuntimeException(e);
            }
            doneSignal.countDown();
        }
    }.start();
    ReferenceEntry<Object, Object> entry = segment.getEntry(one, hash);
    ReferenceEntry<Object, Object> newEntry = segment.copyEntry(entry, null);
    table.set(index, newEntry);
    @SuppressWarnings("unchecked") LoadingValueReference<Object, Object> valueReference = (LoadingValueReference) newEntry.getValueReference();
    assertFalse(valueReference.futureValue.isDone());
    startSignal.countDown();
    try {
        doneSignal.await();
    } catch (InterruptedException e) {
        throw new RuntimeException(e);
    }
    // force notifications
    map.cleanUp();
    assertTrue(listener.isEmpty());
    assertTrue(map.containsKey(one));
    assertEquals(1, map.size());
    assertSame(computedObject, map.get(one));
}
Also used : CountDownLatch(java.util.concurrent.CountDownLatch) ReferenceEntry(com.google.common.cache.LocalCache.ReferenceEntry) LoadingValueReference(com.google.common.cache.LocalCache.LoadingValueReference) ExecutionException(java.util.concurrent.ExecutionException)

Example 8 with ReferenceEntry

use of com.google.common.cache.LocalCache.ReferenceEntry in project guava by hceylan.

the class LocalCacheTest method testRecordReadOnGet.

public void testRecordReadOnGet() {
    for (CacheBuilder<Object, Object> builder : allEvictingMakers()) {
        LocalCache<Object, Object> map = makeLocalCache(builder.concurrencyLevel(1));
        Segment<Object, Object> segment = map.segments[0];
        List<ReferenceEntry<Object, Object>> writeOrder = Lists.newLinkedList();
        List<ReferenceEntry<Object, Object>> readOrder = Lists.newLinkedList();
        for (int i = 0; i < DRAIN_THRESHOLD * 2; i++) {
            Object key = new Object();
            int hash = map.hash(key);
            Object value = new Object();
            map.put(key, value);
            ReferenceEntry<Object, Object> entry = segment.getEntry(key, hash);
            writeOrder.add(entry);
            readOrder.add(entry);
        }
        checkEvictionQueues(map, segment, readOrder, writeOrder);
        checkExpirationTimes(map);
        assertTrue(segment.recencyQueue.isEmpty());
        // access some of the elements
        Random random = new Random();
        List<ReferenceEntry<Object, Object>> reads = Lists.newArrayList();
        Iterator<ReferenceEntry<Object, Object>> i = readOrder.iterator();
        while (i.hasNext()) {
            ReferenceEntry<Object, Object> entry = i.next();
            if (random.nextBoolean()) {
                map.get(entry.getKey());
                reads.add(entry);
                i.remove();
                assertTrue(segment.recencyQueue.size() <= DRAIN_THRESHOLD);
            }
        }
        int undrainedIndex = reads.size() - segment.recencyQueue.size();
        checkAndDrainRecencyQueue(map, segment, reads.subList(undrainedIndex, reads.size()));
        readOrder.addAll(reads);
        checkEvictionQueues(map, segment, readOrder, writeOrder);
        checkExpirationTimes(map);
    }
}
Also used : ReferenceEntry(com.google.common.cache.LocalCache.ReferenceEntry) Random(java.util.Random)

Example 9 with ReferenceEntry

use of com.google.common.cache.LocalCache.ReferenceEntry in project guava by google.

the class LocalCacheTest method testSegmentGetAndContains.

public void testSegmentGetAndContains() {
    FakeTicker ticker = new FakeTicker();
    LocalCache<Object, Object> map = makeLocalCache(createCacheBuilder().concurrencyLevel(1).ticker(ticker).expireAfterAccess(1, TimeUnit.NANOSECONDS));
    Segment<Object, Object> segment = map.segments[0];
    // TODO(fry): check recency ordering
    Object key = new Object();
    int hash = map.hash(key);
    Object value = new Object();
    AtomicReferenceArray<ReferenceEntry<Object, Object>> table = segment.table;
    int index = hash & (table.length() - 1);
    ReferenceEntry<Object, Object> entry = map.newEntry(key, hash, null);
    ValueReference<Object, Object> valueRef = map.newValueReference(entry, value, 1);
    entry.setValueReference(valueRef);
    assertNull(segment.get(key, hash));
    // count == 0
    table.set(index, entry);
    assertNull(segment.get(key, hash));
    assertFalse(segment.containsKey(key, hash));
    assertFalse(segment.containsValue(value));
    // count == 1
    segment.count++;
    assertSame(value, segment.get(key, hash));
    assertTrue(segment.containsKey(key, hash));
    assertTrue(segment.containsValue(value));
    // don't see absent values now that count > 0
    assertNull(segment.get(new Object(), hash));
    // null key
    DummyEntry<Object, Object> nullEntry = DummyEntry.create(null, hash, entry);
    Object nullValue = new Object();
    ValueReference<Object, Object> nullValueRef = map.newValueReference(nullEntry, nullValue, 1);
    nullEntry.setValueReference(nullValueRef);
    table.set(index, nullEntry);
    // skip the null key
    assertSame(value, segment.get(key, hash));
    assertTrue(segment.containsKey(key, hash));
    assertTrue(segment.containsValue(value));
    assertFalse(segment.containsValue(nullValue));
    // hash collision
    DummyEntry<Object, Object> dummy = DummyEntry.create(new Object(), hash, entry);
    Object dummyValue = new Object();
    ValueReference<Object, Object> dummyValueRef = map.newValueReference(dummy, dummyValue, 1);
    dummy.setValueReference(dummyValueRef);
    table.set(index, dummy);
    assertSame(value, segment.get(key, hash));
    assertTrue(segment.containsKey(key, hash));
    assertTrue(segment.containsValue(value));
    assertTrue(segment.containsValue(dummyValue));
    // key collision
    dummy = DummyEntry.create(key, hash, entry);
    dummyValue = new Object();
    dummyValueRef = map.newValueReference(dummy, dummyValue, 1);
    dummy.setValueReference(dummyValueRef);
    table.set(index, dummy);
    // returns the most recent entry
    assertSame(dummyValue, segment.get(key, hash));
    assertTrue(segment.containsKey(key, hash));
    assertTrue(segment.containsValue(value));
    assertTrue(segment.containsValue(dummyValue));
    // expired
    dummy.setAccessTime(ticker.read() - 2);
    assertNull(segment.get(key, hash));
    assertFalse(segment.containsKey(key, hash));
    assertTrue(segment.containsValue(value));
    assertFalse(segment.containsValue(dummyValue));
}
Also used : ReferenceEntry(com.google.common.cache.LocalCache.ReferenceEntry) FakeTicker(com.google.common.testing.FakeTicker)

Example 10 with ReferenceEntry

use of com.google.common.cache.LocalCache.ReferenceEntry in project guava by google.

the class LocalCacheTest method testCopyEntry_computing.

public void testCopyEntry_computing() {
    final CountDownLatch startSignal = new CountDownLatch(1);
    final CountDownLatch computingSignal = new CountDownLatch(1);
    final CountDownLatch doneSignal = new CountDownLatch(2);
    final Object computedObject = new Object();
    final CacheLoader<Object, Object> loader = new CacheLoader<Object, Object>() {

        @Override
        public Object load(Object key) throws Exception {
            computingSignal.countDown();
            startSignal.await();
            return computedObject;
        }
    };
    QueuingRemovalListener<Object, Object> listener = queuingRemovalListener();
    CacheBuilder<Object, Object> builder = createCacheBuilder().concurrencyLevel(1).removalListener(listener);
    final LocalCache<Object, Object> map = makeLocalCache(builder);
    Segment<Object, Object> segment = map.segments[0];
    AtomicReferenceArray<ReferenceEntry<Object, Object>> table = segment.table;
    assertTrue(listener.isEmpty());
    final Object one = new Object();
    int hash = map.hash(one);
    int index = hash & (table.length() - 1);
    new Thread() {

        @Override
        public void run() {
            try {
                map.get(one, loader);
            } catch (ExecutionException e) {
                throw new RuntimeException(e);
            }
            doneSignal.countDown();
        }
    }.start();
    try {
        computingSignal.await();
    } catch (InterruptedException e) {
        throw new RuntimeException(e);
    }
    new Thread() {

        @Override
        public void run() {
            try {
                map.get(one, loader);
            } catch (ExecutionException e) {
                throw new RuntimeException(e);
            }
            doneSignal.countDown();
        }
    }.start();
    ReferenceEntry<Object, Object> entry = segment.getEntry(one, hash);
    ReferenceEntry<Object, Object> newEntry = segment.copyEntry(entry, null);
    table.set(index, newEntry);
    @SuppressWarnings("unchecked") LoadingValueReference<Object, Object> valueReference = (LoadingValueReference) newEntry.getValueReference();
    assertFalse(valueReference.futureValue.isDone());
    startSignal.countDown();
    try {
        doneSignal.await();
    } catch (InterruptedException e) {
        throw new RuntimeException(e);
    }
    // force notifications
    map.cleanUp();
    assertTrue(listener.isEmpty());
    assertTrue(map.containsKey(one));
    assertEquals(1, map.size());
    assertSame(computedObject, map.get(one));
}
Also used : CountDownLatch(java.util.concurrent.CountDownLatch) ReferenceEntry(com.google.common.cache.LocalCache.ReferenceEntry) LoadingValueReference(com.google.common.cache.LocalCache.LoadingValueReference) ExecutionException(java.util.concurrent.ExecutionException)

Aggregations

ReferenceEntry (com.google.common.cache.LocalCache.ReferenceEntry)16 Random (java.util.Random)8 CountingLoader (com.google.common.cache.TestingCacheLoaders.CountingLoader)6 LoadingValueReference (com.google.common.cache.LocalCache.LoadingValueReference)2 FakeTicker (com.google.common.testing.FakeTicker)2 CountDownLatch (java.util.concurrent.CountDownLatch)2 ExecutionException (java.util.concurrent.ExecutionException)2