Coverage Summary for Class: AbstractCache (com.google.common.cache)

Class Method, % Line, %
AbstractCache 0% (0/11) 0% (0/23)
AbstractCache$SimpleStatsCounter 0% (0/9) 0% (0/28)
Total 0% (0/20) 0% (0/51)


1 /* 2  * Copyright (C) 2011 The Guava Authors 3  * 4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5  * in compliance with the License. You may obtain a copy of the License at 6  * 7  * http://www.apache.org/licenses/LICENSE-2.0 8  * 9  * Unless required by applicable law or agreed to in writing, software distributed under the License 10  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11  * or implied. See the License for the specific language governing permissions and limitations under 12  * the License. 13  */ 14  15 package com.google.common.cache; 16  17 import com.google.common.annotations.GwtCompatible; 18 import com.google.common.collect.ImmutableMap; 19 import com.google.common.collect.Maps; 20 import java.util.Map; 21 import java.util.Map.Entry; 22 import java.util.concurrent.Callable; 23 import java.util.concurrent.ConcurrentMap; 24 import java.util.concurrent.ExecutionException; 25  26 /** 27  * This class provides a skeletal implementation of the {@code Cache} interface to minimize the 28  * effort required to implement this interface. 29  * 30  * <p>To implement a cache, the programmer needs only to extend this class and provide an 31  * implementation for the {@link #put} and {@link #getIfPresent} methods. {@link #getAllPresent} is 32  * implemented in terms of {@link #getIfPresent}; {@link #putAll} is implemented in terms of {@link 33  * #put}, {@link #invalidateAll(Iterable)} is implemented in terms of {@link #invalidate}. The 34  * method {@link #cleanUp} is a no-op. All other methods throw an {@link 35  * UnsupportedOperationException}. 36  * 37  * @author Charles Fry 38  * @since 10.0 39  */ 40 @GwtCompatible 41 public abstract class AbstractCache<K, V> implements Cache<K, V> { 42  43  /** Constructor for use by subclasses. */ 44  protected AbstractCache() {} 45  46  /** @since 11.0 */ 47  @Override 48  public V get(K key, Callable<? extends V> valueLoader) throws ExecutionException { 49  throw new UnsupportedOperationException(); 50  } 51  52  /** 53  * {@inheritDoc} 54  * 55  * <p>This implementation of {@code getAllPresent} lacks any insight into the internal cache data 56  * structure, and is thus forced to return the query keys instead of the cached keys. This is only 57  * possible with an unsafe cast which requires {@code keys} to actually be of type {@code K}. 58  * 59  * @since 11.0 60  */ 61  @Override 62  public ImmutableMap<K, V> getAllPresent(Iterable<?> keys) { 63  Map<K, V> result = Maps.newLinkedHashMap(); 64  for (Object key : keys) { 65  if (!result.containsKey(key)) { 66  @SuppressWarnings("unchecked") 67  K castKey = (K) key; 68  V value = getIfPresent(key); 69  if (value != null) { 70  result.put(castKey, value); 71  } 72  } 73  } 74  return ImmutableMap.copyOf(result); 75  } 76  77  /** @since 11.0 */ 78  @Override 79  public void put(K key, V value) { 80  throw new UnsupportedOperationException(); 81  } 82  83  /** @since 12.0 */ 84  @Override 85  public void putAll(Map<? extends K, ? extends V> m) { 86  for (Entry<? extends K, ? extends V> entry : m.entrySet()) { 87  put(entry.getKey(), entry.getValue()); 88  } 89  } 90  91  @Override 92  public void cleanUp() {} 93  94  @Override 95  public long size() { 96  throw new UnsupportedOperationException(); 97  } 98  99  @Override 100  public void invalidate(Object key) { 101  throw new UnsupportedOperationException(); 102  } 103  104  /** @since 11.0 */ 105  @Override 106  public void invalidateAll(Iterable<?> keys) { 107  for (Object key : keys) { 108  invalidate(key); 109  } 110  } 111  112  @Override 113  public void invalidateAll() { 114  throw new UnsupportedOperationException(); 115  } 116  117  @Override 118  public CacheStats stats() { 119  throw new UnsupportedOperationException(); 120  } 121  122  @Override 123  public ConcurrentMap<K, V> asMap() { 124  throw new UnsupportedOperationException(); 125  } 126  127  /** 128  * Accumulates statistics during the operation of a {@link Cache} for presentation by {@link 129  * Cache#stats}. This is solely intended for consumption by {@code Cache} implementors. 130  * 131  * @since 10.0 132  */ 133  public interface StatsCounter { 134  /** 135  * Records cache hits. This should be called when a cache request returns a cached value. 136  * 137  * @param count the number of hits to record 138  * @since 11.0 139  */ 140  void recordHits(int count); 141  142  /** 143  * Records cache misses. This should be called when a cache request returns a value that was not 144  * found in the cache. This method should be called by the loading thread, as well as by threads 145  * blocking on the load. Multiple concurrent calls to {@link Cache} lookup methods with the same 146  * key on an absent value should result in a single call to either {@code recordLoadSuccess} or 147  * {@code recordLoadException} and multiple calls to this method, despite all being served by 148  * the results of a single load operation. 149  * 150  * @param count the number of misses to record 151  * @since 11.0 152  */ 153  void recordMisses(int count); 154  155  /** 156  * Records the successful load of a new entry. This should be called when a cache request causes 157  * an entry to be loaded, and the loading completes successfully. In contrast to {@link 158  * #recordMisses}, this method should only be called by the loading thread. 159  * 160  * @param loadTime the number of nanoseconds the cache spent computing or retrieving the new 161  * value 162  */ 163  @SuppressWarnings("GoodTime") // should accept a java.time.Duration 164  void recordLoadSuccess(long loadTime); 165  166  /** 167  * Records the failed load of a new entry. This should be called when a cache request causes an 168  * entry to be loaded, but an exception is thrown while loading the entry. In contrast to {@link 169  * #recordMisses}, this method should only be called by the loading thread. 170  * 171  * @param loadTime the number of nanoseconds the cache spent computing or retrieving the new 172  * value prior to an exception being thrown 173  */ 174  @SuppressWarnings("GoodTime") // should accept a java.time.Duration 175  void recordLoadException(long loadTime); 176  177  /** 178  * Records the eviction of an entry from the cache. This should only been called when an entry 179  * is evicted due to the cache's eviction strategy, and not as a result of manual {@linkplain 180  * Cache#invalidate invalidations}. 181  */ 182  void recordEviction(); 183  184  /** 185  * Returns a snapshot of this counter's values. Note that this may be an inconsistent view, as 186  * it may be interleaved with update operations. 187  */ 188  CacheStats snapshot(); 189  } 190  191  /** 192  * A thread-safe {@link StatsCounter} implementation for use by {@link Cache} implementors. 193  * 194  * @since 10.0 195  */ 196  public static final class SimpleStatsCounter implements StatsCounter { 197  private final LongAddable hitCount = LongAddables.create(); 198  private final LongAddable missCount = LongAddables.create(); 199  private final LongAddable loadSuccessCount = LongAddables.create(); 200  private final LongAddable loadExceptionCount = LongAddables.create(); 201  private final LongAddable totalLoadTime = LongAddables.create(); 202  private final LongAddable evictionCount = LongAddables.create(); 203  204  /** Constructs an instance with all counts initialized to zero. */ 205  public SimpleStatsCounter() {} 206  207  /** @since 11.0 */ 208  @Override 209  public void recordHits(int count) { 210  hitCount.add(count); 211  } 212  213  /** @since 11.0 */ 214  @Override 215  public void recordMisses(int count) { 216  missCount.add(count); 217  } 218  219  @SuppressWarnings("GoodTime") // b/122668874 220  @Override 221  public void recordLoadSuccess(long loadTime) { 222  loadSuccessCount.increment(); 223  totalLoadTime.add(loadTime); 224  } 225  226  @SuppressWarnings("GoodTime") // b/122668874 227  @Override 228  public void recordLoadException(long loadTime) { 229  loadExceptionCount.increment(); 230  totalLoadTime.add(loadTime); 231  } 232  233  @Override 234  public void recordEviction() { 235  evictionCount.increment(); 236  } 237  238  @Override 239  public CacheStats snapshot() { 240  return new CacheStats( 241  negativeToMaxValue(hitCount.sum()), 242  negativeToMaxValue(missCount.sum()), 243  negativeToMaxValue(loadSuccessCount.sum()), 244  negativeToMaxValue(loadExceptionCount.sum()), 245  negativeToMaxValue(totalLoadTime.sum()), 246  negativeToMaxValue(evictionCount.sum())); 247  } 248  249  /** Returns {@code value}, if non-negative. Otherwise, returns {@link Long#MAX_VALUE}. */ 250  private static long negativeToMaxValue(long value) { 251  return (value >= 0) ? value : Long.MAX_VALUE; 252  } 253  254  /** Increments all counters by the values in {@code other}. */ 255  public void incrementBy(StatsCounter other) { 256  CacheStats otherStats = other.snapshot(); 257  hitCount.add(otherStats.hitCount()); 258  missCount.add(otherStats.missCount()); 259  loadSuccessCount.add(otherStats.loadSuccessCount()); 260  loadExceptionCount.add(otherStats.loadExceptionCount()); 261  totalLoadTime.add(otherStats.totalLoadTime()); 262  evictionCount.add(otherStats.evictionCount()); 263  } 264  } 265 }