Program: 50914
Project: 50914
Buggy source:
/** 
 * Given a collection of segments, all of the same dimensionality, rolls up to create a segment with reduced dimensionality.
 * @param map Source segment headers and bodies
 * @param keepColumns A list of column names to keep as part ofthe rolled up segment.
 * @param targetBitkey The column bit key to match with theresulting segment.
 * @param rollupAggregator The aggregator to use to rollup.
 * @return Segment header and body of requested dimensionality
 */
public static Pair<SegmentHeader,SegmentBody> rollup(Map<SegmentHeader,SegmentBody> map,Set<String> keepColumns,BitKey targetBitkey,Aggregator rollupAggregator){
class AxisInfo {
    SegmentColumn column;
    SortedSet<Comparable> requestedValues;
    SortedSet<Comparable> valueSet;
    Comparable[] values;
    boolean hasNull;
    int src;
    boolean lostPredicate;
  }
  final SegmentHeader firstHeader=map.keySet().iterator().next();
  final AxisInfo[] axes=new AxisInfo[keepColumns.size()];
  int z=0, j=0;
  for (  SegmentColumn column : firstHeader.getConstrainedColumns()) {
    if (keepColumns.contains(column.columnExpression)) {
      final AxisInfo axisInfo=axes[z++]=new AxisInfo();
      axisInfo.src=j;
      axisInfo.column=column;
      axisInfo.requestedValues=column.values;
    }
    j++;
  }
  for (  Map.Entry<SegmentHeader,SegmentBody> entry : map.entrySet()) {
    final SegmentHeader header=entry.getKey();
    for (    AxisInfo axis : axes) {
      final SortedSet<Comparable> values=entry.getValue().getAxisValueSets()[axis.src];
      final SegmentColumn headerColumn=header.getConstrainedColumn(axis.column.columnExpression);
      final boolean hasNull=entry.getValue().getNullAxisFlags()[axis.src];
      final SortedSet<Comparable> requestedValues=headerColumn.getValues();
      if (axis.valueSet == null) {
        axis.valueSet=new TreeSet<Comparable>(values);
        axis.hasNull=hasNull;
        axis.requestedValues=requestedValues;
      }
 else {
        final SortedSet<Comparable> filteredValues;
        final boolean filteredHasNull;
        if (axis.requestedValues == null) {
          filteredValues=values;
          filteredHasNull=hasNull;
        }
 else {
          filteredValues=Util.intersect(values,axis.requestedValues);
          filteredHasNull=false;
        }
        axis.valueSet.addAll(filteredValues);
        axis.hasNull=axis.hasNull || filteredHasNull;
        if (!Util.equals(axis.requestedValues,requestedValues)) {
          if (axis.requestedValues == null) {
            axis.requestedValues=requestedValues;
          }
 else {
            axis.lostPredicate=true;
          }
        }
      }
    }
  }
  for (  AxisInfo axis : axes) {
    axis.values=axis.valueSet.toArray(new Comparable[axis.valueSet.size()]);
  }
  final Map<CellKey,List<Object>> cellValues=new HashMap<CellKey,List<Object>>();
  for (  Map.Entry<SegmentHeader,SegmentBody> entry : map.entrySet()) {
    final int[] pos=new int[axes.length];
    final Comparable[][] valueArrays=new Comparable[firstHeader.getConstrainedColumns().size()][];
    final SegmentBody body=entry.getValue();
    z=0;
    for (    SortedSet<Comparable> set : body.getAxisValueSets()) {
      valueArrays[z]=keepColumns.contains(firstHeader.getConstrainedColumns().get(z).columnExpression) ? set.toArray(new Comparable[set.size()]) : null;
      ++z;
    }
    Map<CellKey,Object> v=body.getValueMap();
    for (    Map.Entry<CellKey,Object> vEntry : v.entrySet()) {
      z=0;
      for (int i=0; i < vEntry.getKey().size(); i++) {
        final Comparable[] valueArray=valueArrays[i];
        if (valueArray == null) {
          continue;
        }
        final int ordinal=vEntry.getKey().getOrdinals()[i];
        final Comparable value=valueArray[ordinal];
        int targetOrdinal;
        if (value == null) {
          targetOrdinal=axes[z].valueSet.size();
        }
 else {
          targetOrdinal=Util.binarySearch(axes[z].values,0,axes[z].values.length,value);
        }
        pos[z++]=targetOrdinal;
      }
      final CellKey ck=CellKey.Generator.newCellKey(pos);
      if (!cellValues.containsKey(ck)) {
        cellValues.put(ck,new ArrayList<Object>());
      }
      cellValues.get(ck).add(vEntry.getValue());
    }
  }
  final List<Pair<SortedSet<Comparable>,Boolean>> axisList=new ArrayList<Pair<SortedSet<Comparable>,Boolean>>();
  final BitSet nullIndicators=new BitSet(axes.length);
  int nbValues=1;
  for (int i=0; i < axes.length; i++) {
    axisList.add(new Pair<SortedSet<Comparable>,Boolean>(axes[i].valueSet,axes[i].hasNull));
    nullIndicators.set(i,axes[i].hasNull);
    nbValues*=axes[i].values.length;
  }
  final int[] axisMultipliers=computeAxisMultipliers(axisList);
  final SegmentBody body;
  if (cellValues.size() == 0) {
    body=new DenseObjectSegmentBody(new Object[0],axisList);
  }
 else   if (SegmentLoader.useSparse(cellValues.size(),cellValues.size() - nullIndicators.cardinality())) {
    final Map<CellKey,Object> data=new HashMap<CellKey,Object>();
    for (    Entry<CellKey,List<Object>> entry : cellValues.entrySet()) {
      data.put(CellKey.Generator.newCellKey(entry.getKey().getOrdinals()),rollupAggregator.aggregate(entry.getValue()));
    }
    body=new SparseSegmentBody(data,axisList);
  }
 else {
    final Object peek=cellValues.entrySet().iterator().next().getValue().get(0);
    if (peek instanceof Double) {
      final double[] data=new double[nbValues];
      for (      Entry<CellKey,List<Object>> entry : cellValues.entrySet()) {
        final int offset=CellKey.Generator.getOffset(entry.getKey().getOrdinals(),axisMultipliers);
        data[offset]=(Double)rollupAggregator.aggregate(entry.getValue());
      }
      body=new DenseDoubleSegmentBody(nullIndicators,data,axisList);
    }
 else     if (peek instanceof Integer) {
      final int[] data=new int[cellValues.size()];
      for (      Entry<CellKey,List<Object>> entry : cellValues.entrySet()) {
        final int offset=CellKey.Generator.getOffset(entry.getKey().getOrdinals(),axisMultipliers);
        data[offset]=(Integer)rollupAggregator.aggregate(entry.getValue());
      }
      body=new DenseIntSegmentBody(nullIndicators,data,axisList);
    }
 else {
      final Object[] data=new Object[cellValues.size()];
      for (      Entry<CellKey,List<Object>> entry : cellValues.entrySet()) {
        final int offset=CellKey.Generator.getOffset(entry.getKey().getOrdinals(),axisMultipliers);
        data[offset]=(Object)rollupAggregator.aggregate(entry.getValue());
      }
      body=new DenseObjectSegmentBody(data,axisList);
    }
  }
  final List<SegmentColumn> constrainedColumns=new ArrayList<SegmentColumn>();
  for (int i=0; i < axes.length; i++) {
    AxisInfo axisInfo=axes[i];
    constrainedColumns.add(new SegmentColumn(axisInfo.column.getColumnExpression(),axisInfo.column.getValueCount(),axisInfo.lostPredicate ? axisList.get(i).left : axisInfo.column.values));
  }
  final SegmentHeader header=new SegmentHeader(firstHeader.schemaName,firstHeader.schemaChecksum,firstHeader.cubeName,firstHeader.measureName,constrainedColumns,firstHeader.compoundPredicates,firstHeader.rolapStarFactTableName,targetBitkey,Collections.<SegmentColumn>emptyList());
  return Pair.of(header,body);
}

Fixed version (ground truth):
/** 
 * Given a collection of segments, all of the same dimensionality, rolls up to create a segment with reduced dimensionality.
 * @param map Source segment headers and bodies
 * @param keepColumns A list of column names to keep as part ofthe rolled up segment.
 * @param targetBitkey The column bit key to match with theresulting segment.
 * @param rollupAggregator The aggregator to use to rollup.
 * @return Segment header and body of requested dimensionality
 */
public static Pair<SegmentHeader,SegmentBody> rollup(Map<SegmentHeader,SegmentBody> map,Set<String> keepColumns,BitKey targetBitkey,Aggregator rollupAggregator){
class AxisInfo {
    SegmentColumn column;
    SortedSet<Comparable> requestedValues;
    SortedSet<Comparable> valueSet;
    Comparable[] values;
    boolean hasNull;
    int src;
    boolean lostPredicate;
  }
  final SegmentHeader firstHeader=map.keySet().iterator().next();
  final AxisInfo[] axes=new AxisInfo[keepColumns.size()];
  int z=0, j=0;
  for (  SegmentColumn column : firstHeader.getConstrainedColumns()) {
    if (keepColumns.contains(column.columnExpression)) {
      final AxisInfo axisInfo=axes[z++]=new AxisInfo();
      axisInfo.src=j;
      axisInfo.column=column;
      axisInfo.requestedValues=column.values;
    }
    j++;
  }
  for (  Map.Entry<SegmentHeader,SegmentBody> entry : map.entrySet()) {
    final SegmentHeader header=entry.getKey();
    for (    AxisInfo axis : axes) {
      final SortedSet<Comparable> values=entry.getValue().getAxisValueSets()[axis.src];
      final SegmentColumn headerColumn=header.getConstrainedColumn(axis.column.columnExpression);
      final boolean hasNull=entry.getValue().getNullAxisFlags()[axis.src];
      final SortedSet<Comparable> requestedValues=headerColumn.getValues();
      if (axis.valueSet == null) {
        axis.valueSet=new TreeSet<Comparable>(values);
        axis.hasNull=hasNull;
        axis.requestedValues=requestedValues;
      }
 else {
        final SortedSet<Comparable> filteredValues;
        final boolean filteredHasNull;
        if (axis.requestedValues == null) {
          filteredValues=values;
          filteredHasNull=hasNull;
        }
 else {
          filteredValues=Util.intersect(values,axis.requestedValues);
          filteredHasNull=false;
        }
        axis.valueSet.addAll(filteredValues);
        axis.hasNull=axis.hasNull || filteredHasNull;
        if (!Util.equals(axis.requestedValues,requestedValues)) {
          if (axis.requestedValues == null) {
            axis.requestedValues=requestedValues;
          }
 else {
            axis.lostPredicate=true;
          }
        }
      }
    }
  }
  for (  AxisInfo axis : axes) {
    axis.values=axis.valueSet.toArray(new Comparable[axis.valueSet.size()]);
  }
  final Map<CellKey,List<Object>> cellValues=new HashMap<CellKey,List<Object>>();
  for (  Map.Entry<SegmentHeader,SegmentBody> entry : map.entrySet()) {
    final int[] pos=new int[axes.length];
    final Comparable[][] valueArrays=new Comparable[firstHeader.getConstrainedColumns().size()][];
    final SegmentBody body=entry.getValue();
    z=0;
    for (    SortedSet<Comparable> set : body.getAxisValueSets()) {
      valueArrays[z]=keepColumns.contains(firstHeader.getConstrainedColumns().get(z).columnExpression) ? set.toArray(new Comparable[set.size()]) : null;
      ++z;
    }
    Map<CellKey,Object> v=body.getValueMap();
    for (    Map.Entry<CellKey,Object> vEntry : v.entrySet()) {
      z=0;
      for (int i=0; i < vEntry.getKey().size(); i++) {
        final Comparable[] valueArray=valueArrays[i];
        if (valueArray == null) {
          continue;
        }
        final int ordinal=vEntry.getKey().getOrdinals()[i];
        final int targetOrdinal;
        if (axes[z].hasNull && ordinal == valueArray.length) {
          targetOrdinal=axes[z].valueSet.size();
        }
 else {
          final Comparable value=valueArray[ordinal];
          if (value == null) {
            targetOrdinal=axes[z].valueSet.size();
          }
 else {
            targetOrdinal=Util.binarySearch(axes[z].values,0,axes[z].values.length,value);
          }
        }
        pos[z++]=targetOrdinal;
      }
      final CellKey ck=CellKey.Generator.newCellKey(pos);
      if (!cellValues.containsKey(ck)) {
        cellValues.put(ck,new ArrayList<Object>());
      }
      cellValues.get(ck).add(vEntry.getValue());
    }
  }
  final List<Pair<SortedSet<Comparable>,Boolean>> axisList=new ArrayList<Pair<SortedSet<Comparable>,Boolean>>();
  final BitSet nullIndicators=new BitSet(axes.length);
  int nbValues=1;
  for (int i=0; i < axes.length; i++) {
    axisList.add(new Pair<SortedSet<Comparable>,Boolean>(axes[i].valueSet,axes[i].hasNull));
    nullIndicators.set(i,axes[i].hasNull);
    nbValues*=axes[i].hasNull ? axes[i].values.length + 1 : axes[i].values.length;
  }
  final int[] axisMultipliers=computeAxisMultipliers(axisList);
  final SegmentBody body;
  if (cellValues.size() == 0) {
    body=new DenseObjectSegmentBody(new Object[0],axisList);
  }
 else   if (SegmentLoader.useSparse(cellValues.size(),cellValues.size() - nullIndicators.cardinality())) {
    final Map<CellKey,Object> data=new HashMap<CellKey,Object>();
    for (    Entry<CellKey,List<Object>> entry : cellValues.entrySet()) {
      data.put(CellKey.Generator.newCellKey(entry.getKey().getOrdinals()),rollupAggregator.aggregate(entry.getValue()));
    }
    body=new SparseSegmentBody(data,axisList);
  }
 else {
    final Object peek=cellValues.entrySet().iterator().next().getValue().get(0);
    if (peek instanceof Double) {
      final double[] data=new double[nbValues];
      for (      Entry<CellKey,List<Object>> entry : cellValues.entrySet()) {
        final int offset=CellKey.Generator.getOffset(entry.getKey().getOrdinals(),axisMultipliers);
        data[offset]=(Double)rollupAggregator.aggregate(entry.getValue());
      }
      body=new DenseDoubleSegmentBody(nullIndicators,data,axisList);
    }
 else     if (peek instanceof Integer) {
      final int[] data=new int[nbValues];
      for (      Entry<CellKey,List<Object>> entry : cellValues.entrySet()) {
        final int offset=CellKey.Generator.getOffset(entry.getKey().getOrdinals(),axisMultipliers);
        data[offset]=(Integer)rollupAggregator.aggregate(entry.getValue());
      }
      body=new DenseIntSegmentBody(nullIndicators,data,axisList);
    }
 else {
      final Object[] data=new Object[nbValues];
      for (      Entry<CellKey,List<Object>> entry : cellValues.entrySet()) {
        final int offset=CellKey.Generator.getOffset(entry.getKey().getOrdinals(),axisMultipliers);
        data[offset]=(Object)rollupAggregator.aggregate(entry.getValue());
      }
      body=new DenseObjectSegmentBody(data,axisList);
    }
  }
  final List<SegmentColumn> constrainedColumns=new ArrayList<SegmentColumn>();
  for (int i=0; i < axes.length; i++) {
    AxisInfo axisInfo=axes[i];
    constrainedColumns.add(new SegmentColumn(axisInfo.column.getColumnExpression(),axisInfo.column.getValueCount(),axisInfo.lostPredicate ? axisList.get(i).left : axisInfo.column.values));
  }
  final SegmentHeader header=new SegmentHeader(firstHeader.schemaName,firstHeader.schemaChecksum,firstHeader.cubeName,firstHeader.measureName,constrainedColumns,firstHeader.compoundPredicates,firstHeader.rolapStarFactTableName,targetBitkey,Collections.<SegmentColumn>emptyList());
  return Pair.of(header,body);
}