Home | History | Annotate | Download | only in cache
      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 static com.google.common.base.Preconditions.checkNotNull;
     18 
     19 import com.google.common.annotations.GwtCompatible;
     20 import com.google.common.annotations.GwtIncompatible;
     21 import com.google.common.collect.Maps;
     22 import com.google.common.util.concurrent.Futures;
     23 import com.google.common.util.concurrent.ListenableFuture;
     24 
     25 import java.util.Map;
     26 import java.util.concurrent.atomic.AtomicInteger;
     27 
     28 import javax.annotation.Nullable;
     29 
     30 /**
     31  * Utility {@link CacheLoader} implementations intended for use in testing.
     32  *
     33  * @author mike nonemacher
     34  */
     35 @GwtCompatible(emulated = true)
     36 class TestingCacheLoaders {
     37 
     38   /**
     39    * Returns a {@link CacheLoader} that implements a naive {@link CacheLoader#loadAll}, delegating
     40    * {@link CacheLoader#load} calls to {@code loader}.
     41    */
     42   static <K, V> CacheLoader<K, V> bulkLoader(final CacheLoader<K, V> loader) {
     43     checkNotNull(loader);
     44     return new CacheLoader<K, V>() {
     45       @Override
     46       public V load(K key) throws Exception {
     47         return loader.load(key);
     48       }
     49 
     50       @Override
     51       public Map<K, V> loadAll(Iterable<? extends K> keys) throws Exception {
     52         Map<K, V> result = Maps.newHashMap(); // allow nulls
     53         for (K key : keys) {
     54           result.put(key, load(key));
     55         }
     56         return result;
     57       }
     58     };
     59   }
     60 
     61   /**
     62    * Returns a {@link CacheLoader} that returns the given {@code constant} for every request.
     63    */
     64   static <K, V> ConstantLoader<K, V> constantLoader(@Nullable V constant) {
     65     return new ConstantLoader<K, V>(constant);
     66   }
     67 
     68   /**
     69    * Returns a {@link CacheLoader} that returns the given {@code constant} for every request.
     70    */
     71   static IncrementingLoader incrementingLoader() {
     72     return new IncrementingLoader();
     73   }
     74 
     75   /**
     76    * Returns a {@link CacheLoader} that throws the given error for every request.
     77    */
     78   static <K, V> CacheLoader<K, V> errorLoader(final Error e) {
     79     checkNotNull(e);
     80     return new CacheLoader<K, V>() {
     81       @Override
     82       public V load(K key) {
     83         throw e;
     84       }
     85     };
     86   }
     87 
     88   /**
     89    * Returns a {@link CacheLoader} that throws the given exception for every request.
     90    */
     91   static <K, V> CacheLoader<K, V> exceptionLoader(final Exception e) {
     92     checkNotNull(e);
     93     return new CacheLoader<K, V>() {
     94       @Override
     95       public V load(K key) throws Exception {
     96         throw e;
     97       }
     98     };
     99   }
    100 
    101   /**
    102    * Returns a {@link CacheLoader} that returns the key for every request.
    103    */
    104   static <T> IdentityLoader<T> identityLoader() {
    105     return new IdentityLoader<T>();
    106   }
    107 
    108   /**
    109    * Returns a {@code new Object()} for every request, and increments a counter for every request.
    110    * The count is accessible via {@link #getCount}.
    111    */
    112   static class CountingLoader extends CacheLoader<Object, Object> {
    113     private final AtomicInteger count = new AtomicInteger();
    114 
    115     @Override
    116     public Object load(Object from) {
    117       count.incrementAndGet();
    118       return new Object();
    119     }
    120 
    121     public int getCount() {
    122       return count.get();
    123     }
    124   }
    125 
    126   static final class ConstantLoader<K, V> extends CacheLoader<K, V> {
    127     private final V constant;
    128 
    129     ConstantLoader(V constant) {
    130       this.constant = constant;
    131     }
    132 
    133     @Override
    134     public V load(K key) {
    135       return constant;
    136     }
    137   }
    138 
    139   /**
    140    * Returns a {@code new Object()} for every request, and increments a counter for every request.
    141    * An {@code Integer} loader that returns the key for {@code load} requests, and increments the
    142    * old value on {@code reload} requests. The load counts are accessible via {@link #getLoadCount}
    143    * and {@link #getReloadCount}.
    144    */
    145   static class IncrementingLoader extends CacheLoader<Integer, Integer> {
    146     private final AtomicInteger countLoad = new AtomicInteger();
    147     private final AtomicInteger countReload = new AtomicInteger();
    148 
    149     @Override
    150     public Integer load(Integer key) {
    151       countLoad.incrementAndGet();
    152       return key;
    153     }
    154 
    155     @GwtIncompatible("reload")
    156     @Override
    157     public ListenableFuture<Integer> reload(Integer key, Integer oldValue) {
    158       countReload.incrementAndGet();
    159       return Futures.immediateFuture(oldValue + 1);
    160     }
    161 
    162     public int getLoadCount() {
    163       return countLoad.get();
    164     }
    165 
    166     public int getReloadCount() {
    167       return countReload.get();
    168     }
    169   }
    170 
    171   static final class IdentityLoader<T> extends CacheLoader<T, T> {
    172     @Override
    173     public T load(T key) {
    174       return key;
    175     }
    176   }
    177 }
    178