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