001/*
002// This software is subject to the terms of the Eclipse Public License v1.0
003// Agreement, available at the following URL:
004// http://www.eclipse.org/legal/epl-v10.html.
005// You must accept the terms of that agreement to use this software.
006//
007// Copyright (C) 2010-2013 Pentaho and others
008// All Rights Reserved.
009*/
010package mondrian.rolap.agg;
011
012import mondrian.rolap.CellKey;
013import mondrian.rolap.SqlStatement;
014import mondrian.spi.SegmentBody;
015import mondrian.util.Pair;
016
017import java.util.List;
018import java.util.SortedSet;
019
020/**
021 * Implementation of {@link mondrian.rolap.agg.DenseSegmentDataset} that stores
022 * values of type {@link Object}.
023 *
024 * <p>The storage requirements are as follows. Table requires 1 word per
025 * cell.</p>
026 *
027 * @author jhyde
028 * @since 21 March, 2002
029 */
030class DenseObjectSegmentDataset extends DenseSegmentDataset {
031    final Object[] values; // length == m[0] * ... * m[axes.length-1]
032
033    /**
034     * Creates a DenseSegmentDataset.
035     *
036     * @param axes Segment axes, containing actual column values
037     * @param size Number of coordinates
038     */
039    DenseObjectSegmentDataset(SegmentAxis[] axes, int size) {
040        this(axes, new Object[size]);
041    }
042
043    /**
044     * Creates and populates a DenseSegmentDataset. The data set is not copied.
045     *
046     * @param axes Axes
047     * @param values Data set
048     */
049    DenseObjectSegmentDataset(SegmentAxis[] axes, Object[] values) {
050        super(axes);
051        this.values = values;
052    }
053
054    public Object getObject(CellKey key) {
055        if (values.length == 0) {
056            // No values means they are all null.
057            // We can't call isNull because we risk going into a SOE. Besides,
058            // this is a tight loop and we can skip over one VFC.
059            return null;
060        }
061        int offset = key.getOffset(axisMultipliers);
062        return values[offset];
063    }
064
065    public boolean isNull(CellKey pos) {
066        if (values.length == 0) {
067            // No values means they are all null.
068            return true;
069        }
070        return getObject(pos) != null;
071    }
072
073    public boolean exists(CellKey pos) {
074        return getObject(pos) != null;
075    }
076
077    public void populateFrom(int[] pos, SegmentDataset data, CellKey key) {
078        values[getOffset(pos)] = data.getObject(key);
079    }
080
081    public void populateFrom(
082        int[] pos, SegmentLoader.RowList rowList, int column)
083    {
084        int offset = getOffset(pos);
085        values[offset] = rowList.getObject(column);
086    }
087
088    public SqlStatement.Type getType() {
089        return SqlStatement.Type.OBJECT;
090    }
091
092    public void put(CellKey key, Object value) {
093        int offset = key.getOffset(axisMultipliers);
094        values[offset] = value;
095    }
096
097    protected Object getObject(int i) {
098        return values[i];
099    }
100
101    protected int getSize() {
102        return values.length;
103    }
104
105    public SegmentBody createSegmentBody(
106        List<Pair<SortedSet<Comparable>, Boolean>> axes)
107    {
108        return new DenseObjectSegmentBody(
109            values,
110            axes);
111    }
112}
113
114// End DenseObjectSegmentDataset.java