001/* 002 * Copyright (C) 2007 The Guava Authors 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package com.google.common.base; 018 019import com.google.common.annotations.Beta; 020import com.google.common.annotations.GwtCompatible; 021import com.google.common.annotations.VisibleForTesting; 022 023import java.io.Serializable; 024import java.util.concurrent.TimeUnit; 025 026import javax.annotation.Nullable; 027 028/** 029 * Useful suppliers. 030 * 031 * <p>All methods return serializable suppliers as long as they're given 032 * serializable parameters. 033 * 034 * @author Laurence Gonsalves 035 * @author Harry Heymann 036 * @since 2.0 (imported from Google Collections Library) 037 */ 038@GwtCompatible 039public final class Suppliers { 040 private Suppliers() {} 041 042 /** 043 * Returns a new supplier which is the composition of the provided function 044 * and supplier. In other words, the new supplier's value will be computed by 045 * retrieving the value from {@code supplier}, and then applying 046 * {@code function} to that value. Note that the resulting supplier will not 047 * call {@code supplier} or invoke {@code function} until it is called. 048 */ 049 public static <F, T> Supplier<T> compose( 050 Function<? super F, T> function, Supplier<F> supplier) { 051 Preconditions.checkNotNull(function); 052 Preconditions.checkNotNull(supplier); 053 return new SupplierComposition<F, T>(function, supplier); 054 } 055 056 private static class SupplierComposition<F, T> 057 implements Supplier<T>, Serializable { 058 final Function<? super F, T> function; 059 final Supplier<F> supplier; 060 061 SupplierComposition(Function<? super F, T> function, Supplier<F> supplier) { 062 this.function = function; 063 this.supplier = supplier; 064 } 065 066 @Override public T get() { 067 return function.apply(supplier.get()); 068 } 069 070 @Override public boolean equals(@Nullable Object obj) { 071 if (obj instanceof SupplierComposition) { 072 SupplierComposition<?, ?> that = (SupplierComposition<?, ?>) obj; 073 return function.equals(that.function) && supplier.equals(that.supplier); 074 } 075 return false; 076 } 077 078 @Override public int hashCode() { 079 return Objects.hashCode(function, supplier); 080 } 081 082 @Override public String toString() { 083 return "Suppliers.compose(" + function + ", " + supplier + ")"; 084 } 085 086 private static final long serialVersionUID = 0; 087 } 088 089 /** 090 * Returns a supplier which caches the instance retrieved during the first 091 * call to {@code get()} and returns that value on subsequent calls to 092 * {@code get()}. See: 093 * <a href="http://en.wikipedia.org/wiki/Memoization">memoization</a> 094 * 095 * <p>The returned supplier is thread-safe. The supplier's serialized form 096 * does not contain the cached value, which will be recalculated when {@code 097 * get()} is called on the reserialized instance. 098 * 099 * <p>If {@code delegate} is an instance created by an earlier call to {@code 100 * memoize}, it is returned directly. 101 */ 102 public static <T> Supplier<T> memoize(Supplier<T> delegate) { 103 return (delegate instanceof MemoizingSupplier) 104 ? delegate 105 : new MemoizingSupplier<T>(Preconditions.checkNotNull(delegate)); 106 } 107 108 @VisibleForTesting 109 static class MemoizingSupplier<T> implements Supplier<T>, Serializable { 110 final Supplier<T> delegate; 111 transient volatile boolean initialized; 112 // "value" does not need to be volatile; visibility piggy-backs 113 // on volatile read of "initialized". 114 transient T value; 115 116 MemoizingSupplier(Supplier<T> delegate) { 117 this.delegate = delegate; 118 } 119 120 @Override public T get() { 121 // A 2-field variant of Double Checked Locking. 122 if (!initialized) { 123 synchronized (this) { 124 if (!initialized) { 125 T t = delegate.get(); 126 value = t; 127 initialized = true; 128 return t; 129 } 130 } 131 } 132 return value; 133 } 134 135 @Override public String toString() { 136 return "Suppliers.memoize(" + delegate + ")"; 137 } 138 139 private static final long serialVersionUID = 0; 140 } 141 142 /** 143 * Returns a supplier that caches the instance supplied by the delegate and 144 * removes the cached value after the specified time has passed. Subsequent 145 * calls to {@code get()} return the cached value if the expiration time has 146 * not passed. After the expiration time, a new value is retrieved, cached, 147 * and returned. See: 148 * <a href="http://en.wikipedia.org/wiki/Memoization">memoization</a> 149 * 150 * <p>The returned supplier is thread-safe. The supplier's serialized form 151 * does not contain the cached value, which will be recalculated when {@code 152 * get()} is called on the reserialized instance. 153 * 154 * @param duration the length of time after a value is created that it 155 * should stop being returned by subsequent {@code get()} calls 156 * @param unit the unit that {@code duration} is expressed in 157 * @throws IllegalArgumentException if {@code duration} is not positive 158 * @since 2.0 159 */ 160 public static <T> Supplier<T> memoizeWithExpiration( 161 Supplier<T> delegate, long duration, TimeUnit unit) { 162 return new ExpiringMemoizingSupplier<T>(delegate, duration, unit); 163 } 164 165 @VisibleForTesting static class ExpiringMemoizingSupplier<T> 166 implements Supplier<T>, Serializable { 167 final Supplier<T> delegate; 168 final long durationNanos; 169 transient volatile T value; 170 // The special value 0 means "not yet initialized". 171 transient volatile long expirationNanos; 172 173 ExpiringMemoizingSupplier( 174 Supplier<T> delegate, long duration, TimeUnit unit) { 175 this.delegate = Preconditions.checkNotNull(delegate); 176 this.durationNanos = unit.toNanos(duration); 177 Preconditions.checkArgument(duration > 0); 178 } 179 180 @Override public T get() { 181 // Another variant of Double Checked Locking. 182 // 183 // We use two volatile reads. We could reduce this to one by 184 // putting our fields into a holder class, but (at least on x86) 185 // the extra memory consumption and indirection are more 186 // expensive than the extra volatile reads. 187 long nanos = expirationNanos; 188 long now = Platform.systemNanoTime(); 189 if (nanos == 0 || now - nanos >= 0) { 190 synchronized (this) { 191 if (nanos == expirationNanos) { // recheck for lost race 192 T t = delegate.get(); 193 value = t; 194 nanos = now + durationNanos; 195 // In the very unlikely event that nanos is 0, set it to 1; 196 // no one will notice 1 ns of tardiness. 197 expirationNanos = (nanos == 0) ? 1 : nanos; 198 return t; 199 } 200 } 201 } 202 return value; 203 } 204 205 @Override public String toString() { 206 // This is a little strange if the unit the user provided was not NANOS, 207 // but we don't want to store the unit just for toString 208 return "Suppliers.memoizeWithExpiration(" + delegate + ", " + 209 durationNanos + ", NANOS)"; 210 } 211 212 private static final long serialVersionUID = 0; 213 } 214 215 /** 216 * Returns a supplier that always supplies {@code instance}. 217 */ 218 public static <T> Supplier<T> ofInstance(@Nullable T instance) { 219 return new SupplierOfInstance<T>(instance); 220 } 221 222 private static class SupplierOfInstance<T> 223 implements Supplier<T>, Serializable { 224 final T instance; 225 226 SupplierOfInstance(@Nullable T instance) { 227 this.instance = instance; 228 } 229 230 @Override public T get() { 231 return instance; 232 } 233 234 @Override public boolean equals(@Nullable Object obj) { 235 if (obj instanceof SupplierOfInstance) { 236 SupplierOfInstance<?> that = (SupplierOfInstance<?>) obj; 237 return Objects.equal(instance, that.instance); 238 } 239 return false; 240 } 241 242 @Override public int hashCode() { 243 return Objects.hashCode(instance); 244 } 245 246 @Override public String toString() { 247 return "Suppliers.ofInstance(" + instance + ")"; 248 } 249 250 private static final long serialVersionUID = 0; 251 } 252 253 /** 254 * Returns a supplier whose {@code get()} method synchronizes on 255 * {@code delegate} before calling it, making it thread-safe. 256 */ 257 public static <T> Supplier<T> synchronizedSupplier(Supplier<T> delegate) { 258 return new ThreadSafeSupplier<T>(Preconditions.checkNotNull(delegate)); 259 } 260 261 private static class ThreadSafeSupplier<T> 262 implements Supplier<T>, Serializable { 263 final Supplier<T> delegate; 264 265 ThreadSafeSupplier(Supplier<T> delegate) { 266 this.delegate = delegate; 267 } 268 269 @Override public T get() { 270 synchronized (delegate) { 271 return delegate.get(); 272 } 273 } 274 275 @Override public String toString() { 276 return "Suppliers.synchronizedSupplier(" + delegate + ")"; 277 } 278 279 private static final long serialVersionUID = 0; 280 } 281 282 /** 283 * Returns a function that accepts a supplier and returns the result of 284 * invoking {@link Supplier#get} on that supplier. 285 * 286 * @since 8.0 287 */ 288 @Beta 289 //SupplierFunction works for any T. 290 @SuppressWarnings({"unchecked", "rawtypes"}) 291 public static <T> Function<Supplier<T>, T> supplierFunction() { 292 return (Function) SupplierFunction.INSTANCE; 293 } 294 295 private enum SupplierFunction implements Function<Supplier<?>, Object> { 296 INSTANCE; 297 298 @Override public Object apply(Supplier<?> input) { 299 return input.get(); 300 } 301 302 @Override public String toString() { 303 return "Suppliers.supplierFunction()"; 304 } 305 } 306}