public long[] getUsageStats() {
      long dataOnHeap     = 0L;   // all non-meta related buffers on min-heap
      long dataOnList     = 0L;   // all non-meta related buffers on eviction list
      long metaOnHeap     = 0L;   // meta data buffers on min-heap
      long metaOnList     = 0L;   // meta data buffers on eviction list
      long listSize       = 0L;   // number of entries on eviction list
      long lockedData     = 0L;   // number of bytes in locked data buffers
      long lockedMeta     = 0L;   // number of bytes in locked metadata buffers
      long bpWrapCount    = 0L;   // number of buffers in BP wrapper threadlocals
      long bpWrapDistinct = 0L;   // number of distinct buffers in BP wrapper threadlocals
      long bpWrapData     = 0L;   // number of bytes stored in BP wrapper data buffers
      long bpWrapMeta     = 0L;   // number of bytes stored in BP wrapper metadata buffers

      // Using set to produce result of distinct buffers only
      // (same buffer may be present in multiple thread local bp wrappers, or even inside heap/list, but ultimately
      // it uses the same cache space)
      Set<LlapCacheableBuffer> bpWrapperBuffers = new HashSet<>();
      for (BPWrapper bpWrapper : bpWrappers.values()) {
        bpWrapper.lock.lock();
        try {
          bpWrapCount += bpWrapper.count;
          for (int i = 0; i < bpWrapper.count; ++i) {
            bpWrapperBuffers.add(bpWrapper.buffers[i]);
          }
        } finally {
          bpWrapper.lock.unlock();
        }
      }

      // aggregate values on the heap
      heapLock.lock();
      try {
        for (int heapIdx = 0; heapIdx < heapSize; ++heapIdx) {
          LlapCacheableBuffer buff = heap[heapIdx];

          if (null != buff) {
            if (buff instanceof LlapMetadataBuffer) {
              metaOnHeap += buff.getMemoryUsage();
              if (buff.isLocked()) {
                lockedMeta += buff.getMemoryUsage();
              }
            } else {
              dataOnHeap += buff.getMemoryUsage();
              if (buff.isLocked()) {
                lockedData += buff.getMemoryUsage();
              }
            }
            bpWrapperBuffers.remove(buff);
          }
        }
      } finally {
        heapLock.unlock();
      }

      // aggregate values on the evicition short list
      try {
        listLock.lock();
        LlapCacheableBuffer scan = listHead;
        while (null != scan) {
          if (scan instanceof LlapMetadataBuffer) {
            metaOnList += scan.getMemoryUsage();
            if (scan.isLocked()) {
              lockedMeta += scan.getMemoryUsage();
            }
          } else {
            dataOnList += scan.getMemoryUsage();
            if (scan.isLocked()) {
              lockedData += scan.getMemoryUsage();
            }
          }
          bpWrapperBuffers.remove(scan);
          ++listSize;
          scan = scan.next;
        }
      } finally {
        listLock.unlock();
      }


      for (LlapCacheableBuffer buff : bpWrapperBuffers) {
        if (buff instanceof LlapMetadataBuffer) {
          bpWrapMeta += buff.getMemoryUsage();
        } else {
          bpWrapData += buff.getMemoryUsage();
        }
        ++bpWrapDistinct;
      }

      return new long[] {dataOnHeap, dataOnList,
                         metaOnHeap, metaOnList, listSize,
                         lockedData, lockedMeta,
                         bpWrapCount, bpWrapDistinct, bpWrapData, bpWrapMeta};
    }
Helper to get some basic LRFU usage statistics.
This method returns a long array with the following content:
- amount of data (bytes) on min-heap
- amount of data (bytes) on eviction short list
- amount of metadata (bytes) on min-heap
- amount of metadata (bytes) on eviction short list
- size of the eviction short list
- amount of locked bytes for data
- amount of locked bytes for metadata

@return long array with LRFU stats
llap-server/src/java/org/apache/hadoop/hive/llap/cache/LowLevelLrfuCachePolicy.java