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