Example #1
0
  @Override
  public Cacheable getBlock(
      BlockCacheKey key, boolean caching, boolean repeat, boolean updateCacheMetrics) {
    CacheablePair contentBlock = backingMap.get(key);
    if (contentBlock == null) {
      if (!repeat && updateCacheMetrics) stats.miss(caching);
      return null;
    }

    if (updateCacheMetrics) stats.hit(caching);
    // If lock cannot be obtained, that means we're undergoing eviction.
    try {
      contentBlock.recentlyAccessed.set(System.nanoTime());
      synchronized (contentBlock) {
        if (contentBlock.serializedData == null) {
          // concurrently evicted
          LOG.warn("Concurrent eviction of " + key);
          return null;
        }
        return contentBlock.deserializer.deserialize(
            contentBlock.serializedData.asReadOnlyBuffer());
      }
    } catch (Throwable t) {
      LOG.error("Deserializer threw an exception. This may indicate a bug.", t);
      return null;
    }
  }
Example #2
0
  private void doEviction(BlockCacheKey key, CacheablePair evictedBlock) {
    long evictedHeap = 0;
    synchronized (evictedBlock) {
      if (evictedBlock.serializedData == null) {
        // someone else already freed
        return;
      }
      evictedHeap = evictedBlock.heapSize();
      ByteBuffer bb = evictedBlock.serializedData;
      evictedBlock.serializedData = null;
      backingStore.free(bb);

      // We have to do this callback inside the synchronization here.
      // Otherwise we can have the following interleaving:
      // Thread A calls getBlock():
      // SlabCache directs call to this SingleSizeCache
      // It gets the CacheablePair object
      // Thread B runs eviction
      // doEviction() is called and sets serializedData = null, here.
      // Thread A sees the null serializedData, and returns null
      // Thread A calls cacheBlock on the same block, and gets
      // "already cached" since the block is still in backingStore

      if (actionWatcher != null) {
        actionWatcher.onEviction(key, this);
      }
    }
    stats.evicted();
    size.addAndGet(-1 * evictedHeap);
  }
Example #3
0
  /**
   * Evicts the block
   *
   * @param key the key of the entry we are going to evict
   * @return the evicted ByteBuffer
   */
  public boolean evictBlock(BlockCacheKey key) {
    stats.evict();
    CacheablePair evictedBlock = backingMap.remove(key);

    if (evictedBlock != null) {
      doEviction(key, evictedBlock);
    }
    return evictedBlock != null;
  }
Example #4
0
 public long getEvictedCount() {
   return stats.getEvictedCount();
 }
Example #5
0
  public void logStats() {

    long milliseconds = this.timeSinceLastAccess.get() / 1000000;

    LOG.info(
        "For Slab of size "
            + this.blockSize
            + ": "
            + this.getOccupiedSize() / this.blockSize
            + " occupied, out of a capacity of "
            + this.numBlocks
            + " blocks. HeapSize is "
            + StringUtils.humanReadableInt(this.heapSize())
            + " bytes."
            + ", "
            + "churnTime="
            + StringUtils.formatTime(milliseconds));

    LOG.info(
        "Slab Stats: "
            + "accesses="
            + stats.getRequestCount()
            + ", "
            + "hits="
            + stats.getHitCount()
            + ", "
            + "hitRatio="
            + (stats.getHitCount() == 0
                ? "0"
                : (StringUtils.formatPercent(stats.getHitRatio(), 2) + "%, "))
            + "cachingAccesses="
            + stats.getRequestCachingCount()
            + ", "
            + "cachingHits="
            + stats.getHitCachingCount()
            + ", "
            + "cachingHitsRatio="
            + (stats.getHitCachingCount() == 0
                ? "0"
                : (StringUtils.formatPercent(stats.getHitCachingRatio(), 2) + "%, "))
            + "evictions="
            + stats.getEvictionCount()
            + ", "
            + "evicted="
            + stats.getEvictedCount()
            + ", "
            + "evictedPerRun="
            + stats.evictedPerEviction());
  }