Program: 50905
Project: 50905
Buggy source:
/** 
 * Resolves any pending cell reads using the cache. After calling this method, all cells requested in a given batch are loaded into this statement's local cache. <p>The method is implemented by making an asynchronous call to the cache manager. The result is a list of segments that satisfies every cell request.</p> <p>The client should put the resulting segments into its "query local" cache, to ensure that future cells in that segment can be answered without a call to the cache manager. (That is probably 1000x faster.)</p> <p>The cache manager does not inform where client where each segment came from. There are several possibilities:</p> <ul> <li>Segment was already in cache (header and body)</li> <li>Segment is in the process of being loaded by executing a SQL statement (probably due to a request from another client)</li> <li>Segment is in an external cache (that is, header is in the cache, body is not yet)</li> <li>Segment can be created by rolling up one or more cache segments. (And of course each of these segments might be "paged out".)</li> <li>By executing a SQL   {@code GROUP BY} statement</li></ul> <p>Furthermore, segments in external cache may take some time to retrieve (a LAN round trip, say 1 millisecond, is a reasonable guess); and the request may fail. (It depends on the cache, but caches are at liberty to 'forget' segments.) So, any strategy that relies on cache segments should be able to fall back. Even if there are fall backs, only one call needs to be made to the cache manager.</p>
 * @return Whether any aggregations were loaded.
 */
boolean loadAggregations(){
  if (!isDirty()) {
    return false;
  }
  final List<Future<Map<Segment,SegmentWithData>>> sqlSegmentMapFutures=new ArrayList<Future<Map<Segment,SegmentWithData>>>();
  final List<CellRequest> cellRequests1=new ArrayList<CellRequest>(cellRequests);
  for (int iteration=0; ; ++iteration) {
    final BatchLoader.LoadBatchResponse response=cacheMgr.execute(new BatchLoader.LoadBatchCommand(Locus.peek(),cacheMgr,getDialect(),cube,Collections.unmodifiableList(cellRequests1)));
    int failureCount=0;
    Map<SegmentHeader,SegmentBody> headerBodies=new HashMap<SegmentHeader,SegmentBody>();
    final Set<SegmentHeader> failedSegments=new HashSet<SegmentHeader>();
    for (    SegmentHeader header : response.cacheSegments) {
      final SegmentBody body=cacheMgr.compositeCache.get(header);
      if (body == null) {
        cacheMgr.remove(cube.getStar(),header);
        failedSegments.add(header);
        ++failureCount;
        continue;
      }
      headerBodies.put(header,body);
      final SegmentWithData segmentWithData=response.convert(header,body);
      segmentWithData.getStar().register(segmentWithData);
    }
    final Map<SegmentHeader,SegmentBody> succeededRollups=new HashMap<SegmentHeader,SegmentBody>();
    for (    final BatchLoader.RollupInfo rollup : response.rollups) {
      Map<SegmentHeader,SegmentBody> map=findResidentRollupCandidate(headerBodies,rollup);
      if (map == null) {
        continue;
      }
      final Set<String> keepColumns=new HashSet<String>();
      for (      RolapStar.Column column : rollup.constrainedColumns) {
        keepColumns.add(column.getExpression().getGenericExpression());
      }
      Pair<SegmentHeader,SegmentBody> rollupHeaderBody=SegmentBuilder.rollup(map,keepColumns,rollup.constrainedColumnsBitKey,rollup.measure.getAggregator().getRollup());
      final SegmentHeader header=rollupHeaderBody.left;
      final SegmentBody body=rollupHeaderBody.right;
      if (headerBodies.containsKey(header)) {
        continue;
      }
      headerBodies.put(header,body);
      succeededRollups.put(header,body);
      final SegmentWithData segmentWithData=response.convert(header,body);
      final Locus locus=Locus.peek();
      cacheMgr.execute(new SegmentCacheManager.Command<Void>(){
        public Void call() throws Exception {
          SegmentCacheIndex index=cacheMgr.getIndexRegistry().getIndex(segmentWithData.getStar());
          index.add(segmentWithData.getHeader(),true,response.converterMap.get(SegmentCacheIndexImpl.makeConverterKey(segmentWithData.getHeader())));
          ((SlotFuture<SegmentBody>)index.getFuture(segmentWithData.getHeader())).put(body);
          return null;
        }
        public Locus getLocus(){
          return locus;
        }
      }
);
      segmentWithData.getStar().register(segmentWithData);
    }
    sqlSegmentMapFutures.addAll(response.sqlSegmentMapFutures);
    if (failureCount == 0 || iteration > 0) {
      for (      Map.Entry<SegmentHeader,Future<SegmentBody>> entry : response.futures.entrySet()) {
        final SegmentHeader header=entry.getKey();
        final Future<SegmentBody> bodyFuture=entry.getValue();
        final SegmentBody body=Util.safeGet(bodyFuture,"String_Node_Str");
        final SegmentWithData segmentWithData=response.convert(header,body);
        segmentWithData.getStar().register(segmentWithData);
      }
      for (      Future<Map<Segment,SegmentWithData>> sqlSegmentMapFuture : sqlSegmentMapFutures) {
        final Map<Segment,SegmentWithData> segmentMap=Util.safeGet(sqlSegmentMapFuture,"String_Node_Str");
        for (        SegmentWithData segmentWithData : segmentMap.values()) {
          segmentWithData.getStar().register(segmentWithData);
        }
      }
    }
    if (failureCount == 0) {
      break;
    }
    @SuppressWarnings("String_Node_Str") List<CellRequest> old=new ArrayList<CellRequest>(cellRequests1);
    cellRequests1.clear();
    for (    CellRequest cellRequest : old) {
      if (cellRequest.getMeasure().getStar().getCellFromCache(cellRequest,null) == null) {
        cellRequests1.add(cellRequest);
      }
    }
    if (cellRequests1.isEmpty()) {
      break;
    }
    if (cellRequests1.size() >= old.size() && iteration > 10) {
      throw Util.newError("String_Node_Str" + "String_Node_Str" + iteration + "String_Node_Str"+ cellRequests1.size()+ "String_Node_Str"+ response.cacheSegments.size()+ "String_Node_Str"+ response.rollups.size()+ "String_Node_Str"+ response.sqlSegmentMapFutures.size());
    }
  }
  dirty=false;
  cellRequests.clear();
  return true;
}

Fixed version (ground truth):
/** 
 * Resolves any pending cell reads using the cache. After calling this method, all cells requested in a given batch are loaded into this statement's local cache. <p>The method is implemented by making an asynchronous call to the cache manager. The result is a list of segments that satisfies every cell request.</p> <p>The client should put the resulting segments into its "query local" cache, to ensure that future cells in that segment can be answered without a call to the cache manager. (That is probably 1000x faster.)</p> <p>The cache manager does not inform where client where each segment came from. There are several possibilities:</p> <ul> <li>Segment was already in cache (header and body)</li> <li>Segment is in the process of being loaded by executing a SQL statement (probably due to a request from another client)</li> <li>Segment is in an external cache (that is, header is in the cache, body is not yet)</li> <li>Segment can be created by rolling up one or more cache segments. (And of course each of these segments might be "paged out".)</li> <li>By executing a SQL   {@code GROUP BY} statement</li></ul> <p>Furthermore, segments in external cache may take some time to retrieve (a LAN round trip, say 1 millisecond, is a reasonable guess); and the request may fail. (It depends on the cache, but caches are at liberty to 'forget' segments.) So, any strategy that relies on cache segments should be able to fall back. Even if there are fall backs, only one call needs to be made to the cache manager.</p>
 * @return Whether any aggregations were loaded.
 */
boolean loadAggregations(){
  if (!isDirty()) {
    return false;
  }
  final List<Future<Map<Segment,SegmentWithData>>> sqlSegmentMapFutures=new ArrayList<Future<Map<Segment,SegmentWithData>>>();
  final List<CellRequest> cellRequests1=new ArrayList<CellRequest>(cellRequests);
  for (int iteration=0; ; ++iteration) {
    final BatchLoader.LoadBatchResponse response=cacheMgr.execute(new BatchLoader.LoadBatchCommand(Locus.peek(),cacheMgr,getDialect(),cube,Collections.unmodifiableList(cellRequests1)));
    int failureCount=0;
    Map<SegmentHeader,SegmentBody> headerBodies=new HashMap<SegmentHeader,SegmentBody>();
    final Set<SegmentHeader> failedSegments=new HashSet<SegmentHeader>();
    for (    SegmentHeader header : response.cacheSegments) {
      final SegmentBody body=cacheMgr.compositeCache.get(header);
      if (body == null) {
        cacheMgr.remove(cube.getStar(),header);
        failedSegments.add(header);
        ++failureCount;
        continue;
      }
      headerBodies.put(header,body);
      final SegmentWithData segmentWithData=response.convert(header,body);
      segmentWithData.getStar().register(segmentWithData);
    }
    final Map<SegmentHeader,SegmentBody> succeededRollups=new HashMap<SegmentHeader,SegmentBody>();
    for (    final BatchLoader.RollupInfo rollup : response.rollups) {
      Map<SegmentHeader,SegmentBody> map=findResidentRollupCandidate(headerBodies,rollup);
      if (map == null) {
        continue;
      }
      final Set<String> keepColumns=new HashSet<String>();
      for (      RolapStar.Column column : rollup.constrainedColumns) {
        keepColumns.add(column.getExpression().getGenericExpression());
      }
      Pair<SegmentHeader,SegmentBody> rollupHeaderBody=SegmentBuilder.rollup(map,keepColumns,rollup.constrainedColumnsBitKey,rollup.measure.getAggregator().getRollup());
      final SegmentHeader header=rollupHeaderBody.left;
      final SegmentBody body=rollupHeaderBody.right;
      if (headerBodies.containsKey(header)) {
        continue;
      }
      headerBodies.put(header,body);
      succeededRollups.put(header,body);
      final SegmentWithData segmentWithData=response.convert(header,body);
      final Locus locus=Locus.peek();
      cacheMgr.execute(new SegmentCacheManager.Command<Void>(){
        public Void call() throws Exception {
          SegmentCacheIndex index=cacheMgr.getIndexRegistry().getIndex(segmentWithData.getStar());
          boolean added=index.add(segmentWithData.getHeader(),true,response.converterMap.get(SegmentCacheIndexImpl.makeConverterKey(segmentWithData.getHeader())));
          if (added) {
            ((SlotFuture<SegmentBody>)index.getFuture(segmentWithData.getHeader())).put(body);
          }
          return null;
        }
        public Locus getLocus(){
          return locus;
        }
      }
);
      segmentWithData.getStar().register(segmentWithData);
    }
    sqlSegmentMapFutures.addAll(response.sqlSegmentMapFutures);
    if (failureCount == 0 || iteration > 0) {
      for (      Map.Entry<SegmentHeader,Future<SegmentBody>> entry : response.futures.entrySet()) {
        final SegmentHeader header=entry.getKey();
        final Future<SegmentBody> bodyFuture=entry.getValue();
        final SegmentBody body=Util.safeGet(bodyFuture,"String_Node_Str");
        final SegmentWithData segmentWithData=response.convert(header,body);
        segmentWithData.getStar().register(segmentWithData);
      }
      for (      Future<Map<Segment,SegmentWithData>> sqlSegmentMapFuture : sqlSegmentMapFutures) {
        final Map<Segment,SegmentWithData> segmentMap=Util.safeGet(sqlSegmentMapFuture,"String_Node_Str");
        for (        SegmentWithData segmentWithData : segmentMap.values()) {
          segmentWithData.getStar().register(segmentWithData);
        }
      }
    }
    if (failureCount == 0) {
      break;
    }
    @SuppressWarnings("String_Node_Str") List<CellRequest> old=new ArrayList<CellRequest>(cellRequests1);
    cellRequests1.clear();
    for (    CellRequest cellRequest : old) {
      if (cellRequest.getMeasure().getStar().getCellFromCache(cellRequest,null) == null) {
        cellRequests1.add(cellRequest);
      }
    }
    if (cellRequests1.isEmpty()) {
      break;
    }
    if (cellRequests1.size() >= old.size() && iteration > 10) {
      throw Util.newError("String_Node_Str" + "String_Node_Str" + iteration + "String_Node_Str"+ cellRequests1.size()+ "String_Node_Str"+ response.cacheSegments.size()+ "String_Node_Str"+ response.rollups.size()+ "String_Node_Str"+ response.sqlSegmentMapFutures.size());
    }
  }
  dirty=false;
  cellRequests.clear();
  return true;
}