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-2012 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.*; 018 019/** 020 * A <code>SparseSegmentDataset</code> is a means of storing segment values 021 * which is suitable when few of the combinations of keys have a value present. 022 * 023 * <p>The storage requirements are as follows. Key is 1 word for each 024 * dimension. Hashtable entry is 3 words. Value is 1 word. Total space is (4 + 025 * d) * v. (May also need hash table to ensure that values are only stored 026 * once.)</p> 027 * 028 * <p>NOTE: This class is not synchronized.</p> 029 * 030 * @author jhyde 031 * @since 21 March, 2002 032 */ 033class SparseSegmentDataset implements SegmentDataset { 034 private final Map<CellKey, Object> values; 035 036 /** 037 * Creates an empty SparseSegmentDataset. 038 */ 039 SparseSegmentDataset() { 040 this(new HashMap<CellKey, Object>()); 041 } 042 043 /** 044 * Creates a SparseSegmentDataset with a given value map. The map is not 045 * copied; a reference to the map is retained inside the dataset, and 046 * therefore the contents of the dataset will change if the map is modified. 047 * 048 * @param values Value map 049 */ 050 SparseSegmentDataset(Map<CellKey, Object> values) { 051 this.values = values; 052 } 053 054 public Object getObject(CellKey pos) { 055 return values.get(pos); 056 } 057 058 public boolean isNull(CellKey pos) { 059 // cf exists -- calls values.containsKey 060 return values.get(pos) == null; 061 } 062 063 public int getInt(CellKey pos) { 064 throw new UnsupportedOperationException(); 065 } 066 067 public double getDouble(CellKey pos) { 068 throw new UnsupportedOperationException(); 069 } 070 071 public boolean exists(CellKey pos) { 072 return values.containsKey(pos); 073 } 074 075 public void put(CellKey key, Object value) { 076 values.put(key, value); 077 } 078 079 public Iterator<Map.Entry<CellKey, Object>> iterator() { 080 return values.entrySet().iterator(); 081 } 082 083 public double getBytes() { 084 // assume a slot, key, and value are each 4 bytes 085 return values.size() * 12; 086 } 087 088 public void populateFrom(int[] pos, SegmentDataset data, CellKey key) { 089 values.put(CellKey.Generator.newCellKey(pos), data.getObject(key)); 090 } 091 092 public void populateFrom( 093 int[] pos, SegmentLoader.RowList rowList, int column) 094 { 095 final Object o = rowList.getObject(column); 096 put(CellKey.Generator.newCellKey(pos), o); 097 } 098 099 public SqlStatement.Type getType() { 100 return SqlStatement.Type.OBJECT; 101 } 102 103 public SegmentBody createSegmentBody( 104 List<Pair<SortedSet<Comparable>, Boolean>> axes) 105 { 106 return new SparseSegmentBody( 107 values, 108 axes); 109 } 110} 111 112// End SparseSegmentDataset.java