All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.blazegraph.gremlin.util.Memoizer Maven / Gradle / Ivy

/**
Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016.  All rights reserved.

Contact:
     SYSTAP, LLC DBA Blazegraph
     2501 Calvert ST NW #106
     Washington, DC 20008
     [email protected]

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/
package com.blazegraph.gremlin.util;

import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import java.util.concurrent.atomic.AtomicReference;

/**
 * Safe lazy-initialization pattern for Java 8.
 * 
 * @author mikepersonick
 */
public class Memoizer {

    private final AtomicReference> cache = new AtomicReference<>(null);
    
    private final Callable compute;

    /**
     * Lazy initializer.
     * 
     * @param compute
     *          Callable to compute the value to cache.
     */
    public Memoizer(final Callable compute) {
        this(compute, null);
    }
    
    /**
     * Eager initializer.
     * 
     * @param compute
     *          Callable to compute the value to cache.
     * @param val
     *          Pre-computed value to cache (if non-null).
     */
    public Memoizer(final Callable compute, final V val) {
        this.compute = compute;
        
        if (val != null) {
            final FutureTask ft = new FutureTask<>(() -> val);
            ft.run();
            cache.set(ft);
        }
    }
    
    /**
     * Get the cached value (compute if necessary).
     * 
     * @return
     *      the cached value
     */
    public V get() {
        if (cache.get() == null) {
            final FutureTask ft = new FutureTask<>(compute);
            if (cache.compareAndSet(null, ft)) {
                ft.run();
            }
        }
        final Future f = cache.get();
        if (f == null) {
            /*
             * Cleared by another thread, re-compute
             */
            return get();
        }
        return Code.wrapThrow(() -> f.get());
    }
    
    /**
     * Clear the cache, return the old value (or null if it had not been 
     * computed yet).
     * 
     * @return
     *      the previously cached value
     */
    public V clear() {
        final Future f = cache.getAndSet(null);
        return f == null ? null : Code.wrapThrow(() -> f.get());
    }
    
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy