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    
017    package com.google.common.base;
018    
019    import com.google.common.annotations.Beta;
020    import com.google.common.annotations.GwtCompatible;
021    import com.google.common.annotations.VisibleForTesting;
022    
023    import java.io.Serializable;
024    import java.util.concurrent.TimeUnit;
025    
026    import 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
039    public 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        @Override
066        public T get() {
067          return function.apply(supplier.get());
068        }
069        private static final long serialVersionUID = 0;
070      }
071    
072      /**
073       * Returns a supplier which caches the instance retrieved during the first
074       * call to {@code get()} and returns that value on subsequent calls to
075       * {@code get()}. See:
076       * <a href="http://en.wikipedia.org/wiki/Memoization">memoization</a>
077       *
078       * <p>The returned supplier is thread-safe. The supplier's serialized form
079       * does not contain the cached value, which will be recalculated when {@code
080       * get()} is called on the reserialized instance.
081       *
082       * <p>If {@code delegate} is an instance created by an earlier call to {@code
083       * memoize}, it is returned directly.
084       */
085      public static <T> Supplier<T> memoize(Supplier<T> delegate) {
086        return (delegate instanceof MemoizingSupplier)
087            ? delegate
088            : new MemoizingSupplier<T>(Preconditions.checkNotNull(delegate));
089      }
090    
091      @VisibleForTesting
092      static class MemoizingSupplier<T> implements Supplier<T>, Serializable {
093        final Supplier<T> delegate;
094        transient volatile boolean initialized;
095        // "value" does not need to be volatile; visibility piggy-backs
096        // on volatile read of "initialized".
097        transient T value;
098    
099        MemoizingSupplier(Supplier<T> delegate) {
100          this.delegate = delegate;
101        }
102    
103        @Override
104        public T get() {
105          // A 2-field variant of Double Checked Locking.
106          if (!initialized) {
107            synchronized (this) {
108              if (!initialized) {
109                T t = delegate.get();
110                value = t;
111                initialized = true;
112                return t;
113              }
114            }
115          }
116          return value;
117        }
118    
119        private static final long serialVersionUID = 0;
120      }
121    
122      /**
123       * Returns a supplier that caches the instance supplied by the delegate and
124       * removes the cached value after the specified time has passed. Subsequent
125       * calls to {@code get()} return the cached value if the expiration time has
126       * not passed. After the expiration time, a new value is retrieved, cached,
127       * and returned. See:
128       * <a href="http://en.wikipedia.org/wiki/Memoization">memoization</a>
129       *
130       * <p>The returned supplier is thread-safe. The supplier's serialized form
131       * does not contain the cached value, which will be recalculated when {@code
132       * get()} is called on the reserialized instance.
133       *
134       * @param duration the length of time after a value is created that it
135       *     should stop being returned by subsequent {@code get()} calls
136       * @param unit the unit that {@code duration} is expressed in
137       * @throws IllegalArgumentException if {@code duration} is not positive
138       * @since 2.0
139       */
140      public static <T> Supplier<T> memoizeWithExpiration(
141          Supplier<T> delegate, long duration, TimeUnit unit) {
142        return new ExpiringMemoizingSupplier<T>(delegate, duration, unit);
143      }
144    
145      @VisibleForTesting static class ExpiringMemoizingSupplier<T>
146          implements Supplier<T>, Serializable {
147        final Supplier<T> delegate;
148        final long durationNanos;
149        transient volatile T value;
150        // The special value 0 means "not yet initialized".
151        transient volatile long expirationNanos;
152    
153        ExpiringMemoizingSupplier(
154            Supplier<T> delegate, long duration, TimeUnit unit) {
155          this.delegate = Preconditions.checkNotNull(delegate);
156          this.durationNanos = unit.toNanos(duration);
157          Preconditions.checkArgument(duration > 0);
158        }
159    
160        @Override
161        public T get() {
162          // Another variant of Double Checked Locking.
163          //
164          // We use two volatile reads.  We could reduce this to one by
165          // putting our fields into a holder class, but (at least on x86)
166          // the extra memory consumption and indirection are more
167          // expensive than the extra volatile reads.
168          long nanos = expirationNanos;
169          long now = Platform.systemNanoTime();
170          if (nanos == 0 || now - nanos >= 0) {
171            synchronized (this) {
172              if (nanos == expirationNanos) {  // recheck for lost race
173                T t = delegate.get();
174                value = t;
175                nanos = now + durationNanos;
176                // In the very unlikely event that nanos is 0, set it to 1;
177                // no one will notice 1 ns of tardiness.
178                expirationNanos = (nanos == 0) ? 1 : nanos;
179                return t;
180              }
181            }
182          }
183          return value;
184        }
185    
186        private static final long serialVersionUID = 0;
187      }
188    
189      /**
190       * Returns a supplier that always supplies {@code instance}.
191       */
192      public static <T> Supplier<T> ofInstance(@Nullable T instance) {
193        return new SupplierOfInstance<T>(instance);
194      }
195    
196      private static class SupplierOfInstance<T>
197          implements Supplier<T>, Serializable {
198        final T instance;
199    
200        SupplierOfInstance(@Nullable T instance) {
201          this.instance = instance;
202        }
203        @Override
204        public T get() {
205          return instance;
206        }
207        private static final long serialVersionUID = 0;
208      }
209    
210      /**
211       * Returns a supplier whose {@code get()} method synchronizes on
212       * {@code delegate} before calling it, making it thread-safe.
213       */
214      public static <T> Supplier<T> synchronizedSupplier(Supplier<T> delegate) {
215        return new ThreadSafeSupplier<T>(Preconditions.checkNotNull(delegate));
216      }
217    
218      private static class ThreadSafeSupplier<T>
219          implements Supplier<T>, Serializable {
220        final Supplier<T> delegate;
221    
222        ThreadSafeSupplier(Supplier<T> delegate) {
223          this.delegate = delegate;
224        }
225        @Override
226        public T get() {
227          synchronized (delegate) {
228            return delegate.get();
229          }
230        }
231        private static final long serialVersionUID = 0;
232      }
233    
234      /**
235       * Returns a function that accepts a supplier and returns the result of
236       * invoking {@link Supplier#get} on that supplier.
237       *
238       * @since 8.0
239       */
240      @Beta
241      @SuppressWarnings("unchecked") // SupplierFunction works for any T.
242      public static <T> Function<Supplier<T>, T> supplierFunction() {
243        return (Function) SupplierFunction.INSTANCE;
244      }
245    
246      private enum SupplierFunction implements Function<Supplier<?>, Object> {
247        INSTANCE;
248    
249        @Override
250        public Object apply(Supplier<?> input) {
251          return input.get();
252        }
253      }
254    }