use of mondrian.calc.impl.AbstractListCalc in project mondrian by pentaho.
the class NonEmptyCrossJoinFunDef method compileCall.
public Calc compileCall(final 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 }, false) {
public TupleList evaluateList(Evaluator evaluator) {
SchemaReader schemaReader = evaluator.getSchemaReader();
// Evaluate the arguments in non empty mode, but remove from
// the slicer any members that will be overridden by args to
// the NonEmptyCrossjoin function. For example, in
//
// SELECT NonEmptyCrossJoin(
// [Store].[USA].Children,
// [Product].[Beer].Children)
// FROM [Sales]
// WHERE [Store].[Mexico]
//
// we want all beers, not just those sold in Mexico.
final int savepoint = evaluator.savepoint();
try {
evaluator.setNonEmpty(true);
for (Member member : ((RolapEvaluator) evaluator).getSlicerMembers()) {
if (getType().getElementType().usesHierarchy(member.getHierarchy(), true)) {
evaluator.setContext(member.getHierarchy().getAllMember());
}
}
NativeEvaluator nativeEvaluator = schemaReader.getNativeSetEvaluator(call.getFunDef(), call.getArgs(), evaluator, this);
if (nativeEvaluator != null) {
evaluator.restore(savepoint);
return (TupleList) nativeEvaluator.execute(ResultStyle.LIST);
}
final TupleList list1 = listCalc1.evaluateList(evaluator);
if (list1.isEmpty()) {
evaluator.restore(savepoint);
return list1;
}
final TupleList list2 = listCalc2.evaluateList(evaluator);
TupleList result = mutableCrossJoin(list1, list2);
// remove any remaining empty crossings from the result
result = nonEmptyList(evaluator, result, call);
return result;
} finally {
evaluator.restore(savepoint);
}
}
public boolean dependsOn(Hierarchy hierarchy) {
if (super.dependsOn(hierarchy)) {
return true;
}
// expression from the inherited context.
if (listCalc1.getType().usesHierarchy(hierarchy, true)) {
return false;
}
if (listCalc2.getType().usesHierarchy(hierarchy, true)) {
return false;
}
// whether a given tuple is empty, depends upon all dimensions.
return true;
}
};
}
use of mondrian.calc.impl.AbstractListCalc in project mondrian by pentaho.
the class PeriodsToDateFunDef method compileCall.
public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
final LevelCalc levelCalc = call.getArgCount() > 0 ? compiler.compileLevel(call.getArg(0)) : null;
final MemberCalc memberCalc = call.getArgCount() > 1 ? compiler.compileMember(call.getArg(1)) : null;
final RolapHierarchy timeHierarchy = levelCalc == null ? ((RolapCube) compiler.getEvaluator().getCube()).getTimeHierarchy(getName()) : null;
return new AbstractListCalc(call, new Calc[] { levelCalc, memberCalc }) {
public TupleList evaluateList(Evaluator evaluator) {
evaluator.getTiming().markStart(TIMING_NAME);
try {
final Member member;
final Level level;
if (levelCalc == null) {
member = evaluator.getContext(timeHierarchy);
level = member.getLevel().getParentLevel();
} else {
level = levelCalc.evaluateLevel(evaluator);
if (memberCalc == null) {
member = evaluator.getContext(level.getHierarchy());
} else {
member = memberCalc.evaluateMember(evaluator);
}
}
return new UnaryTupleList(periodsToDate(evaluator, level, member));
} finally {
evaluator.getTiming().markEnd(TIMING_NAME);
}
}
public boolean dependsOn(Hierarchy hierarchy) {
if (super.dependsOn(hierarchy)) {
return true;
}
if (memberCalc != null) {
return false;
} else if (levelCalc != null) {
return levelCalc.getType().usesHierarchy(hierarchy, true);
} else {
return hierarchy == timeHierarchy;
}
}
};
}
use of mondrian.calc.impl.AbstractListCalc in project mondrian by pentaho.
the class TopBottomCountFunDef 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 sort it later.
final ListCalc listCalc = compiler.compileList(call.getArg(0), true);
final IntegerCalc integerCalc = compiler.compileInteger(call.getArg(1));
final Calc orderCalc = call.getArgCount() > 2 ? compiler.compileScalar(call.getArg(2), true) : null;
final int arity = call.getType().getArity();
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);
}
int n = integerCalc.evaluateInteger(evaluator);
if (n == 0 || n == mondrian.olap.fun.FunUtil.IntegerNull) {
return TupleCollections.emptyList(arity);
}
TupleList list = listCalc.evaluateList(evaluator);
assert list.getArity() == arity;
if (list.isEmpty()) {
return list;
}
if (orderCalc == null) {
// REVIEW: Why require "instanceof AbstractList"?
if (list instanceof AbstractList && list.size() <= n) {
return list;
} else if (top) {
return list.subList(0, n);
} else {
return list.subList(list.size() - n, list.size());
}
}
return partiallySortList(evaluator, list, hasHighCardDimension(list), Math.min(n, list.size()));
}
private TupleList partiallySortList(Evaluator evaluator, TupleList list, boolean highCard, int n) {
assert list.size() > 0;
assert n <= list.size();
if (highCard) {
// sort list in chunks, collect the results
// what is this really?
final int chunkSize = 6400;
TupleList allChunkResults = TupleCollections.createList(arity);
for (int i = 0, next; i < list.size(); i = next) {
next = Math.min(i + chunkSize, list.size());
final TupleList chunk = list.subList(i, next);
TupleList chunkResult = partiallySortList(evaluator, chunk, false, n);
allChunkResults.addAll(chunkResult);
}
// one last sort, to merge and cull
return partiallySortList(evaluator, allChunkResults, false, n);
}
// normal case: no need for chunks
final int savepoint = evaluator.savepoint();
try {
switch(list.getArity()) {
case 1:
final List<Member> members = Sorter.partiallySortMembers(evaluator.push(), list.slice(0), orderCalc, n, top);
return new UnaryTupleList(members);
default:
final List<List<Member>> tuples = partiallySortTuples(evaluator.push(), list, orderCalc, n, top);
return new DelegatingTupleList(list.getArity(), tuples);
}
} finally {
evaluator.restore(savepoint);
}
}
public boolean dependsOn(Hierarchy hierarchy) {
return anyDependsButFirst(getCalcs(), hierarchy);
}
private boolean hasHighCardDimension(TupleList l) {
final List<Member> trial = l.get(0);
for (Member m : trial) {
if (m.getHierarchy().getDimension().isHighCardinality()) {
return true;
}
}
return false;
}
};
}
use of mondrian.calc.impl.AbstractListCalc in project mondrian by pentaho.
the class ExtractFunDef method compileCall.
public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
List<Hierarchy> extractedHierarchyList = new ArrayList<Hierarchy>();
List<Integer> extractedOrdinalList = new ArrayList<Integer>();
findExtractedHierarchies(call.getArgs(), extractedHierarchyList, extractedOrdinalList);
Util.assertTrue(extractedOrdinalList.size() == extractedHierarchyList.size());
Exp arg = call.getArg(0);
final ListCalc listCalc = compiler.compileList(arg, false);
int inArity = arg.getType().getArity();
final int outArity = extractedOrdinalList.size();
if (inArity == 1) {
// LHS is a set of members, RHS is the same hierarchy. Extract boils
// down to eliminating duplicate members.
Util.assertTrue(outArity == 1);
return new DistinctFunDef.CalcImpl(call, listCalc);
}
final int[] extractedOrdinals = toIntArray(extractedOrdinalList);
return new AbstractListCalc(call, new Calc[] { listCalc }) {
public TupleList evaluateList(Evaluator evaluator) {
TupleList result = TupleCollections.createList(outArity);
TupleList list = listCalc.evaluateList(evaluator);
Set<List<Member>> emittedTuples = new HashSet<List<Member>>();
for (List<Member> members : list.project(extractedOrdinals)) {
if (emittedTuples.add(members)) {
result.add(members);
}
}
return result;
}
};
}
use of mondrian.calc.impl.AbstractListCalc in project mondrian by pentaho.
the class LastPeriodsFunDef method compileCall.
public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
// Member defaults to [Time].currentmember
Exp[] args = call.getArgs();
final MemberCalc memberCalc;
if (args.length == 1) {
final RolapHierarchy timeHierarchy = ((RolapCube) compiler.getEvaluator().getCube()).getTimeHierarchy(getName());
memberCalc = new HierarchyCurrentMemberFunDef.FixedCalcImpl(call, timeHierarchy);
} else {
memberCalc = compiler.compileMember(args[1]);
}
// Numeric Expression.
final IntegerCalc indexValueCalc = compiler.compileInteger(args[0]);
return new AbstractListCalc(call, new Calc[] { memberCalc, indexValueCalc }) {
public TupleList evaluateList(Evaluator evaluator) {
Member member = memberCalc.evaluateMember(evaluator);
int indexValue = indexValueCalc.evaluateInteger(evaluator);
return new UnaryTupleList(lastPeriods(member, evaluator, indexValue));
}
};
}
Aggregations