private void doNotifyUnderHeapLock(LlapCacheableBuffer buffer) {
    long time = timer.incrementAndGet();
    if (LlapIoImpl.CACHE_LOGGER.isTraceEnabled()) {
      LlapIoImpl.CACHE_LOGGER.trace("Touching {} at {}", buffer, time);
    }
    // First, update buffer priority - we have just been using it.
    buffer.priority = (buffer.lastUpdate == -1) ? F0
        : touchPriority(time, buffer.lastUpdate, buffer.priority);
    buffer.lastUpdate = time;
    // Then, if the buffer was in the list, remove it.
    if (buffer.indexInHeap == LlapCacheableBuffer.IN_LIST) {
      listLock.lock();
      removeFromListAndUnlock(buffer);
    }
    // The only concurrent change that can happen when we hold the heap lock is list removal;
    // we have just ensured the item is not in the list, so we have a definite state now.
    if (buffer.indexInHeap >= 0) {
      // The buffer has lived in the heap all along. Restore heap property.
      heapifyDownUnderLock(buffer, time);
    } else if (heapSize == heap.length) {
      // The buffer is not in the (full) heap. Demote the top item of the heap into the list.
      LlapCacheableBuffer demoted = heap[0];
      listLock.lock();
      try {
        assert demoted.indexInHeap == 0; // Noone could have moved it, we have the heap lock.
        demoted.indexInHeap = LlapCacheableBuffer.IN_LIST;
        demoted.prev = null;
        if (listHead != null) {
          demoted.next = listHead;
          listHead.prev = demoted;
          listHead = demoted;
        } else {
          listHead = demoted;
          listTail = demoted;
          demoted.next = null;
        }
      } finally {
        listLock.unlock();
      }
      // Now insert the new buffer in its place and restore heap property.
      buffer.indexInHeap = 0;
      heapifyDownUnderLock(buffer, time);
    } else {
      // Heap is not full, add the buffer to the heap and restore heap property up.
      assert heapSize < heap.length : heap.length + " < " + heapSize;
      buffer.indexInHeap = heapSize;
      heapifyUpUnderLock(buffer, time);
      ++heapSize;
    }
  }
Wraps around the structures used in thread locals and buffers instances of LlapCachableBuffers in order to prevent
lock contention in LRFU during buffer ingress initiated heap access.
llap-server/src/java/org/apache/hadoop/hive/llap/cache/LowLevelLrfuCachePolicy.java