/** Returns the {@link SegmentCacheIndex} for a given {@link SegmentHeader}. */
 private SegmentCacheIndex getIndex(SegmentHeader header) {
   // First we check the indexes that already exist.
   // This is fast.
   for (Entry<RolapStar, SegmentCacheIndex> entry : indexes.entrySet()) {
     final String factTableName = entry.getKey().getFactTable().getTableName();
     final ByteString schemaChecksum = entry.getKey().getSchema().getChecksum();
     if (!factTableName.equals(header.rolapStarFactTableName)) {
       continue;
     }
     if (!schemaChecksum.equals(header.schemaChecksum)) {
       continue;
     }
     return entry.getValue();
   }
   // The index doesn't exist. Let's create it.
   for (RolapSchema schema : RolapSchema.getRolapSchemas()) {
     if (!schema.getChecksum().equals(header.schemaChecksum)) {
       continue;
     }
     // We have a schema match.
     RolapStar star = schema.getStar(header.rolapStarFactTableName);
     if (star != null) {
       // Found it.
       indexes.put(star, new SegmentCacheIndexImpl(thread));
     }
     return indexes.get(star);
   }
   return null;
 }
 /**
  * Retrieves the response from the queue matching the given key, blocking until it is received.
  *
  * @param k Response
  * @return Response
  * @throws InterruptedException if interrupted while waiting
  */
 public synchronized V take(K k) throws InterruptedException {
   final V v = taken.remove(k);
   if (v != null) {
     return v;
   }
   // Take the laundry out of the machine. If it's ours, leave with it.
   // If it's someone else's, fold it neatly and put it on the pile.
   for (; ; ) {
     final Pair<K, V> pair = queue.take();
     if (pair.left.equals(k)) {
       return pair.right;
     } else {
       taken.put(pair.left, pair.right);
     }
   }
 }
 /** Returns the {@link SegmentCacheIndex} for a given {@link RolapStar}. */
 public SegmentCacheIndex getIndex(RolapStar star) {
   if (!indexes.containsKey(star)) {
     indexes.put(star, new SegmentCacheIndexImpl(thread));
   }
   return indexes.get(star);
 }
    public PeekResponse call() {
      final RolapStar.Measure measure = request.getMeasure();
      final RolapStar star = measure.getStar();
      final RolapSchema schema = star.getSchema();
      final AggregationKey key = new AggregationKey(request);
      final List<SegmentHeader> headers =
          indexRegistry
              .getIndex(star)
              .locate(
                  schema.getName(),
                  schema.getChecksum(),
                  measure.getCubeName(),
                  measure.getName(),
                  star.getFactTable().getAlias(),
                  request.getConstrainedColumnsBitKey(),
                  request.getMappedCellValues(),
                  AggregationKey.getCompoundPredicateStringList(
                      star, key.getCompoundPredicateList()));

      final Map<SegmentHeader, Future<SegmentBody>> headerMap =
          new HashMap<SegmentHeader, Future<SegmentBody>>();
      final Map<List, SegmentBuilder.SegmentConverter> converterMap =
          new HashMap<List, SegmentBuilder.SegmentConverter>();

      // Is there a pending segment? (A segment that has been created and
      // is loading via SQL.)
      for (final SegmentHeader header : headers) {
        final Future<SegmentBody> bodyFuture = indexRegistry.getIndex(star).getFuture(header);
        if (bodyFuture != null) {
          // Check if the DataSourceChangeListener wants us to clear
          // the current segment
          if (star.getChangeListener() != null
              && star.getChangeListener().isAggregationChanged(key)) {
            /*
             * We can't satisfy this request, and we must clear the
             * data from our cache. We clear it from the index
             * first, then queue up a job in the background
             * to remove the data from all the caches.
             */
            indexRegistry.getIndex(star).remove(header);
            Util.safeGet(
                cacheExecutor.submit(
                    new Runnable() {
                      public void run() {
                        try {
                          compositeCache.remove(header);
                        } catch (Throwable e) {
                          LOGGER.warn("remove header failed: " + header, e);
                        }
                      }
                    }),
                "SegmentCacheManager.peek");
          }
          converterMap.put(
              SegmentCacheIndexImpl.makeConverterKey(header), getConverter(star, header));
          headerMap.put(header, bodyFuture);
        }
      }

      return new PeekResponse(headerMap, converterMap);
    }