@Override
  public void debugDumpShort(StringBuilder sb) {
    sb.append("\nSerDe cache state ");
    int allLocked = 0, allUnlocked = 0, allEvicted = 0, allMoving = 0, allMarked = 0;
    for (Map.Entry<Object, FileCache<FileData>> e : cache.entrySet()) {
      if (!e.getValue().incRef()) continue;
      try {
        FileData fd = e.getValue().getCache();
        int fileLocked = 0, fileUnlocked = 0, fileEvicted = 0, fileMoving = 0, fileMarked = 0;
        for (StripeData stripe : fd.stripes) {
          if (stripe.data == null) continue;
          for (int i = 0; i < stripe.data.length; ++i) {
            LlapSerDeDataBuffer[][] colData = stripe.data[i];
            if (colData == null) continue;
            for (int j = 0; j < colData.length; ++j) {
              LlapSerDeDataBuffer[] streamData = colData[j];
              if (streamData == null) continue;
              for (int k = 0; k < streamData.length; ++k) {
                int newRc = streamData[k].incRef();
                if (newRc < 0) {
                  if (newRc == LlapAllocatorBuffer.INCREF_EVICTED) {
                    ++fileEvicted;
                  } else if (newRc == LlapAllocatorBuffer.INCREF_FAILED) {
                    ++fileMoving;
                  }
                  continue;
                }
                if (streamData[k].isMarkedForEviction()) {
                  ++fileMarked;
                }
                try {
                  if (newRc > 1) { // We hold one refcount.
                    ++fileLocked;
                  } else {
                    ++fileUnlocked;
                  }
                } finally {
                  streamData[k].decRef();
                }
              }
            }
          }
        }
        allLocked += fileLocked;
        allUnlocked += fileUnlocked;
        allEvicted += fileEvicted;
        allMoving += fileMoving;
        allMarked += fileMarked;
        sb.append("\n  file " + e.getKey() + ": " + fileLocked + " locked, " + fileUnlocked
            + " unlocked, " + fileEvicted + " evicted, " + fileMoving + " being moved, " + fileMarked
            + " marked for eviction; ");
        sb.append(fd.colCount).append(" columns, ").append(fd.stripes.size()).append(" stripes");
      } finally {
        e.getValue().decRef();
      }
    }
    sb.append("\nSerDe cache summary: " + allLocked + " locked, " + allUnlocked + " unlocked, "
        + allEvicted + " evicted, " + allMoving + " being moved, " + allMarked + " marked for eviction");
  }
RW lock ensures we have a consistent view of the file data, which is important given that
we generate "stripe" boundaries arbitrarily. Reading buffer data itself doesn't require
that this lock is held; however, everything else in stripes list does.
TODO: make more granular? We only care that each one reader sees consistent boundaries.
      So, we could shallow-copy the stripes list, then have individual locks inside each.
llap-server/src/java/org/apache/hadoop/hive/llap/cache/SerDeLowLevelCacheImpl.java