use of mondrian.calc.TupleCalc in project mondrian by pentaho.
the class CachedExistsFunDef method compileCall.
public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
final ListCalc listCalc1 = compiler.compileList(call.getArg(0));
final TupleCalc tupleCalc1 = compiler.compileTuple(call.getArg(1));
final StringCalc stringCalc = compiler.compileString(call.getArg(2));
return new AbstractListCalc(call, new Calc[] { listCalc1, tupleCalc1, stringCalc }) {
public TupleList evaluateList(Evaluator evaluator) {
evaluator.getTiming().markStart(TIMING_NAME);
try {
Member[] subtotal = tupleCalc1.evaluateTuple(evaluator);
String namedSetName = stringCalc.evaluateString(evaluator);
Object cacheObj = evaluator.getQuery().getEvalCache(makeSetCacheKey(namedSetName, subtotal));
if (cacheObj != null) {
HashMap<String, TupleList> setCache = (HashMap<String, TupleList>) cacheObj;
TupleList tuples = setCache.get(makeSubtotalKey(subtotal));
if (tuples == null) {
tuples = TupleCollections.emptyList(listCalc1.getType().getArity());
}
return tuples;
}
// Build a mapping from subtotal tuple types to the input set's tuple types
List<Hierarchy> listHiers = getHierarchies(listCalc1.getType());
List<Hierarchy> subtotalHiers = getHierarchies(tupleCalc1.getType());
int[] subtotalToListIndex = new int[subtotalHiers.size()];
for (int i = 0; i < subtotalToListIndex.length; i++) {
Hierarchy subtotalHier = subtotalHiers.get(i);
boolean found = false;
for (int j = 0; j < listHiers.size(); j++) {
if (listHiers.get(j) == subtotalHier) {
subtotalToListIndex[i] = j;
found = true;
break;
}
}
if (!found) {
throw new IllegalArgumentException("Hierarchy in <Tuple> not present in <Set>");
}
}
// Build subtotal cache
HashMap<String, TupleList> setCache = new HashMap<String, TupleList>();
TupleList setToCache = listCalc1.evaluateList(evaluator);
for (List<Member> tuple : setToCache) {
String subtotalKey = makeSubtotalKey(subtotalToListIndex, tuple, subtotal);
TupleList tupleCache = setCache.get(subtotalKey);
if (tupleCache == null) {
tupleCache = TupleCollections.createList(listCalc1.getType().getArity());
setCache.put(subtotalKey, tupleCache);
}
tupleCache.add(tuple);
}
evaluator.getQuery().putEvalCache(makeSetCacheKey(namedSetName, subtotal), setCache);
TupleList tuples = setCache.get(makeSubtotalKey(subtotal));
if (tuples == null) {
tuples = TupleCollections.emptyList(listCalc1.getType().getArity());
}
return tuples;
} finally {
evaluator.getTiming().markEnd(TIMING_NAME);
}
}
};
}
Aggregations