public static <T> FileCache<T> getOrAddFileSubCache(
      ConcurrentHashMap<Object, FileCache<T>> cache, Object fileKey,
      Function<Void, T> createFunc, CacheTag tag) {
    FileCache<T> newSubCache = null;
    while (true) { // Overwhelmingly executes once.
      FileCache<T> subCache = cache.get(fileKey);
      if (subCache != null) {
        if (subCache.incRef()) return subCache; // Main path - found it, incRef-ed it.
        if (newSubCache == null) {
          newSubCache = new FileCache<T>(createFunc.apply(null), fileKey, tag);
          newSubCache.incRef();
        }
        // Found a stale value we cannot incRef; try to replace it with new value.
        if (cache.replace(fileKey, subCache, newSubCache)) return newSubCache;
        continue; // Someone else replaced/removed a stale value, try again.
      }
      // No value found.
      if (newSubCache == null) {
        newSubCache = new FileCache<T>(createFunc.apply(null), fileKey, tag);
        newSubCache.incRef();
      }
      FileCache<T> oldSubCache = cache.putIfAbsent(fileKey, newSubCache);
      if (oldSubCache == null) return newSubCache; // Main path 2 - created a new file cache.
      if (oldSubCache.incRef()) return oldSubCache; // Someone created one in parallel.
      // Someone created one in parallel and then it went stale.
      if (cache.replace(fileKey, oldSubCache, newSubCache)) return newSubCache;
      // Someone else replaced/removed a parallel-added stale value, try again. Max confusion.
    }
  }
All this mess is necessary because we want to be able to remove sub-caches for fully
evicted files. It may actually be better to have non-nested map with object keys?
llap-server/src/java/org/apache/hadoop/hive/llap/cache/FileCache.java