Search in sources :

Example 6 with TupleCursor

use of mondrian.calc.TupleCursor in project mondrian by pentaho.

the class RolapNamedSetEvaluator method ensureList.

/**
 * Evaluates and saves the value of this named set, if it has not been evaluated already.
 */
private void ensureList(Evaluator evaluator) {
    if (list != null) {
        if (list == DUMMY_LIST) {
            recursionCount++;
            if (RECURSION_TOLERANCE > 0 && recursionCount > RECURSION_TOLERANCE) {
                throw rrer.result.slicerEvaluator.newEvalException(null, "Illegal attempt to reference value of named set '" + namedSet.getName() + "' while evaluating itself");
            }
        }
        return;
    }
    if (RolapResult.LOGGER.isDebugEnabled()) {
        RolapResult.LOGGER.debug("Named set " + namedSet.getName() + ": starting evaluation");
    }
    // recursion detection
    list = DUMMY_LIST;
    try {
        final Calc calc = rrer.getCompiled(namedSet.getExp(), false, ResultStyle.ITERABLE);
        TupleIterable iterable = (TupleIterable) rrer.result.evaluateExp(calc, rrer.result.slicerEvaluator, evaluator);
        // Axes can be in two forms: list or iterable. If iterable, we
        // need to materialize it, to ensure that all cell values are in
        // cache.
        final TupleList rawList;
        if (iterable instanceof TupleList) {
            rawList = (TupleList) iterable;
        } else {
            rawList = TupleCollections.createList(iterable.getArity());
            TupleCursor cursor = iterable.tupleCursor();
            while (cursor.forward()) {
                rawList.addCurrent(cursor);
            }
        }
        if (RolapResult.LOGGER.isDebugEnabled()) {
            RolapResult.LOGGER.debug(generateDebugMessage(calc, rawList));
        }
        // NamedSets are not supposed to depend on the current evaluation context but the
        // way NamedSet evaluation was implemented in Mondrian, they could...
        // So as a result, the nameset calc has to be profiled at the time of use instead
        // of on close of the statement.
        Util.explain(rrer.statement.getProfileHandler(), "NamedSet (" + namedSet.getName() + "):", calc, evaluator.getTiming());
        // Wrap list so that currentOrdinal is updated whenever the list
        // is accessed. The list is immutable, because we don't override
        // AbstractList.set(int, Object).
        this.list = rawList.withPositionCallback(this);
    } finally {
        if (this.list == DUMMY_LIST) {
            this.list = null;
        }
        recursionCount = 0;
    }
}
Also used : TupleList(mondrian.calc.TupleList) TupleIterable(mondrian.calc.TupleIterable) TupleCursor(mondrian.calc.TupleCursor) Calc(mondrian.calc.Calc)

Example 7 with TupleCursor

use of mondrian.calc.TupleCursor in project mondrian by pentaho.

the class Sorter method sortTuples.

/**
 * Sorts a list of Tuples by the value of an applied expression. Stable sort.
 *
 * <p>Helper function for MDX functions TopCount, TopSum, TopPercent,
 * BottomCount, BottomSum, BottomPercent, but not the MDX function Order.
 *
 * <p>NOTE: This function does not preserve the contents of the validator.
 *
 * <p>If you specify {@code tupleList}, the list is sorted in place, and
 * tupleList is returned.
 *
 * @param evaluator     Evaluator
 * @param tupleIterable Iterator over tuples
 * @param tupleList     List of tuples, if known, otherwise null
 * @param exp           Expression to sort on
 * @param desc          Whether to sort descending
 * @param brk           Whether to break
 * @param arity         Number of members in each tuple
 * @return sorted list (never null)
 */
public static TupleList sortTuples(Evaluator evaluator, TupleIterable tupleIterable, TupleList tupleList, Calc exp, boolean desc, boolean brk, int arity) {
    // NOTE: This method does not implement the iterable/list concept
    // as fully as sortMembers. This is because sortMembers evaluates all
    // sort expressions up front. There, it is efficient to unravel the
    // iterator and evaluate the sort expressions at the same time.
    List<List<Member>> tupleArrayList;
    if (tupleList == null) {
        final TupleCursor cursor = tupleIterable.tupleCursor();
        tupleArrayList = iterableToList(evaluator, cursor);
        if (tupleArrayList.size() <= 1) {
            return new DelegatingTupleList(tupleIterable.getArity(), tupleArrayList);
        }
    } else {
        if (tupleList.size() <= 1) {
            return tupleList;
        }
        tupleArrayList = tupleList;
    }
    @SuppressWarnings({ "unchecked" }) List<Member>[] tuples = tupleArrayList.toArray(new List[tupleArrayList.size()]);
    final DelegatingTupleList result = new DelegatingTupleList(tupleIterable.getArity(), Arrays.asList(tuples));
    Comparator<List<Member>> comparator;
    if (brk) {
        comparator = new TupleExpMemoComparator.BreakTupleComparator(evaluator, exp, arity);
        if (desc) {
            comparator = Collections.reverseOrder(comparator);
        }
    } else {
        comparator = new HierarchicalTupleComparator(evaluator, exp, arity, desc);
    }
    Arrays.sort(tuples, comparator);
    logTuples(tupleList, "Sorter.sortTuples");
    return result;
}
Also used : TupleCursor(mondrian.calc.TupleCursor) AbstractList(java.util.AbstractList) ArrayList(java.util.ArrayList) DelegatingTupleList(mondrian.calc.impl.DelegatingTupleList) TupleList(mondrian.calc.TupleList) List(java.util.List) DelegatingTupleList(mondrian.calc.impl.DelegatingTupleList)

Example 8 with TupleCursor

use of mondrian.calc.TupleCursor in project mondrian by pentaho.

the class FunUtil method count.

public static int count(Evaluator evaluator, TupleIterable iterable, boolean includeEmpty) {
    if (iterable == null) {
        return 0;
    }
    if (includeEmpty) {
        if (iterable instanceof TupleList) {
            return ((TupleList) iterable).size();
        } else {
            int retval = 0;
            TupleCursor cursor = iterable.tupleCursor();
            while (cursor.forward()) {
                retval++;
            }
            return retval;
        }
    } else {
        int retval = 0;
        TupleCursor cursor = iterable.tupleCursor();
        while (cursor.forward()) {
            cursor.setContext(evaluator);
            if (!evaluator.currentIsEmpty()) {
                retval++;
            }
        }
        return retval;
    }
}
Also used : UnaryTupleList(mondrian.calc.impl.UnaryTupleList) Sorter.hierarchizeTupleList(mondrian.olap.fun.sort.Sorter.hierarchizeTupleList) TupleList(mondrian.calc.TupleList) TupleCursor(mondrian.calc.TupleCursor)

Example 9 with TupleCursor

use of mondrian.calc.TupleCursor in project mondrian by pentaho.

the class FunUtil method evaluateSet.

/**
 * Evaluates {@code exp} (if defined) over {@code members} to generate a {@link List} of {@link SetWrapper} objects,
 * which contains a {@link Double} value and meta information, unlike {@link #evaluateMembers}, which only produces
 * values.
 *
 * @pre exp != null
 */
static SetWrapper evaluateSet(Evaluator evaluator, TupleIterable members, Calc calc) {
    assert members != null;
    assert calc != null;
    assert calc.getType() instanceof ScalarType;
    // todo: treat constant exps as evaluateMembers() does
    SetWrapper retval = new SetWrapper();
    final TupleCursor cursor = members.tupleCursor();
    int currentIteration = 0;
    Execution execution = evaluator.getQuery().getStatement().getCurrentExecution();
    while (cursor.forward()) {
        CancellationChecker.checkCancelOrTimeout(currentIteration++, execution);
        cursor.setContext(evaluator);
        Object o = calc.evaluate(evaluator);
        if (o == null || o == Util.nullValue) {
            retval.nullCount++;
        } else if (o == RolapUtil.valueNotReadyException) {
            // Carry on summing, so that if we are running in a
            // BatchingCellReader, we find out all the dependent cells we
            // need
            retval.errorCount++;
        } else if (o instanceof Number) {
            retval.v.add(((Number) o).doubleValue());
        } else {
            retval.v.add(o);
        }
    }
    return retval;
}
Also used : Execution(mondrian.server.Execution) TupleCursor(mondrian.calc.TupleCursor) ScalarType(mondrian.olap.type.ScalarType)

Example 10 with TupleCursor

use of mondrian.calc.TupleCursor in project mondrian by pentaho.

the class RolapResult method evaluateExp.

/**
 * Evaluates an expression. Intended for evaluating named sets.
 *
 * <p>
 * Does not modify the contents of the evaluator.
 *
 * @param calc
 *          Compiled expression
 * @param slicerEvaluator
 *          Evaluation context for slicers
 * @param contextEvaluator
 *          Evaluation context (optional)
 * @return Result
 */
Object evaluateExp(Calc calc, RolapEvaluator slicerEvaluator, Evaluator contextEvaluator) {
    int attempt = 0;
    RolapEvaluator evaluator = slicerEvaluator.push();
    if (contextEvaluator != null && contextEvaluator.isEvalAxes()) {
        evaluator.setEvalAxes(true);
    }
    final int savepoint = evaluator.savepoint();
    boolean dirty = batchingReader.isDirty();
    try {
        while (true) {
            evaluator.restore(savepoint);
            evaluator.setCellReader(batchingReader);
            Object preliminaryValue = calc.evaluate(evaluator);
            if (preliminaryValue instanceof TupleIterable) {
                // During the preliminary phase, we have to materialize the
                // tuple lists or the evaluation lower down won't take into
                // account all the tuples.
                TupleIterable iterable = (TupleIterable) preliminaryValue;
                final TupleCursor cursor = iterable.tupleCursor();
                while (cursor.forward()) {
                // ignore
                }
            }
            if (!phase()) {
                break;
            } else {
                // Clear invalid expression result so that the next
                // evaluation will pick up the newly loaded aggregates.
                evaluator.clearExpResultCache(false);
            }
            if (attempt++ > maxEvalDepth) {
                throw Util.newInternal("Failed to load all aggregations after " + maxEvalDepth + "passes; there's probably a cycle");
            }
        }
        // re-evaluate them.
        if (dirty) {
            batchingReader.setDirty(true);
        }
        evaluator.restore(savepoint);
        evaluator.setCellReader(aggregatingReader);
        final Object o = calc.evaluate(evaluator);
        return o;
    } finally {
        evaluator.restore(savepoint);
    }
}
Also used : TupleIterable(mondrian.calc.TupleIterable) TupleCursor(mondrian.calc.TupleCursor)

Aggregations

TupleCursor (mondrian.calc.TupleCursor)10 TupleList (mondrian.calc.TupleList)7 DelegatingTupleList (mondrian.calc.impl.DelegatingTupleList)5 ListTupleList (mondrian.calc.impl.ListTupleList)4 Execution (mondrian.server.Execution)4 ArrayList (java.util.ArrayList)3 TupleIterable (mondrian.calc.TupleIterable)3 Member (mondrian.olap.Member)3 List (java.util.List)2 AbstractTupleCursor (mondrian.calc.impl.AbstractTupleCursor)2 Hierarchy (mondrian.olap.Hierarchy)2 VisualTotalMember (mondrian.olap.fun.VisualTotalsFunDef.VisualTotalMember)2 AbstractList (java.util.AbstractList)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 Locale (java.util.Locale)1 Set (java.util.Set)1 Calc (mondrian.calc.Calc)1 DoubleCalc (mondrian.calc.DoubleCalc)1 DummyExp (mondrian.calc.DummyExp)1