Search in sources :

Example 6 with AbstractListCalc

use of mondrian.calc.impl.AbstractListCalc in project mondrian by pentaho.

the class ToggleDrillStateFunDef method compileCall.

public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
    if (call.getArgCount() > 2) {
        throw MondrianResource.instance().ToggleDrillStateRecursiveNotSupported.ex();
    }
    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) {
            final TupleList list0 = listCalc0.evaluateList(evaluator);
            final TupleList list1 = listCalc1.evaluateList(evaluator);
            return toggleDrillStateTuples(evaluator, list0, list1);
        }
    };
}
Also used : AbstractListCalc(mondrian.calc.impl.AbstractListCalc) AbstractListCalc(mondrian.calc.impl.AbstractListCalc)

Example 7 with AbstractListCalc

use of mondrian.calc.impl.AbstractListCalc 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);
            }
        }
    };
}
Also used : StringCalc(mondrian.calc.StringCalc) HashMap(java.util.HashMap) AbstractListCalc(mondrian.calc.impl.AbstractListCalc) Evaluator(mondrian.olap.Evaluator) TupleCalc(mondrian.calc.TupleCalc) TupleList(mondrian.calc.TupleList) Hierarchy(mondrian.olap.Hierarchy) AbstractListCalc(mondrian.calc.impl.AbstractListCalc) ListCalc(mondrian.calc.ListCalc) Member(mondrian.olap.Member)

Example 8 with AbstractListCalc

use of mondrian.calc.impl.AbstractListCalc in project mondrian by pentaho.

the class SubsetFunDef method compileCall.

public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
    final ListCalc listCalc = compiler.compileList(call.getArg(0));
    final IntegerCalc startCalc = compiler.compileInteger(call.getArg(1));
    final IntegerCalc countCalc = call.getArgCount() > 2 ? compiler.compileInteger(call.getArg(2)) : null;
    return new AbstractListCalc(call, new Calc[] { listCalc, startCalc, countCalc }) {

        public TupleList evaluateList(Evaluator evaluator) {
            final int savepoint = evaluator.savepoint();
            try {
                evaluator.setNonEmpty(false);
                final TupleList list = listCalc.evaluateList(evaluator);
                final int start = startCalc.evaluateInteger(evaluator);
                int end;
                if (countCalc != null) {
                    final int count = countCalc.evaluateInteger(evaluator);
                    end = start + count;
                } else {
                    end = list.size();
                }
                if (end > list.size()) {
                    end = list.size();
                }
                if (start >= end || start < 0) {
                    return TupleCollections.emptyList(list.getArity());
                }
                if (start == 0 && end == list.size()) {
                    return list;
                }
                assert 0 <= start;
                assert start < end;
                assert end <= list.size();
                return list.subList(start, end);
            } finally {
                evaluator.restore(savepoint);
            }
        }
    };
}
Also used : AbstractListCalc(mondrian.calc.impl.AbstractListCalc) AbstractListCalc(mondrian.calc.impl.AbstractListCalc) Evaluator(mondrian.olap.Evaluator)

Example 9 with AbstractListCalc

use of mondrian.calc.impl.AbstractListCalc in project mondrian by pentaho.

the class HierarchizeFunDef method compileCall.

public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
    final ListCalc listCalc = compiler.compileList(call.getArg(0), true);
    String order = getLiteralArg(call, 1, "PRE", prePost);
    final boolean post = order.equals("POST");
    return new AbstractListCalc(call, new Calc[] { listCalc }) {

        public TupleList evaluateList(Evaluator evaluator) {
            TupleList list = listCalc.evaluateList(evaluator);
            return Sorter.hierarchizeTupleList(list, post);
        }
    };
}
Also used : TupleList(mondrian.calc.TupleList) AbstractListCalc(mondrian.calc.impl.AbstractListCalc) ListCalc(mondrian.calc.ListCalc) AbstractListCalc(mondrian.calc.impl.AbstractListCalc) Evaluator(mondrian.olap.Evaluator)

Example 10 with AbstractListCalc

use of mondrian.calc.impl.AbstractListCalc in project mondrian by pentaho.

the class IntersectFunDef method compileCall.

public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
    final String literalArg = getLiteralArg(call, 2, "", ReservedWords);
    final boolean all = literalArg.equalsIgnoreCase("ALL");
    final int arity = call.getType().getArity();
    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 leftList = listCalc1.evaluateList(evaluator);
            if (leftList.isEmpty()) {
                return leftList;
            }
            final TupleList rightList = listCalc2.evaluateList(evaluator);
            if (rightList.isEmpty()) {
                return rightList;
            }
            // Set of members from the right side of the intersect.
            // We use a RetrievableSet because distinct keys
            // (regular members and visual totals members) compare
            // identical using hashCode and equals, we want to retrieve
            // the actual key, and java.util.Set only has containsKey.
            RetrievableSet<List<Member>> rightSet = new RetrievableHashSet<List<Member>>(rightList.size() * 3 / 2);
            for (List<Member> tuple : rightList) {
                rightSet.add(tuple);
            }
            final TupleList result = TupleCollections.createList(arity, Math.min(leftList.size(), rightList.size()));
            final Set<List<Member>> resultSet = all ? null : new HashSet<List<Member>>();
            for (List<Member> leftTuple : leftList) {
                List<Member> rightKey = rightSet.getKey(leftTuple);
                if (rightKey == null) {
                    continue;
                }
                if (resultSet != null && !resultSet.add(leftTuple)) {
                    continue;
                }
                result.add(copyTupleWithVisualTotalsMembersOverriding(leftTuple, rightKey));
            }
            return result;
        }

        /**
         * Constructs a tuple consisting of members from
         * {@code leftTuple}, but overridden by any corresponding
         * members from {@code rightKey} that happen to be visual totals
         * members.
         *
         * <p>Returns the original tuple if there are no visual totals
         * members on the RHS.
         *
         * @param leftTuple Original tuple
         * @param rightKey Right tuple
         * @return Copy of original tuple, with any VisualTotalMembers
         *   from right tuple overriding
         */
        private List<Member> copyTupleWithVisualTotalsMembersOverriding(List<Member> leftTuple, List<Member> rightKey) {
            List<Member> tuple = leftTuple;
            for (int i = 0; i < rightKey.size(); i++) {
                Member member = rightKey.get(i);
                if (!(tuple.get(i) instanceof VisualTotalsFunDef.VisualTotalMember) && member instanceof VisualTotalsFunDef.VisualTotalMember) {
                    if (tuple == leftTuple) {
                        // clone on first VisualTotalMember -- to avoid
                        // alloc/copy in the common case where there are
                        // no VisualTotalMembers
                        tuple = new ArrayList<Member>(leftTuple);
                    }
                    tuple.set(i, member);
                }
            }
            return tuple;
        }
    };
}
Also used : AbstractListCalc(mondrian.calc.impl.AbstractListCalc) AbstractListCalc(mondrian.calc.impl.AbstractListCalc)

Aggregations

AbstractListCalc (mondrian.calc.impl.AbstractListCalc)21 Evaluator (mondrian.olap.Evaluator)9 TupleList (mondrian.calc.TupleList)7 UnaryTupleList (mondrian.calc.impl.UnaryTupleList)7 Hierarchy (mondrian.olap.Hierarchy)6 Member (mondrian.olap.Member)6 ArrayList (java.util.ArrayList)5 ListCalc (mondrian.calc.ListCalc)5 List (java.util.List)4 Calc (mondrian.calc.Calc)4 IntegerCalc (mondrian.calc.IntegerCalc)4 SchemaReader (mondrian.olap.SchemaReader)4 Type (mondrian.olap.type.Type)4 LevelCalc (mondrian.calc.LevelCalc)3 Level (mondrian.olap.Level)3 MemberCalc (mondrian.calc.MemberCalc)2 StringCalc (mondrian.calc.StringCalc)2 ValueCalc (mondrian.calc.impl.ValueCalc)2 ResolvedFunCall (mondrian.mdx.ResolvedFunCall)2 Exp (mondrian.olap.Exp)2