Package mondrian.olap.fun

Source Code of mondrian.olap.fun.HeadTailFunDef

/*
// $Id: //open/mondrian-release/3.2/src/main/mondrian/olap/fun/HeadTailFunDef.java#2 $
// This software is subject to the terms of the Eclipse Public License v1.0
// Agreement, available at the following URL:
// http://www.eclipse.org/legal/epl-v10.html.
// Copyright (C) 2006-2009 Julian Hyde
// All Rights Reserved.
// You must accept the terms of that agreement to use this software.
*/
package mondrian.olap.fun;

import mondrian.calc.*;
import mondrian.calc.impl.AbstractListCalc;
import mondrian.calc.impl.ConstantCalc;
import mondrian.mdx.ResolvedFunCall;
import mondrian.olap.Evaluator;
import mondrian.olap.FunDef;
import mondrian.util.UnsupportedList;

import java.util.*;

/**
* Definition of the <code>Head</code> and <code>Tail</code>
* MDX builtin functions.
*
* @author jhyde
* @version $Id: //open/mondrian-release/3.2/src/main/mondrian/olap/fun/HeadTailFunDef.java#2 $
* @since Mar 23, 2006
*/
class HeadTailFunDef extends FunDefBase {
    static final Resolver TailResolver = new ReflectiveMultiResolver(
            "Tail",
            "Tail(<Set>[, <Count>])",
            "Returns a subset from the end of a set.",
            new String[] {"fxx", "fxxn"},
            HeadTailFunDef.class);

    static final Resolver HeadResolver = new ReflectiveMultiResolver(
            "Head",
            "Head(<Set>[, < Numeric Expression >])",
            "Returns the first specified number of elements in a set.",
            new String[] {"fxx", "fxxn"},
            HeadTailFunDef.class);

    private final boolean head;

    public HeadTailFunDef(FunDef dummyFunDef) {
        super(dummyFunDef);
        head = dummyFunDef.getName().equals("Head");
    }

    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 List evaluateList(Evaluator evaluator) {
                    evaluator = evaluator.push(false);
                    List list = listCalc.evaluateList(evaluator);
                    int count = integerCalc.evaluateInteger(evaluator);
                    return head(count, list);
                }
            };
        } else {
            return new AbstractListCalc(
                call, new Calc[] {listCalc, integerCalc})
            {
                public List evaluateList(Evaluator evaluator) {
                    evaluator = evaluator.push(false);
                    List list = listCalc.evaluateList(evaluator);
                    int count = integerCalc.evaluateInteger(evaluator);
                    return tail(count, list);
                }
            };
        }
    }

    static <T> List<T> tail(final int count, final List<T> members) {
        assert members != null;
        final int memberCount = members.size();
        if (count >= memberCount) {
            return members;
        }
        if (count <= 0) {
            return Collections.emptyList();
        }
        return new UnsupportedList<T>() {
            public boolean isEmpty() {
                return count == 0 || members.isEmpty();
            }

            public int size() {
                return Math.min(count, members.size());
            }

            public T get(final int idx) {
                final int index = idx + memberCount - count;
                return members.get(index);
            }

            public Iterator<T> iterator() {
                return new Itr();
            }

            public Object[] toArray() {
                final int offset = memberCount - count;
                final Object[] a = new Object[size()];
                for (int i = memberCount - count; i < memberCount; i++) {
                    a[i - offset] = members.get(i);
                }
                return a;
            }
        };
    }

    static <T> List<T> head(final int count, final List<T> members) {
        assert members != null;
        if (count <= 0) {
            return Collections.emptyList();
        }
        return new UnsupportedList<T>() {
            public boolean isEmpty() {
                return count == 0 || members.isEmpty();
            }

            public int size() {
                return Math.min(count, members.size());
            }

            public T get(final int index) {
                if (index >= count) {
                    throw new IndexOutOfBoundsException();
                }
                return members.get(index);
            }

            public Iterator<T> iterator() {
                return new Itr();
            }

            public Object[] toArray() {
                Object[] a = new Object[count];
                int i = 0;
                for (Object member : members) {
                    if (i >= a.length) {
                        return a;
                    }
                    a[i++] = member;
                }
                if (i < a.length) {
                    Object[] a0 = a;
                    a = new Object[i];
                    System.arraycopy(a0, 0, a, 0, i);
                }
                return a;
            }
        };
    }
}

// End HeadTailFunDef.java
TOP

Related Classes of mondrian.olap.fun.HeadTailFunDef

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.