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

org.aksw.sparqlify.database.PrefixMapStoreAccessor Maven / Gradle / Ivy

There is a newer version: 3.17.0-1
Show newest version
package org.aksw.sparqlify.database;

import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.NavigableMap;
import java.util.Set;
import java.util.TreeMap;

import org.aksw.commons.util.strings.StringUtils;
import org.apache.commons.collections15.Transformer;


interface MapStoreAccessor {
	//void add(Object store, List row);
	//void put(Object store, Object )
	
	Set> getSupportedConstraintClasses();
	
	//
	// Insertion and lookup of rows 
	//
	void put(Object store, List row, Object value);
	Object get(Object store, List row);
	
	// TODO: Is this the same as lookup without constraints? Guess so!
	Collection list(Object store);
	
	//
	// Lookup with constraints (e.g. greater(1.0), equals('foo'), ... 
	//
	Collection lookup(Object store, Constraint constraint);
	
	
	/**
	 * Create a new store that can be used with this accessor
	 * 
	 * @return
	 */
	Object createStore();
}


interface IndexStore {
	public List lookup(List constraints);
}



/**
 * Accessor for a NavigableMap, Object>
 * 
 * We separate the accessor from the store, in order to avoid duplicating
 * (referenences to) the index metadata at each node of the index tree -
 * this way there is just one accessor with the metadata, which can
 * work on any corresponding store at some level in an hierarchical index.  
 * 
 * 
 * @author Claus Stadler 
 *
 */
public class PrefixMapStoreAccessor
	implements MapStoreAccessor
{
	public static Set> supportedConstraintClasses = new HashSet>();

	static
	{
		supportedConstraintClasses.add(EqualsConstraint.class);
		supportedConstraintClasses.add(StartsWithConstraint.class);
		supportedConstraintClasses.add(IsPrefixOfConstraint.class);		
	}
	
	public Set> getSupportedConstraintClasses() {
		return supportedConstraintClasses;
	}

	
	private int indexColumn;
	private Transformer> prefixExtractor;

	public PrefixMapStoreAccessor(int[] indexColumns, Transformer> prefixExtractor) {
		if(indexColumns.length != 1) {
			throw new RuntimeException("Prefix index can only operate on single columns");
		}
		
		this.indexColumn = indexColumns[0];
		this.prefixExtractor = prefixExtractor;
	}
	
	/**
	 * We assume that
	 * . only classes that are in supportedConstraintClasses are passed to this method.
	 * . only constraints for which the index has the right columns are passed
	 * 
	 * This method should only be used by the engine
	 * 
	 * @param constraints
	 * @return
	 */
	/*
	@Override
	public Collection lookup(Object store, List constraints)
	{
		return lookup((NavigableMap)store, constraints);
	}*/
		

	@Override
	public void put(Object store, List row, Object value) {
		/*
		PatriciaTrie x;
		x.prefixMap(arg0)
		*/
		
		
		put((NavigableMap)store, row, value);
	}
	
	public void put(NavigableMap map, List row, Object value) {
		map.put((String)row.get(indexColumn), value);
	}
	
	///*protected PrefixMap
	
	/**
	 * The constraints given as arguments are interpreted as conjunctions.
	 * The set of prefixes within a constraint is interpreted as a disjunction. 
	 * 
	 * 
	 * @param constraints
	 */
	public Collection lookup(Object store, Constraint constraint) {
		NavigableMap map = (NavigableMap)store; 
		
		if(constraint instanceof IsPrefixOfConstraint) {
			return lookup(map, (IsPrefixOfConstraint)constraint);
		} else if(constraint instanceof StartsWithConstraint) {
			return lookup(map, (StartsWithConstraint)constraint);
		} else if(constraint instanceof EqualsConstraint) {
			return lookup(map, (EqualsConstraint)constraint);
		} else {
			throw new RuntimeException("Could not handle constraint " + constraint);
		}
	}
	
	public Collection lookup(NavigableMap map, EqualsConstraint constraint) {
		return Collections.singleton(map.get(constraint.getValue()));
	}
	
	public Collection lookup(NavigableMap map, StartsWithConstraint constraint) {
		return StringUtils.getAllPrefixedEntries(constraint.getPrefix(), constraint.isInclusive(), map).values();
	}

	public Collection lookup(NavigableMap map, IsPrefixOfConstraint constraint) {
		return StringUtils.getAllPrefixes(constraint.getValue(), constraint.isInclusive(), map).values();
	}

	@Override
	public Object get(Object store, List row) {
		return get((NavigableMap)store, row);
	}
	
	public Object get(NavigableMap map, List row) {
		return map.get(row.get(indexColumn));
	}

	@SuppressWarnings("unchecked")
	@Override
	public Collection list(Object store) {
		return ((NavigableMap)store).values();
	}

	@Override
	public Object createStore() {
		return new TreeMap();
	}
	
	

	/*
	public Collection> lookupSimple(List prefixList)
	{
		List> result = new ArrayList>();
		lookupSimple(prefixList, 0, map, result);
		return result;
	}

	public Collection> lookupSimpleLonger(List prefixList)
	{
		List> result = new ArrayList>();
		lookupSimpleLonger(prefixList, 0, map, result);
		return result;
	}
	*/
	
	/*
	public void lookupSimple(List prefixList, int i, NavigableMap current, Collection> result)
	{
		boolean isLast = i == prefixList.size();

		//Entry o;

		if(isLast) {
			lookupRemaining(current, i, result);
		} else {
			int index = indexColumns[i];
			String prefix = prefixList.get(index);

			Map candidates = StringUtils.getAllPrefixes(prefix, true, current);
			for(Entry entry : candidates.entrySet()) {
				NavigableMap next = (NavigableMap) entry.getValue();
				lookupSimple(prefixList, i + 1, next, result);
			}
		
		}		
	}
	
	public void lookupSimpleLonger(List prefixList, int i, NavigableMap current, Collection> result)
	{
		boolean isLast = i == prefixList.size();

		//Entry o;

		if(isLast) {
			lookupRemaining(current, i, result);
		} else {
			int index = indexColumns[i];
			String prefix = prefixList.get(index);

			Map candidates = StringUtils.getAllPrefixedEntries(prefix, true, current);
			for(Entry entry : candidates.entrySet()) {
				NavigableMap next = (NavigableMap) entry.getValue();
				lookupSimpleLonger(prefixList, i + 1, next, result);
			}
		
		}		
	}
	
	
	
	public void lookupRemaining(NavigableMap current, int i, Collection> result) {
		// Add everything that is left
		boolean isLast = i == indexColumns.length - 1;
		int index = indexColumns[i];
			
		if(isLast) {
			for(Object o : current.values()) {				
				List row = (List) o;
				result.add(row);
			}
		} else {
			for(Object o : current.values()) {
				NavigableMap next = (NavigableMap) o;
				
				lookupRemaining(next, i + 1, result);
			}
		}
	}

	/*
	public Collection> lookup(List> prefixesList) {
		List> result = new ArrayList>();
		
		lookup(prefixesList, 0, map, result);
		
		return result;
	}*/

	/*
	public void lookup(List> prefixesList, int i, NavigableMap current, Collection> result) {

		boolean isLast = i == indexColumns.length - 1;
		int index = indexColumns[i];
		Set prefixes = prefixesList.get(index);

		for(String prefix : prefixes) {
			Object o = current.get(prefix);
			
			if(isLast) {
				if(o == null) {
					return;
				}
				
				List row = (List) o;
				
				result.add(row);
			} else {				
				NavigableMap next = (NavigableMap) o;
				if(next == null) {
					return;
				}
				
				lookup(prefixesList, i + 1, next, result);
			}
		}

			
	}
	*/
}