/** * Creates a WritebackCell. * * @param cube Cube * @param members Members that form context * @param constrainedColumnsBitKey Bitmap of columns which have values * @param keyValues List of values, by bit position * @param newValue New value * @param currentValue Current value * @param allocationPolicy Allocation policy */ WritebackCell( RolapCube cube, List<RolapMember> members, BitKey constrainedColumnsBitKey, Object[] keyValues, double newValue, double currentValue, AllocationPolicy allocationPolicy) { assert keyValues.length == constrainedColumnsBitKey.cardinality(); Util.discard(cube); // not used currently Util.discard(constrainedColumnsBitKey); // not used currently Util.discard(keyValues); // not used currently this.newValue = newValue; this.currentValue = currentValue; this.allocationPolicy = allocationPolicy; this.atomicCellCount = computeAtomicCellCount(cube, members); // Build the array of members by ordinal. If a member is not // specified for a particular dimension, use the 'all' member (not // necessarily the same as the default member). final List<RolapHierarchy> hierarchyList = cube.getHierarchies(); this.membersByOrdinal = new Member[hierarchyList.size()]; for (int i = 0; i < membersByOrdinal.length; i++) { membersByOrdinal[i] = hierarchyList.get(i).getDefaultMember(); } for (RolapMember member : members) { final RolapHierarchy hierarchy = member.getHierarchy(); if (isScenario(hierarchy)) { assert member.isAll(); } // REVIEW The following works because Measures is the only // dimension whose members do not belong to RolapCubeDimension, // just a regular RolapDimension, but has ordinal 0. final int ordinal = hierarchy.getOrdinalInCube(); membersByOrdinal[ordinal] = member; } }
/** * Sets the value of a cell. * * @param connection Connection (not currently used) * @param members Coordinates of cell * @param newValue New value * @param currentValue Current value * @param allocationPolicy Allocation policy * @param allocationArgs Additional arguments of allocation policy */ public void setCellValue( Connection connection, List<RolapMember> members, double newValue, double currentValue, AllocationPolicy allocationPolicy, Object[] allocationArgs) { Util.discard(connection); // for future use assert allocationPolicy != null; assert allocationArgs != null; switch (allocationPolicy) { case EQUAL_ALLOCATION: case EQUAL_INCREMENT: if (allocationArgs.length != 0) { throw Util.newError( "Allocation policy " + allocationPolicy + " takes 0 arguments; " + allocationArgs.length + " were supplied"); } break; default: throw Util.newError("Allocation policy " + allocationPolicy + " is not supported"); } // Compute the set of columns which are constrained by the cell's // coordinates. // // NOTE: This code is very similar to code in // RolapAggregationManager.makeCellRequest. Consider creating a // CellRequest then mining it. It will work better in the presence of // calculated members, compound members, parent-child hierarchies, // hierarchies whose default member is not the 'all' member, and so // forth. final RolapStoredMeasure measure = (RolapStoredMeasure) members.get(0); final RolapCube baseCube = measure.getCube(); final RolapStar.Measure starMeasure = (RolapStar.Measure) measure.getStarMeasure(); assert starMeasure != null; int starColumnCount = starMeasure.getStar().getColumnCount(); final BitKey constrainedColumnsBitKey = BitKey.Factory.makeBitKey(starColumnCount); Object[] keyValues = new Object[starColumnCount]; for (int i = 1; i < members.size(); i++) { Member member = members.get(i); for (RolapCubeMember m = (RolapCubeMember) member; m != null && !m.isAll(); m = m.getParentMember()) { final RolapCubeLevel level = m.getLevel(); RolapStar.Column column = level.getBaseStarKeyColumn(baseCube); if (column != null) { final int bitPos = column.getBitPosition(); keyValues[bitPos] = m.getKey(); constrainedColumnsBitKey.set(bitPos); } if (level.areMembersUnique()) { break; } } } // Squish the values down. We want the compactKeyValues[i] to correspond // to the i'th set bit in the key. This is the same format used by // CellRequest. Object[] compactKeyValues = new Object[constrainedColumnsBitKey.cardinality()]; int k = 0; for (int bitPos : constrainedColumnsBitKey) { compactKeyValues[k++] = keyValues[bitPos]; } // Record the override. // // TODO: add a mechanism for persisting the overrides to a file. // // FIXME: make thread-safe writebackCells.add( new WritebackCell( baseCube, new ArrayList<RolapMember>(members), constrainedColumnsBitKey, compactKeyValues, newValue, currentValue, allocationPolicy)); }