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

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

The newest version!
package org.aksw.sparqlify.database;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.NavigableMap;
import java.util.Set;
import java.util.TreeMap;
import java.util.function.Function;

import org.aksw.commons.util.strings.StringUtils;

import com.google.common.collect.Sets;


interface PrefixIndexValue
{
	
}

enum LookupDirection
{
	SHORTER,
	LONGER,
	BOTH;
}


public class PrefixIndex
	implements Index
{

	// The table this index is bound to
	private Table table;
	
	private int[] indexColumns;
	private List indexColumnNames;
	
	private Function> prefixExtractor;
	
	private NavigableMap map = new TreeMap();

	
	public PrefixIndex(Table table, int[] indexColumns, Function> prefixExtractor) {
		this.table = table;
		this.indexColumns = indexColumns;
		this.prefixExtractor = prefixExtractor;
		
		this.indexColumnNames = new ArrayList();
		for(int index : indexColumns) {
			this.indexColumnNames.add(table.getColumns().getKey(index));
		}
		
	}
	
	//private Transformer transformer;
	
	public void index(String ... row) {
		
	}

	@Override
	public void add(List row) {
		
		NavigableMap current = map;
		
		for(int i = 0; i < indexColumns.length; ++i) {
			boolean isLast = i == indexColumns.length - 1;
			int index = indexColumns[i];
			T value = row.get(index);
			
			Set prefixes = prefixExtractor.apply(value);
			
			for(String prefix : prefixes) {
				Object o = current.get(prefix);
				
				if(isLast) {
					Set values = (Set)o;
					if(values == null) {
						values = new HashSet();
						current.put(prefix, values);
					}
					/*
					else {
						throw new RuntimeException("Duplicate row");
					}*/
					
					values.add(row);
				} else {				
					NavigableMap next = (NavigableMap) o;
					if(next == null) {
						next = new TreeMap();
						
						current.put(prefix, next);
					}
					current = next;
				}
			}
		}
	}
	
	///*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 void lookup(Constraint ... constraints) {
		/*
		for(VariableConstraintPrefix constraint : constraints) {
			String columnName = constraint.getVariableName();
			
			
		}*/
	}
	
	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, Object tmp, Collection> result)
	{
		boolean isLast = i == prefixList.size();

		//Entry o;

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

			Map candidates = StringUtils.getAllPrefixes(prefix, true, current);
			for(Entry entry : candidates.entrySet()) {
				Object next = 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(Object tmp, int i, Collection> result) {
		// Add everything that is left
		boolean isLast = i == indexColumns.length - 1;
		int index = indexColumns[i];
			
		if(isLast) {
			Set> current = (Set>)tmp;

			result.addAll(current);
			/*
			for(Object o : current) {				
				Set> rows = (Set>) o;
				//List row = (List) o;
				result.addAll(rows);
			}*/
		} else {
			NavigableMap current = (NavigableMap)tmp; 
			
			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);
			}
		}

			
	}
	
	
	public static  PrefixIndex attach(Function> prefixExtractor, Table table, String ... columnNames) {
		List names = Arrays.asList(columnNames);
		
		Set nameSet = new HashSet(names);		
		Set dangling = Sets.difference(nameSet, table.getColumns().keySet());
		if(!dangling.isEmpty()) {
			throw new RuntimeException("Columns " + dangling + " referenced, but not present in table");
		}
		
		int[] indexColumns = new int[columnNames.length];
		for(int i = 0; i < columnNames.length; ++i) {
			Integer index = table.getColumns().getIndex(columnNames[i]);
			if(index == null) {
				throw new NullPointerException("Column name does not have an index");
			}
			indexColumns[i] = index;
		}
		

		PrefixIndex index = new PrefixIndex(table, indexColumns, prefixExtractor);
		
		table.addIndex(index);
		
		return index;
	}

	@Override
	public boolean preAdd(List row) {
		return true;
	}

	@Override
	public void postAdd(List row) {
	}

	@Override
	public Table getTable() {
		return table;
	}

	@Override
	public int[] getIndexColumns() {
		return indexColumns;
	}

	@Override
	public List getIndexColumnNames() {
		return indexColumnNames; 
	}

	@Override
	public String toString() {
		return "PrefixIndex [table=" + table + ", indexColumnNames="
				+ indexColumnNames + "]";
	}

	@Override
	public IndexMetaNode getRoot() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Object getStore() {
		// TODO Auto-generated method stub
		return null;
	}
	
	
}