package com.hammurapi.extract;

import java.util.Map;
import java.util.Set;

/**
 * Extractors extract values from objects.
 * Extractors are used to reduce number of calcluations performed on 
 * objects through caching of extracted values.
 * Extractors shall implement equals() and hashCode(). Two extractors
 * which extract the same value from the same objects shall be equal. 
 * @author Pavel Vlasov.
 *
 * @param <T> Object type.
 * @param <V> Value type.
 * @param <C> Context type.
 */
public interface Extractor<T, V, C> {
	
	/**
	 * Extracts value.
	 * @param context Extraction context. Extraction context may provide source for constants for comparison
	 * with object values.
	 * @param cache Cache of values extracted from the source object for the given context.
	 * Composite extractors can use cache to find already extracted values and to store extracted values.
	 * For example extractor which extracts object area as obj.getWidth()*obj.getHeight() may find that width was already 
	 * extracted and getWidth() doesn't have to be invoked. So it invokes getHeight() and stores
	 * returned value to the cache. It also calculates object area and stores it to the cache. A particular cache instance
	 * is valid only for a particular obj array, i.e. it can be re-used between extractors but not between arguments.
	 * @param obj Source objects.
	 * @return Extracted value.
	 */
	V extract(C context, Map<C, Map<Extractor<T, ? super V, C>, ? super V>> cache, T... obj);
	
	/**
	 * @return Indexes of objects which this extractor uses for computations.
	 */
	Set<Integer> parameterIndices();
	
	/**
	 * @return True if extractor uses context for extraction. False if only object(s) are used.
	 */
	boolean isContextDependent();
	
	/**
	 * Compares two extractors
	 * @param other Other extractor
	 * @return Comparison result.
	 */
	ComparisonResult compareTo(Extractor<T, V, C> other);
	
	/**
	 * @return Extractor evaluation cost. Cost is used for optimization of computation intensive algorithms.
	 * E.g. in Store it is used for selection of indices for query operations.
	 */
	double getCost();

}
