private long calculateBytesToFree(StringBuilder msgBuffer) {
    long bytesToFreeWithoutExtra = 0;
    BucketAllocator.IndexStatistics[] stats = bucketAllocator.getIndexStatistics();
    long[] bytesToFreeForBucket = new long[stats.length];
    for (int i = 0; i < stats.length; i++) {
      bytesToFreeForBucket[i] = 0;
      long freeGoal = (long) Math.floor(stats[i].totalCount() * (1 - minFactor));
      freeGoal = Math.max(freeGoal, 1);
      if (stats[i].freeCount() < freeGoal) {
        bytesToFreeForBucket[i] = stats[i].itemSize() * (freeGoal - stats[i].freeCount());
        bytesToFreeWithoutExtra += bytesToFreeForBucket[i];
        if (msgBuffer != null) {
          msgBuffer.append("Free for bucketSize(" + stats[i].itemSize() + ")="
            + StringUtils.byteDesc(bytesToFreeForBucket[i]) + ", ");
        }
      }
    }
    if (msgBuffer != null) {
      msgBuffer.append("Free for total=" + StringUtils.byteDesc(bytesToFreeWithoutExtra) + ", ");
    }
    return bytesToFreeWithoutExtra;
  }
This method will find the buckets that are minimally occupied and are not reference counted and
will free them completely without any constraint on the access times of the elements, and as a
process will completely free at most the number of buckets passed, sometimes it might not due
to changing refCounts
@param completelyFreeBucketsNeeded number of buckets to free
hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/bucket/BucketCache.java