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

Java example source code file (AbstractCache.java)

This example Java source code file (AbstractCache.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

abstractcache, cachestats, executionexception, gwtcompatible, immutablemap, longaddable, object, override, simplestatscounter, statscounter, suppresswarnings, threading, threads, unsupportedoperationexception, util

The AbstractCache.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 com.google.common.annotations.GwtCompatible;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;

import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ExecutionException;

/**
 * This class provides a skeletal implementation of the {@code Cache} interface to minimize the
 * effort required to implement this interface.
 *
 * <p>To implement a cache, the programmer needs only to extend this class and provide an
 * implementation for the {@link #put} and {@link #getIfPresent} methods. {@link #getAllPresent} is
 * implemented in terms of {@link #getIfPresent}; {@link #putAll} is implemented in terms of
 * {@link #put}, {@link #invalidateAll(Iterable)} is implemented in terms of {@link #invalidate}.
 * The method {@link #cleanUp} is a no-op. All other methods throw an
 * {@link UnsupportedOperationException}.
 *
 * @author Charles Fry
 * @since 10.0
 */
@GwtCompatible
public abstract class AbstractCache<K, V> implements Cache {

  /** Constructor for use by subclasses. */
  protected AbstractCache() {}

  /**
   * @since 11.0
   */
  @Override
  public V get(K key, Callable<? extends V> valueLoader) throws ExecutionException {
    throw new UnsupportedOperationException();
  }

  /**
   * This implementation of {@code getAllPresent} lacks any insight into the internal cache data
   * structure, and is thus forced to return the query keys instead of the cached keys. This is only
   * possible with an unsafe cast which requires {@code keys} to actually be of type {@code K}.
   *
   * {@inheritDoc}
   *
   * @since 11.0
   */
  @Override
  public ImmutableMap<K, V> getAllPresent(Iterable keys) {
    Map<K, V> result = Maps.newLinkedHashMap();
    for (Object key : keys) {
      if (!result.containsKey(key)) {
        @SuppressWarnings("unchecked")
        K castKey = (K) key;
        V value = getIfPresent(key);
        if (value != null) {
          result.put(castKey, value);
        }
      }
    }
    return ImmutableMap.copyOf(result);
  }

  /**
   * @since 11.0
   */
  @Override
  public void put(K key, V value) {
    throw new UnsupportedOperationException();
  }

  /**
   * @since 12.0
   */
  @Override
  public void putAll(Map<? extends K, ? extends V> m) {
    for (Map.Entry<? extends K, ? extends V> entry : m.entrySet()) {
      put(entry.getKey(), entry.getValue());
    }
  }

  @Override
  public void cleanUp() {}

  @Override
  public long size() {
    throw new UnsupportedOperationException();
  }

  @Override
  public void invalidate(Object key) {
    throw new UnsupportedOperationException();
  }

  /**
   * @since 11.0
   */
  @Override
  public void invalidateAll(Iterable<?> keys) {
    for (Object key : keys) {
      invalidate(key);
    }
  }

  @Override
  public void invalidateAll() {
    throw new UnsupportedOperationException();
  }

  @Override
  public CacheStats stats() {
    throw new UnsupportedOperationException();
  }

  @Override
  public ConcurrentMap<K, V> asMap() {
    throw new UnsupportedOperationException();
  }

  /**
   * Accumulates statistics during the operation of a {@link Cache} for presentation by
   * {@link Cache#stats}. This is solely intended for consumption by {@code Cache} implementors.
   *
   * @since 10.0
   */
  public interface StatsCounter {
    /**
     * Records cache hits. This should be called when a cache request returns a cached value.
     *
     * @param count the number of hits to record
     * @since 11.0
     */
    void recordHits(int count);

    /**
     * Records cache misses. This should be called when a cache request returns a value that was not
     * found in the cache. This method should be called by the loading thread, as well as by threads
     * blocking on the load. Multiple concurrent calls to {@link Cache} lookup methods with the same
     * key on an absent value should result in a single call to either {@code recordLoadSuccess} or
     * {@code recordLoadException} and multiple calls to this method, despite all being served by
     * the results of a single load operation.
     *
     * @param count the number of misses to record
     * @since 11.0
     */
    void recordMisses(int count);

    /**
     * Records the successful load of a new entry. This should be called when a cache request causes
     * an entry to be loaded, and the loading completes successfully. In contrast to
     * {@link #recordMisses}, this method should only be called by the loading thread.
     *
     * @param loadTime the number of nanoseconds the cache spent computing or retrieving the new
     *     value
     */
    void recordLoadSuccess(long loadTime);

    /**
     * Records the failed load of a new entry. This should be called when a cache request causes an
     * entry to be loaded, but an exception is thrown while loading the entry. In contrast to
     * {@link #recordMisses}, this method should only be called by the loading thread.
     *
     * @param loadTime the number of nanoseconds the cache spent computing or retrieving the new
     *     value prior to an exception being thrown
     */
    void recordLoadException(long loadTime);

    /**
     * Records the eviction of an entry from the cache. This should only been called when an entry
     * is evicted due to the cache's eviction strategy, and not as a result of manual
     * {@linkplain Cache#invalidate invalidations}.
     */
    void recordEviction();

    /**
     * Returns a snapshot of this counter's values. Note that this may be an inconsistent view, as
     * it may be interleaved with update operations.
     */
    CacheStats snapshot();
  }

  /**
   * A thread-safe {@link StatsCounter} implementation for use by {@link Cache} implementors.
   *
   * @since 10.0
   */
  public static final class SimpleStatsCounter implements StatsCounter {
    private final LongAddable hitCount = LongAddables.create();
    private final LongAddable missCount = LongAddables.create();
    private final LongAddable loadSuccessCount = LongAddables.create();
    private final LongAddable loadExceptionCount = LongAddables.create();
    private final LongAddable totalLoadTime = LongAddables.create();
    private final LongAddable evictionCount = LongAddables.create();

    /**
     * Constructs an instance with all counts initialized to zero.
     */
    public SimpleStatsCounter() {}

    /**
     * @since 11.0
     */
    @Override
    public void recordHits(int count) {
      hitCount.add(count);
    }

    /**
     * @since 11.0
     */
    @Override
    public void recordMisses(int count) {
      missCount.add(count);
    }

    @Override
    public void recordLoadSuccess(long loadTime) {
      loadSuccessCount.increment();
      totalLoadTime.add(loadTime);
    }

    @Override
    public void recordLoadException(long loadTime) {
      loadExceptionCount.increment();
      totalLoadTime.add(loadTime);
    }

    @Override
    public void recordEviction() {
      evictionCount.increment();
    }

    @Override
    public CacheStats snapshot() {
      return new CacheStats(
          hitCount.sum(),
          missCount.sum(),
          loadSuccessCount.sum(),
          loadExceptionCount.sum(),
          totalLoadTime.sum(),
          evictionCount.sum());
    }

    /**
     * Increments all counters by the values in {@code other}.
     */
    public void incrementBy(StatsCounter other) {
      CacheStats otherStats = other.snapshot();
      hitCount.add(otherStats.hitCount());
      missCount.add(otherStats.missCount());
      loadSuccessCount.add(otherStats.loadSuccessCount());
      loadExceptionCount.add(otherStats.loadExceptionCount());
      totalLoadTime.add(otherStats.totalLoadTime());
      evictionCount.add(otherStats.evictionCount());
    }
  }
}

Other Java examples (source code examples)

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

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

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 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.