alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (PopulatedCachesTest.java)

This example Java source code file (PopulatedCachesTest.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

cachebuilderfactory, collection, days, entry, equalstester, list, loadingcache, nullpointerexception, object, seconds, set, util, warmup_max, warmup_min, warmup_size

The PopulatedCachesTest.java Java example source code

/*
 * Copyright (C) 2011 The Guava Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */

package com.google.common.cache;

import static com.google.common.cache.CacheTesting.checkEmpty;
import static com.google.common.cache.CacheTesting.checkValidState;
import static com.google.common.cache.TestingCacheLoaders.identityLoader;
import static com.google.common.truth.Truth.assertThat;
import static java.util.concurrent.TimeUnit.DAYS;
import static java.util.concurrent.TimeUnit.SECONDS;

import com.google.common.base.Function;
import com.google.common.cache.CacheBuilderFactory.DurationSpec;
import com.google.common.cache.LocalCache.Strength;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Iterators;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.testing.EqualsTester;

import junit.framework.TestCase;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

/**
 * {@link LoadingCache} tests that deal with caches that actually contain some key-value mappings.
 *
 * @author mike nonemacher
 */

public class PopulatedCachesTest extends TestCase {
  // we use integers as keys; make sure the range covers some values that ARE cached by
  // Integer.valueOf(int), and some that are not cached. (127 is the highest cached value.)
  static final int WARMUP_MIN = 120;
  static final int WARMUP_MAX = 135;
  static final int WARMUP_SIZE = WARMUP_MAX - WARMUP_MIN;

  public void testSize_populated() {
    for (LoadingCache<Object, Object> cache : caches()) {
      // don't let the entries get GCed
      List<Entry warmed = warmUp(cache);
      assertEquals(WARMUP_SIZE, cache.size());
      assertMapSize(cache.asMap(), WARMUP_SIZE);
      checkValidState(cache);
    }
  }

  public void testContainsKey_found() {
    for (LoadingCache<Object, Object> cache : caches()) {
      // don't let the entries get GCed
      List<Entry warmed = warmUp(cache);
      for (int i = WARMUP_MIN; i < WARMUP_MAX; i++) {
        Entry<Object, Object> entry = warmed.get(i - WARMUP_MIN);
        assertTrue(cache.asMap().containsKey(entry.getKey()));
        assertTrue(cache.asMap().containsValue(entry.getValue()));
        // this getUnchecked() call shouldn't be a cache miss; verified below
        assertEquals(entry.getValue(), cache.getUnchecked(entry.getKey()));
      }
      assertEquals(WARMUP_SIZE, cache.stats().missCount());
      checkValidState(cache);
    }
  }

  public void testPut_populated() {
    for (LoadingCache<Object, Object> cache : caches()) {
      // don't let the entries get GCed
      List<Entry warmed = warmUp(cache);
      for (int i = WARMUP_MIN; i < WARMUP_MAX; i++) {
        Entry<Object, Object> entry = warmed.get(i - WARMUP_MIN);
        Object newValue = new Object();
        assertSame(entry.getValue(), cache.asMap().put(entry.getKey(), newValue));
        // don't let the new entry get GCed
        warmed.add(entryOf(entry.getKey(), newValue));
        Object newKey = new Object();
        assertNull(cache.asMap().put(newKey, entry.getValue()));
        // this getUnchecked() call shouldn't be a cache miss; verified below
        assertEquals(newValue, cache.getUnchecked(entry.getKey()));
        assertEquals(entry.getValue(), cache.getUnchecked(newKey));
        // don't let the new entry get GCed
        warmed.add(entryOf(newKey, entry.getValue()));
      }
      assertEquals(WARMUP_SIZE, cache.stats().missCount());
      checkValidState(cache);
    }
  }

  public void testPutIfAbsent_populated() {
    for (LoadingCache<Object, Object> cache : caches()) {
      // don't let the entries get GCed
      List<Entry warmed = warmUp(cache);
      for (int i = WARMUP_MIN; i < WARMUP_MAX; i++) {
        Entry<Object, Object> entry = warmed.get(i - WARMUP_MIN);
        Object newValue = new Object();
        assertSame(entry.getValue(), cache.asMap().putIfAbsent(entry.getKey(), newValue));
        Object newKey = new Object();
        assertNull(cache.asMap().putIfAbsent(newKey, entry.getValue()));
        // this getUnchecked() call shouldn't be a cache miss; verified below
        assertEquals(entry.getValue(), cache.getUnchecked(entry.getKey()));
        assertEquals(entry.getValue(), cache.getUnchecked(newKey));
        // don't let the new entry get GCed
        warmed.add(entryOf(newKey, entry.getValue()));
      }
      assertEquals(WARMUP_SIZE, cache.stats().missCount());
      checkValidState(cache);
    }
  }

  public void testPutAll_populated() {
    for (LoadingCache<Object, Object> cache : caches()) {
      // don't let the entries get GCed
      List<Entry warmed = warmUp(cache);
      Object newKey = new Object();
      Object newValue = new Object();
      cache.asMap().putAll(ImmutableMap.of(newKey, newValue));
      // this getUnchecked() call shouldn't be a cache miss; verified below
      assertEquals(newValue, cache.getUnchecked(newKey));
      assertEquals(WARMUP_SIZE, cache.stats().missCount());
      checkValidState(cache);
    }
  }

  public void testReplace_populated() {
    for (LoadingCache<Object, Object> cache : caches()) {
      // don't let the entries get GCed
      List<Entry warmed = warmUp(cache);
      for (int i = WARMUP_MIN; i < WARMUP_MAX; i++) {
        Entry<Object, Object> entry = warmed.get(i - WARMUP_MIN);
        Object newValue = new Object();
        assertSame(entry.getValue(), cache.asMap().replace(entry.getKey(), newValue));
        assertTrue(cache.asMap().replace(entry.getKey(), newValue, entry.getValue()));
        Object newKey = new Object();
        assertNull(cache.asMap().replace(newKey, entry.getValue()));
        assertFalse(cache.asMap().replace(newKey, entry.getValue(), newValue));
        // this getUnchecked() call shouldn't be a cache miss; verified below
        assertEquals(entry.getValue(), cache.getUnchecked(entry.getKey()));
        assertFalse(cache.asMap().containsKey(newKey));
      }
      assertEquals(WARMUP_SIZE, cache.stats().missCount());
      checkValidState(cache);
    }
  }

  public void testRemove_byKey() {
    for (LoadingCache<Object, Object> cache : caches()) {
      // don't let the entries get GCed
      List<Entry warmed = warmUp(cache);
      for (int i = WARMUP_MIN; i < WARMUP_MAX; i++) {
        Entry<Object, Object> entry = warmed.get(i - WARMUP_MIN);
        Object key = entry.getKey();
        assertEquals(entry.getValue(), cache.asMap().remove(key));
        assertNull(cache.asMap().remove(key));
        assertFalse(cache.asMap().containsKey(key));
      }
      checkEmpty(cache);
    }
  }

  public void testRemove_byKeyAndValue() {
    for (LoadingCache<Object, Object> cache : caches()) {
      // don't let the entries get GCed
      List<Entry warmed = warmUp(cache);
      for (int i = WARMUP_MIN; i < WARMUP_MAX; i++) {
        Object key = warmed.get(i - WARMUP_MIN).getKey();
        Object value = warmed.get(i - WARMUP_MIN).getValue();
        assertFalse(cache.asMap().remove(key, -1));
        assertTrue(cache.asMap().remove(key, value));
        assertFalse(cache.asMap().remove(key, -1));
        assertFalse(cache.asMap().containsKey(key));
      }
      checkEmpty(cache);
    }
  }

  public void testKeySet_populated() {
    for (LoadingCache<Object, Object> cache : caches()) {
      Set<Object> keys = cache.asMap().keySet();
      List<Entry warmed = warmUp(cache);

      Set<Object> expected = Maps.newHashMap(cache.asMap()).keySet();
      assertThat(keys).containsExactlyElementsIn(expected);
      assertThat(keys.toArray()).asList().containsExactlyElementsIn(expected);
      assertThat(keys.toArray(new Object[0])).asList().containsExactlyElementsIn(expected);

      new EqualsTester()
          .addEqualityGroup(cache.asMap().keySet(), keys)
          .addEqualityGroup(ImmutableSet.of())
          .testEquals();
      assertEquals(WARMUP_SIZE, keys.size());
      for (int i = WARMUP_MIN; i < WARMUP_MAX; i++) {
        Object key = warmed.get(i - WARMUP_MIN).getKey();
        assertTrue(keys.contains(key));
        assertTrue(keys.remove(key));
        assertFalse(keys.remove(key));
        assertFalse(keys.contains(key));
      }
      checkEmpty(keys);
      checkEmpty(cache);
    }
  }

  public void testValues_populated() {
    for (LoadingCache<Object, Object> cache : caches()) {
      Collection<Object> values = cache.asMap().values();
      List<Entry warmed = warmUp(cache);

      Collection<Object> expected = Maps.newHashMap(cache.asMap()).values();
      assertThat(values).containsExactlyElementsIn(expected);
      assertThat(values.toArray()).asList().containsExactlyElementsIn(expected);
      assertThat(values.toArray(new Object[0])).asList().containsExactlyElementsIn(expected);

      assertEquals(WARMUP_SIZE, values.size());
      for (int i = WARMUP_MIN; i < WARMUP_MAX; i++) {
        Object value = warmed.get(i - WARMUP_MIN).getValue();
        assertTrue(values.contains(value));
        assertTrue(values.remove(value));
        assertFalse(values.remove(value));
        assertFalse(values.contains(value));
      }
      checkEmpty(values);
      checkEmpty(cache);
    }
  }

  @SuppressWarnings("unchecked") // generic array creation

  public void testEntrySet_populated() {
    for (LoadingCache<Object, Object> cache : caches()) {
      Set<Entry entries = cache.asMap().entrySet();
      List<Entry warmed = warmUp(cache, WARMUP_MIN, WARMUP_MAX);

      Set<?> expected = Maps.newHashMap(cache.asMap()).entrySet();
      assertThat(entries).containsExactlyElementsIn((Collection<Entry) expected);
      assertThat(entries.toArray())
          .asList()
          .containsExactlyElementsIn((Collection<Object>) expected);
      assertThat(entries.toArray(new Entry[0]))
          .asList()
          .containsExactlyElementsIn((Collection<Entry>) expected);

      new EqualsTester()
          .addEqualityGroup(cache.asMap().entrySet(), entries)
          .addEqualityGroup(ImmutableSet.of())
          .testEquals();
      assertEquals(WARMUP_SIZE, entries.size());
      for (int i = WARMUP_MIN; i < WARMUP_MAX; i++) {
        Entry<Object, Object> newEntry = warmed.get(i - WARMUP_MIN);
        assertTrue(entries.contains(newEntry));
        assertTrue(entries.remove(newEntry));
        assertFalse(entries.remove(newEntry));
        assertFalse(entries.contains(newEntry));
      }
      checkEmpty(entries);
      checkEmpty(cache);
    }
  }

  public void testWriteThroughEntry() {
    for (LoadingCache<Object, Object> cache : caches()) {
      cache.getUnchecked(1);
      Entry<Object, Object> entry = Iterables.getOnlyElement(cache.asMap().entrySet());

      cache.invalidate(1);
      assertEquals(0, cache.size());

      entry.setValue(3);
      assertEquals(1, cache.size());
      assertEquals(3, cache.getIfPresent(1));
      checkValidState(cache);

      try {
        entry.setValue(null);
        fail();
      } catch (NullPointerException expected) {
      }
      checkValidState(cache);
    }
  }

  /* ---------------- Local utilities -------------- */

  /**
   * Most of the tests in this class run against every one of these caches.
   */
  private Iterable<LoadingCache caches() {
    // lots of different ways to configure a LoadingCache
    CacheBuilderFactory factory = cacheFactory();
    return Iterables.transform(factory.buildAllPermutations(),
        new Function<CacheBuilder>() {
          @Override public LoadingCache<Object, Object> apply(
              CacheBuilder<Object, Object> builder) {
            return builder.recordStats().build(identityLoader());
          }
        });
  }

  private CacheBuilderFactory cacheFactory() {
    // This is trickier than expected. We plan to put 15 values in each of these (WARMUP_MIN to
    // WARMUP_MAX), but the tests assume no values get evicted. Even with a maximumSize of 100, one
    // of the values gets evicted. With weak keys, we use identity equality, which means using
    // System.identityHashCode, which means the assignment of keys to segments is nondeterministic,
    // so more than (maximumSize / #segments) keys could get assigned to the same segment, which
    // would cause one to be evicted.
    return new CacheBuilderFactory()
        .withKeyStrengths(ImmutableSet.of(Strength.STRONG, Strength.WEAK))
        .withValueStrengths(ImmutableSet.copyOf(Strength.values()))
        .withConcurrencyLevels(ImmutableSet.of(1, 4, 16, 64))
        .withMaximumSizes(ImmutableSet.of(400, 1000))
        .withInitialCapacities(ImmutableSet.of(0, 1, 10, 100, 1000))
        .withExpireAfterWrites(ImmutableSet.of(
            // DurationSpec.of(500, MILLISECONDS),
            DurationSpec.of(1, SECONDS),
            DurationSpec.of(1, DAYS)))
        .withExpireAfterAccesses(ImmutableSet.of(
            // DurationSpec.of(500, MILLISECONDS),
            DurationSpec.of(1, SECONDS),
            DurationSpec.of(1, DAYS)))
        .withRefreshes(ImmutableSet.of(
            // DurationSpec.of(500, MILLISECONDS),
            DurationSpec.of(1, SECONDS),
            DurationSpec.of(1, DAYS)));
  }

  private List<Map.Entry warmUp(LoadingCache cache) {
    return warmUp(cache, WARMUP_MIN, WARMUP_MAX);
  }

  /**
   * Returns the entries that were added to the map, so they won't fall out of a map with weak or
   * soft references until the caller drops the reference to the returned entries.
   */
  private List<Map.Entry warmUp(
      LoadingCache<Object, Object> cache, int minimum, int maximum) {

    List<Map.Entry entries = Lists.newArrayList();
    for (int i = minimum; i < maximum; i++) {
      Object key = i;
      Object value = cache.getUnchecked(key);
      entries.add(entryOf(key, value));
    }
    return entries;
  }

  private Entry<Object, Object> entryOf(Object key, Object value) {
    return Maps.immutableEntry(key, value);
  }

  private void assertMapSize(Map<?, ?> map, int size) {
    assertEquals(size, map.size());
    if (size > 0) {
      assertFalse(map.isEmpty());
    } else {
      assertTrue(map.isEmpty());
    }
    assertCollectionSize(map.keySet(), size);
    assertCollectionSize(map.entrySet(), size);
    assertCollectionSize(map.values(), size);
  }

  private void assertCollectionSize(Collection<?> collection, int size) {
    assertEquals(size, collection.size());
    if (size > 0) {
      assertFalse(collection.isEmpty());
    } else {
      assertTrue(collection.isEmpty());
    }
    assertEquals(size, Iterables.size(collection));
    assertEquals(size, Iterators.size(collection.iterator()));
  }
}

Other Java examples (source code examples)

Here is a short list of links related to this Java PopulatedCachesTest.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.