use of mondrian.calc.impl.AbstractListCalc in project mondrian by pentaho.
the class DrilldownLevelTopBottomFunDef method compileCall.
public Calc compileCall(final ResolvedFunCall call, ExpCompiler compiler) {
// Compile the member list expression. Ask for a mutable list, because
// we're going to insert members into it later.
final ListCalc listCalc = compiler.compileList(call.getArg(0), true);
final IntegerCalc integerCalc = compiler.compileInteger(call.getArg(1));
final LevelCalc levelCalc = call.getArgCount() > 2 && call.getArg(2).getCategory() != Category.Empty ? compiler.compileLevel(call.getArg(2)) : null;
final Calc orderCalc = call.getArgCount() > 3 ? compiler.compileScalar(call.getArg(3), true) : new ValueCalc(new DummyExp(new ScalarType()));
return new AbstractListCalc(call, new Calc[] { listCalc, integerCalc, orderCalc }) {
public TupleList evaluateList(Evaluator evaluator) {
// Use a native evaluator, if more efficient.
// TODO: Figure this out at compile time.
SchemaReader schemaReader = evaluator.getSchemaReader();
NativeEvaluator nativeEvaluator = schemaReader.getNativeSetEvaluator(call.getFunDef(), call.getArgs(), evaluator, this);
if (nativeEvaluator != null) {
return (TupleList) nativeEvaluator.execute(ResultStyle.LIST);
}
TupleList list = listCalc.evaluateList(evaluator);
int n = integerCalc.evaluateInteger(evaluator);
if (n == FunUtil.IntegerNull || n <= 0) {
return list;
}
Level level;
if (levelCalc == null) {
level = null;
} else {
level = levelCalc.evaluateLevel(evaluator);
}
List<Member> result = new ArrayList<Member>();
assert list.getArity() == 1;
for (Member member : list.slice(0)) {
result.add(member);
if (level != null && member.getLevel() != level) {
if (level.getDimension() != member.getDimension()) {
throw newEvalException(DrilldownLevelTopBottomFunDef.this, "Level '" + level.getUniqueName() + "' not compatible with member '" + member.getUniqueName() + "'");
}
continue;
}
List<Member> children = schemaReader.getMemberChildren(member);
final int savepoint = evaluator.savepoint();
List<Member> sortedChildren;
try {
evaluator.setNonEmpty(false);
sortedChildren = Sorter.sortMembers(evaluator, children, children, orderCalc, top, true);
} finally {
evaluator.restore(savepoint);
}
int x = Math.min(n, sortedChildren.size());
for (int i = 0; i < x; i++) {
result.add(sortedChildren.get(i));
}
}
return new UnaryTupleList(result);
}
public boolean dependsOn(Hierarchy hierarchy) {
return anyDependsButFirst(getCalcs(), hierarchy);
}
};
}
use of mondrian.calc.impl.AbstractListCalc in project mondrian by pentaho.
the class ExceptFunDef method compileCall.
public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
// todo: implement ALL
final ListCalc listCalc0 = compiler.compileList(call.getArg(0));
final ListCalc listCalc1 = compiler.compileList(call.getArg(1));
return new AbstractListCalc(call, new Calc[] { listCalc0, listCalc1 }) {
public TupleList evaluateList(Evaluator evaluator) {
TupleList list0 = listCalc0.evaluateList(evaluator);
if (list0.isEmpty()) {
return list0;
}
TupleList list1 = listCalc1.evaluateList(evaluator);
if (list1.isEmpty()) {
return list0;
}
final Set<List<Member>> set1 = new HashSet<List<Member>>(list1);
final TupleList result = new ArrayTupleList(list0.getArity(), list0.size());
for (List<Member> tuple1 : list0) {
if (!set1.contains(tuple1)) {
result.add(tuple1);
}
}
return result;
}
};
}
use of mondrian.calc.impl.AbstractListCalc in project mondrian by pentaho.
the class ExistsFunDef method compileCall.
public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
final ListCalc listCalc1 = compiler.compileList(call.getArg(0));
final ListCalc listCalc2 = compiler.compileList(call.getArg(1));
return new AbstractListCalc(call, new Calc[] { listCalc1, listCalc2 }) {
public TupleList evaluateList(Evaluator evaluator) {
TupleList leftTuples = listCalc1.evaluateList(evaluator);
if (leftTuples.isEmpty()) {
return TupleCollections.emptyList(leftTuples.getArity());
}
TupleList rightTuples = listCalc2.evaluateList(evaluator);
if (rightTuples.isEmpty()) {
return TupleCollections.emptyList(leftTuples.getArity());
}
TupleList result = TupleCollections.createList(leftTuples.getArity());
List<Hierarchy> leftDims = getHierarchies(leftTuples.get(0));
List<Hierarchy> rightDims = getHierarchies(rightTuples.get(0));
leftLoop: for (List<Member> leftTuple : leftTuples) {
for (List<Member> rightTuple : rightTuples) {
if (existsInTuple(leftTuple, rightTuple, leftDims, rightDims, null)) {
result.add(leftTuple);
continue leftLoop;
}
}
}
return result;
}
};
}
use of mondrian.calc.impl.AbstractListCalc in project mondrian by pentaho.
the class HeadTailFunDef method compileCall.
public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
final ListCalc listCalc = compiler.compileList(call.getArg(0));
final IntegerCalc integerCalc = call.getArgCount() > 1 ? compiler.compileInteger(call.getArg(1)) : ConstantCalc.constantInteger(1);
if (head) {
return new AbstractListCalc(call, new Calc[] { listCalc, integerCalc }) {
public TupleList evaluateList(Evaluator evaluator) {
final int savepoint = evaluator.savepoint();
try {
evaluator.setNonEmpty(false);
TupleList list = listCalc.evaluateList(evaluator);
int count = integerCalc.evaluateInteger(evaluator);
return head(count, list);
} finally {
evaluator.restore(savepoint);
}
}
};
} else {
return new AbstractListCalc(call, new Calc[] { listCalc, integerCalc }) {
public TupleList evaluateList(Evaluator evaluator) {
final int savepoint = evaluator.savepoint();
try {
evaluator.setNonEmpty(false);
TupleList list = listCalc.evaluateList(evaluator);
int count = integerCalc.evaluateInteger(evaluator);
return tail(count, list);
} finally {
evaluator.restore(savepoint);
}
}
};
}
}
use of mondrian.calc.impl.AbstractListCalc in project mondrian by pentaho.
the class DrilldownLevelFunDef method compileCall.
public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
final ListCalc listCalc = compiler.compileList(call.getArg(0));
final LevelCalc levelCalc = call.getArgCount() > 1 && call.getArg(1).getType() instanceof mondrian.olap.type.LevelType ? compiler.compileLevel(call.getArg(1)) : null;
final IntegerCalc indexCalc = call.getArgCount() > 2 ? compiler.compileInteger(call.getArg(2)) : null;
final int arity = listCalc.getType().getArity();
if (indexCalc == null) {
return new AbstractListCalc(call, new Calc[] { listCalc, levelCalc }) {
public TupleList evaluateList(Evaluator evaluator) {
TupleList list = listCalc.evaluateList(evaluator);
if (list.size() == 0) {
return list;
}
int searchDepth = -1;
if (levelCalc != null) {
Level level = levelCalc.evaluateLevel(evaluator);
searchDepth = level.getDepth();
}
return new UnaryTupleList(drill(searchDepth, list.slice(0), evaluator));
}
};
} else {
return new AbstractListCalc(call, new Calc[] { listCalc, indexCalc }) {
public TupleList evaluateList(Evaluator evaluator) {
TupleList list = listCalc.evaluateList(evaluator);
if (list.isEmpty()) {
return list;
}
final int index = indexCalc.evaluateInteger(evaluator);
if (index < 0 || index >= arity) {
return list;
}
TupleList result = TupleCollections.createList(arity);
final SchemaReader schemaReader = evaluator.getSchemaReader();
final Member[] tupleClone = new Member[arity];
for (List<Member> tuple : list) {
result.add(tuple);
final List<Member> children = schemaReader.getMemberChildren(tuple.get(index));
for (Member child : children) {
tuple.toArray(tupleClone);
tupleClone[index] = child;
result.addTuple(tupleClone);
}
}
return result;
}
};
}
}
Aggregations