/*
***************************************************************************************
* Copyright (C) 2006 EsperTech, Inc. All rights reserved. *
* http://www.espertech.com/esper *
* http://www.espertech.com *
* ---------------------------------------------------------------------------------- *
* The software in this package is published under the terms of the GPL license *
* a copy of which has been included with this distribution in the license.txt file. *
***************************************************************************************
*/
package com.espertech.esper.epl.join.plan;
import java.util.ArrayList;
import java.util.List;
public class QueryPlanIndexUniqueHelper {
public static ReducedHashKeys reduceToUniqueIfPossible(String[] hashPropsProvided, Class[] hashCoercionTypes, List<QueryGraphValueEntryHashKeyed> hashFunctions, String[][] hashPropsRequiredPerIndex) {
if (hashPropsRequiredPerIndex == null || hashPropsRequiredPerIndex.length == 0) {
return null;
}
for (String[] hashPropsRequired : hashPropsRequiredPerIndex) {
int[] indexes = checkSufficientGetAssignment(hashPropsRequired, hashPropsProvided);
if (indexes != null) {
String[] props = new String[indexes.length];
Class[] types = new Class[indexes.length];
List<QueryGraphValueEntryHashKeyed> functions = new ArrayList<QueryGraphValueEntryHashKeyed>();
for (int i = 0; i < indexes.length; i++) {
props[i] = hashPropsProvided[indexes[i]];
types[i] = hashCoercionTypes == null ? null : hashCoercionTypes[indexes[i]];
functions.add(hashFunctions.get(indexes[i]));
}
return new ReducedHashKeys(props, types, functions);
}
}
return null;
}
public static int[] checkSufficientGetAssignment(String[] hashPropsRequired, String[] hashPropsProvided) {
if (hashPropsProvided == null || hashPropsRequired == null || hashPropsProvided.length < hashPropsRequired.length) {
return null;
}
// first pass: determine if possible
for (String required : hashPropsRequired) {
boolean found = false;
for (String provided : hashPropsProvided) {
if (provided.equals(required)) {
found = true;
break;
}
}
if (!found) {
return null;
}
}
// second pass: determine assignments
int[] indexes = new int[hashPropsRequired.length];
for (int i = 0; i < indexes.length; i++) {
int foundIndex = -1;
String required = hashPropsRequired[i];
for (int j = 0; j < hashPropsProvided.length; j++) {
if (hashPropsProvided[j].equals(required)) {
foundIndex = j;
break;
}
}
indexes[i] = foundIndex;
}
return indexes;
}
public static class ReducedHashKeys {
private final String[] propertyNames;
private final Class[] coercionTypes;
private final List<QueryGraphValueEntryHashKeyed> hashKeyFunctions;
private ReducedHashKeys(String[] propertyNames, Class[] coercionTypes, List<QueryGraphValueEntryHashKeyed> hashKeyFunctions) {
this.propertyNames = propertyNames;
this.coercionTypes = coercionTypes;
this.hashKeyFunctions = hashKeyFunctions;
}
public String[] getPropertyNames() {
return propertyNames;
}
public Class[] getCoercionTypes() {
return coercionTypes;
}
public List<QueryGraphValueEntryHashKeyed> getHashKeyFunctions() {
return hashKeyFunctions;
}
}
}