Search in sources :

Example 1 with NativeEvaluator

use of mondrian.olap.NativeEvaluator 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;
        }
    };
}
Also used : AbstractList(java.util.AbstractList) SchemaReader(mondrian.olap.SchemaReader) AbstractListCalc(mondrian.calc.impl.AbstractListCalc) Calc(mondrian.calc.Calc) IntegerCalc(mondrian.calc.IntegerCalc) AbstractListCalc(mondrian.calc.impl.AbstractListCalc) ListCalc(mondrian.calc.ListCalc) Evaluator(mondrian.olap.Evaluator) NativeEvaluator(mondrian.olap.NativeEvaluator) DelegatingTupleList(mondrian.calc.impl.DelegatingTupleList) UnaryTupleList(mondrian.calc.impl.UnaryTupleList) TupleList(mondrian.calc.TupleList) Hierarchy(mondrian.olap.Hierarchy) UnaryTupleList(mondrian.calc.impl.UnaryTupleList) IntegerCalc(mondrian.calc.IntegerCalc) AbstractListCalc(mondrian.calc.impl.AbstractListCalc) ListCalc(mondrian.calc.ListCalc) DelegatingTupleList(mondrian.calc.impl.DelegatingTupleList) AbstractList(java.util.AbstractList) UnaryTupleList(mondrian.calc.impl.UnaryTupleList) TupleList(mondrian.calc.TupleList) List(java.util.List) Member(mondrian.olap.Member) NativeEvaluator(mondrian.olap.NativeEvaluator) DelegatingTupleList(mondrian.calc.impl.DelegatingTupleList)

Example 2 with NativeEvaluator

use of mondrian.olap.NativeEvaluator 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);
        }
    };
}
Also used : ValueCalc(mondrian.calc.impl.ValueCalc) SchemaReader(mondrian.olap.SchemaReader) ScalarType(mondrian.olap.type.ScalarType) ArrayList(java.util.ArrayList) AbstractListCalc(mondrian.calc.impl.AbstractListCalc) Calc(mondrian.calc.Calc) LevelCalc(mondrian.calc.LevelCalc) IntegerCalc(mondrian.calc.IntegerCalc) AbstractListCalc(mondrian.calc.impl.AbstractListCalc) ListCalc(mondrian.calc.ListCalc) ValueCalc(mondrian.calc.impl.ValueCalc) LevelCalc(mondrian.calc.LevelCalc) Evaluator(mondrian.olap.Evaluator) NativeEvaluator(mondrian.olap.NativeEvaluator) UnaryTupleList(mondrian.calc.impl.UnaryTupleList) TupleList(mondrian.calc.TupleList) Hierarchy(mondrian.olap.Hierarchy) UnaryTupleList(mondrian.calc.impl.UnaryTupleList) IntegerCalc(mondrian.calc.IntegerCalc) AbstractListCalc(mondrian.calc.impl.AbstractListCalc) ListCalc(mondrian.calc.ListCalc) DummyExp(mondrian.calc.DummyExp) Level(mondrian.olap.Level) Member(mondrian.olap.Member) NativeEvaluator(mondrian.olap.NativeEvaluator)

Example 3 with NativeEvaluator

use of mondrian.olap.NativeEvaluator in project mondrian by pentaho.

the class RolapNativeRegistry method createEvaluator.

/**
 * Returns the matching NativeEvaluator or null if <code>fun</code> can not
 * be executed in SQL for the given context and arguments.
 */
public NativeEvaluator createEvaluator(RolapEvaluator evaluator, FunDef fun, Exp[] args) {
    if (!isEnabled()) {
        return null;
    }
    RolapNative rn = null;
    readLock.lock();
    try {
        rn = nativeEvaluatorMap.get(fun.getName().toUpperCase());
    } finally {
        readLock.unlock();
    }
    if (rn == null) {
        return null;
    }
    NativeEvaluator ne = rn.createEvaluator(evaluator, fun, args);
    if (ne != null) {
        if (listener != null) {
            NativeEvent e = new NativeEvent(this, ne);
            listener.foundEvaluator(e);
        }
    }
    return ne;
}
Also used : NativeEvaluator(mondrian.olap.NativeEvaluator)

Aggregations

NativeEvaluator (mondrian.olap.NativeEvaluator)3 Calc (mondrian.calc.Calc)2 IntegerCalc (mondrian.calc.IntegerCalc)2 ListCalc (mondrian.calc.ListCalc)2 TupleList (mondrian.calc.TupleList)2 AbstractListCalc (mondrian.calc.impl.AbstractListCalc)2 UnaryTupleList (mondrian.calc.impl.UnaryTupleList)2 Evaluator (mondrian.olap.Evaluator)2 Hierarchy (mondrian.olap.Hierarchy)2 Member (mondrian.olap.Member)2 SchemaReader (mondrian.olap.SchemaReader)2 AbstractList (java.util.AbstractList)1 ArrayList (java.util.ArrayList)1 List (java.util.List)1 DummyExp (mondrian.calc.DummyExp)1 LevelCalc (mondrian.calc.LevelCalc)1 DelegatingTupleList (mondrian.calc.impl.DelegatingTupleList)1 ValueCalc (mondrian.calc.impl.ValueCalc)1 Level (mondrian.olap.Level)1 ScalarType (mondrian.olap.type.ScalarType)1