private void lockAllBuffersForPut(StripeData si, Priority priority, FileCache cache) {
    for (int i = 0; i < si.data.length; ++i) {
      LlapSerDeDataBuffer[][] colData = si.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) {
          boolean canLock = lockBuffer(streamData[k], false); // false - not in cache yet
          assert canLock;
          streamData[k].setFileCache(cache);
          cachePolicy.cache(streamData[k], priority);
          streamData[k].isCached = true;
        }
      }
    }
  }
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