package com.hammurapi.store;

import java.util.Comparator;

import com.hammurapi.extract.Extractor;
import com.hammurapi.extract.Predicate;

/**
 * Store.addIndex() returns object which implements one or 
 * more of Index sub-interfaces. Index instances are used
 * to directly leverage index functionality without going through
 * Store.get() methods.
 * @author Pavel Vlasov
 *
 * This interface extends Iterable. Iterator returned by index
 * iterates over objects in the store which match index predicate 
 * and in the order, if the index is ordered. Iteration over indices shall be 
 * performed within store's read lock.
 * @param <T>
 */
public interface Index<ST,T extends ST,PK,V,S extends Store<ST,PK,S>> extends Iterable<T> {
	
	enum Type {
		/**
		 * Unique index is evaluated as part of insert/update (synchronously). 
		 * If uniqueness is violated, exception is thrown and insert/update is
		 * not executed.
		 */
		UNIQUE,
		/**
		 * Synchronous indices as evaluated as part of insert/update (by writer).
		 * If index extractor throws an exception, this exception is propagated
		 * to the caller and insert/update operation doesn't get executed.
		 */
		SYNCHRONOUS,
		/**
		 * Asynchronous index modifications get evaluated in a separate task.
		 * If reader accesses the index before the index update task goes to
		 * execution, index update is performed as part of the access operation (by reader). 
		 * If index extractor throws exception, then index gets marked as 
		 * corrupted and is removed from the store. If the reader
		 * accesses the index directly through one of index interfaces, 
		 * then the exception is propagated to the caller code.
		 * All operations on a corrupted index result in exception.
		 */
		ASYNCHRONOUS,
		/**
		 * Lazy index modifications get queued and are evaluated
		 * as part of the access operation (by reader). If index 
		 * extractor throws exception, then index gets marked as 
		 * corrupted and is removed from the store. If the reader
		 * accesses the index directly through one of index interfaces, 
		 * then the exception is propagated to the caller code.
		 * All operations on a corrupted index result in exception.
		 */
		LAZY
		
	}	

	/**
	 * @return Back-link to the store.
	 */
	S getStore();
	
	Predicate<ST,S> getPredicate();
	
	Extractor<T, V, S> getExtractor();
	
	boolean isUnique();
	
	boolean isOrdered();
	
	Comparator<V> getComparator();	
}
