code: @Override
    public V computeIfAbsent(final K key, final Callable<V> callable) {
      Entry<K,V> e;
      for (;;) {
        e = lookupOrNewEntry(key);
        if (e.hasFreshData(clock)) {
          return returnValue(e);
        }
        synchronized (e) {
          e.waitForProcessing();
          if (e.hasFreshData(clock)) {
            return returnValue(e);
          }
          if (e.isGone()) {
            metrics.goneSpin();
            continue;
          }
          e.startProcessing(Entry.ProcessingState.COMPUTE);
          break;
        }
      }
      metrics.peekMiss();
      boolean _finished = false;
      long t = 0, t0 = 0;
      V _value;
      try {
        if (!isUpdateTimeNeeded()) {
          _value = callable.call();
        } else {
          t0 = clock.millis();
          _value = callable.call();
          if (!metrics.isDisabled()) {
            t = clock.millis();
          }
        }
        synchronized (e) {
          insertOrUpdateAndCalculateExpiry(e, _value, t0, t, t0, INSERT_STAT_PUT);
          e.processingDone();
        }
        _finished = true;
  
      } catch (RuntimeException ex) {
        throw ex;
      } catch (Exception ex) {
        throw new CacheLoaderException(ex);
      } finally {
        e.ensureAbort(_finished);
      }
      return returnValue(e);
    }
docs: Code duplicates with {@link Cache#get(Object)}