package eu.dnetlib.miscutils.functional;

import eu.dnetlib.miscutils.factory.Factory;


/**
 * ThreadSafeUnaryFunction maintains a ThreadLocal of a UnaryFunction and 
 * delegates the application to the thread local function.
 * 
 * @author claudio
 *
 * @param <T>
 * @param <K>
 */
public class ThreadSafeUnaryFunction<T, K> implements UnaryFunction<T, K> {

	/**
	 * ThreadLocal UnaryFunction
	 */
	private ThreadLocal<? extends UnaryFunction<T, K>> localFunction;

	/**
	 * Builds a new ThreadSafeUnaryFunction.
	 * @param localFunction
	 */
	public ThreadSafeUnaryFunction(ThreadLocal<? extends UnaryFunction<T, K>> localFunction) {
		super();
		this.localFunction = localFunction;
	}

	/**
	 * Builds a new ThreadSafeUnaryFunction.
	 * @param localFunction
	 */
	public ThreadSafeUnaryFunction(final Factory<? extends UnaryFunction<T, K>> functionFactory) {
		super();
		this.localFunction = new ThreadLocal<UnaryFunction<T,K>>() {
			@Override
			protected synchronized UnaryFunction<T, K> initialValue() {
				return functionFactory.newInstance();
			}
		};
	}

	/**
	 * method applies the evaluation by invoking the ThreadLocal function.
	 */
	@Override
	public T evaluate(K arg) {
		return localFunction.get().evaluate(arg);
	}
}
