コード例 #1
0
ファイル: BucketAllocator.java プロジェクト: Guavus/hbase
  /**
   * Rebuild the allocator's data structures from a persisted map.
   *
   * @param availableSpace capacity of cache
   * @param map A map stores the block key and BucketEntry(block's meta data like offset, length)
   * @param realCacheSize cached data size statistics for bucket cache
   * @throws BucketAllocatorException
   */
  BucketAllocator(
      long availableSpace,
      int[] bucketSizes,
      Map<BlockCacheKey, BucketEntry> map,
      AtomicLong realCacheSize)
      throws BucketAllocatorException {
    this(availableSpace, bucketSizes);

    // each bucket has an offset, sizeindex. probably the buckets are too big
    // in our default state. so what we do is reconfigure them according to what
    // we've found. we can only reconfigure each bucket once; if more than once,
    // we know there's a bug, so we just log the info, throw, and start again...
    boolean[] reconfigured = new boolean[buckets.length];
    for (Map.Entry<BlockCacheKey, BucketEntry> entry : map.entrySet()) {
      long foundOffset = entry.getValue().offset();
      int foundLen = entry.getValue().getLength();
      int bucketSizeIndex = -1;
      for (int i = 0; i < bucketSizes.length; ++i) {
        if (foundLen <= bucketSizes[i]) {
          bucketSizeIndex = i;
          break;
        }
      }
      if (bucketSizeIndex == -1) {
        throw new BucketAllocatorException(
            "Can't match bucket size for the block with size " + foundLen);
      }
      int bucketNo = (int) (foundOffset / bucketCapacity);
      if (bucketNo < 0 || bucketNo >= buckets.length)
        throw new BucketAllocatorException(
            "Can't find bucket "
                + bucketNo
                + ", total buckets="
                + buckets.length
                + "; did you shrink the cache?");
      Bucket b = buckets[bucketNo];
      if (reconfigured[bucketNo]) {
        if (b.sizeIndex() != bucketSizeIndex)
          throw new BucketAllocatorException("Inconsistent allocation in bucket map;");
      } else {
        if (!b.isCompletelyFree())
          throw new BucketAllocatorException(
              "Reconfiguring bucket " + bucketNo + " but it's already allocated; corrupt data");
        // Need to remove the bucket from whichever list it's currently in at
        // the moment...
        BucketSizeInfo bsi = bucketSizeInfos[bucketSizeIndex];
        BucketSizeInfo oldbsi = bucketSizeInfos[b.sizeIndex()];
        oldbsi.removeBucket(b);
        bsi.instantiateBucket(b);
        reconfigured[bucketNo] = true;
      }
      realCacheSize.addAndGet(foundLen);
      buckets[bucketNo].addAllocation(foundOffset);
      usedSize += buckets[bucketNo].getItemAllocationSize();
      bucketSizeInfos[bucketSizeIndex].blockAllocated(b);
    }
  }
コード例 #2
0
ファイル: BucketAllocator.java プロジェクト: Guavus/hbase
 /**
  * Free a block with the offset
  *
  * @param offset block's offset
  * @return size freed
  */
 public synchronized int freeBlock(long offset) {
   int bucketNo = (int) (offset / bucketCapacity);
   assert bucketNo >= 0 && bucketNo < buckets.length;
   Bucket targetBucket = buckets[bucketNo];
   bucketSizeInfos[targetBucket.sizeIndex()].freeBlock(targetBucket, offset);
   usedSize -= targetBucket.getItemAllocationSize();
   return targetBucket.getItemAllocationSize();
 }
コード例 #3
0
ファイル: BucketAllocator.java プロジェクト: Guavus/hbase
 public int sizeIndexOfAllocation(long offset) {
   int bucketNo = (int) (offset / bucketCapacity);
   assert bucketNo >= 0 && bucketNo < buckets.length;
   Bucket targetBucket = buckets[bucketNo];
   return targetBucket.sizeIndex();
 }