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 012 013import mondrian.olap.Util; 014import mondrian.rolap.CellKey; 015import mondrian.rolap.SqlStatement; 016import mondrian.spi.SegmentBody; 017import mondrian.util.Pair; 018 019import java.util.*; 020 021/** 022 * Implementation of {@link mondrian.rolap.agg.DenseSegmentDataset} that stores 023 * values of type {@code double}. 024 * 025 * @author jhyde 026 */ 027class DenseDoubleSegmentDataset extends DenseNativeSegmentDataset { 028 final double[] values; // length == m[0] * ... * m[axes.length-1] 029 030 /** 031 * Creates a DenseDoubleSegmentDataset. 032 * 033 * @param axes Segment axes, containing actual column values 034 * @param size Number of coordinates 035 */ 036 DenseDoubleSegmentDataset(SegmentAxis[] axes, int size) { 037 this(axes, new double[size], Util.bitSetBetween(0, size)); 038 } 039 040 /** 041 * Creates a populated DenseDoubleSegmentDataset. 042 * 043 * @param axes Segment axes, containing actual column values 044 * @param values Cell values; not copied 045 * @param nullIndicators Null indicators 046 */ 047 DenseDoubleSegmentDataset( 048 SegmentAxis[] axes, double[] values, BitSet nullIndicators) 049 { 050 super(axes, nullIndicators); 051 this.values = values; 052 } 053 054 public double getDouble(CellKey key) { 055 int offset = key.getOffset(axisMultipliers); 056 return values[offset]; 057 } 058 059 public Object getObject(CellKey pos) { 060 if (values.length == 0) { 061 // No values means they are all null. 062 // We can't call isNull because we risk going into a SOE. Besides, 063 // this is a tight loop and we can skip over one VFC. 064 return null; 065 } 066 int offset = pos.getOffset(axisMultipliers); 067 return getObject(offset); 068 } 069 070 public Double getObject(int offset) { 071 final double value = values[offset]; 072 if (value == 0 && isNull(offset)) { 073 return null; 074 } 075 return value; 076 } 077 078 public boolean exists(CellKey pos) { 079 return true; 080 } 081 082 public void populateFrom(int[] pos, SegmentDataset data, CellKey key) { 083 final int offset = getOffset(pos); 084 final double value = values[offset] = data.getDouble(key); 085 if (value != 0d || !data.isNull(key)) { 086 nullValues.clear(offset); 087 } 088 } 089 090 public void populateFrom( 091 int[] pos, SegmentLoader.RowList rowList, int column) 092 { 093 final int offset = getOffset(pos); 094 final double value = values[offset] = rowList.getDouble(column); 095 if (value != 0d || !rowList.isNull(column)) { 096 nullValues.clear(offset); 097 } 098 } 099 100 public SqlStatement.Type getType() { 101 return SqlStatement.Type.DOUBLE; 102 } 103 104 void set(int k, double d) { 105 values[k] = d; 106 } 107 108 protected int getSize() { 109 return values.length; 110 } 111 112 public SegmentBody createSegmentBody( 113 List<Pair<SortedSet<Comparable>, Boolean>> axes) 114 { 115 return new DenseDoubleSegmentBody( 116 nullValues, 117 values, 118 axes); 119 } 120} 121 122// End DenseDoubleSegmentDataset.java