<C, P> V create(final K key, final int hash, final MapCallback<K, V, C, P> valueCreator,
        final C context, final P createParams, final boolean lockForRead) {
      // TODO: This can be optimized by having a special lock implementation
      // that will allow upgrade from read to write lock atomically. This can
      // cause a deadlock if two readers try to simultaneously upgrade, so the
      // upgrade should be a tryLock that will fall back to the usual way if
      // unsuccessful. The advantage of that approach is that "equals" calls in
      // the list can be avoided completely if tryLock succeeds (i.e. presumably
      // the common case of no overlap on a segment concurrently). OTOH it will
      // not be as efficient when get succeeds without a read lock (existing
      // entry) that will not need to wait for any writers.
      if (!lockForRead) {
        final V v = getNoLock(key, hash, true);
        if (v != null) {
          return v;
        }
      } else {
        final ReentrantReadWriteLock.ReadLock readLock = super.readLock();
        readLock.lock();
        try {
          final V v = getNoLock(key, hash, false);
          if (v != null) {
            // invoke the callback before returning
            valueCreator.oldValueRead(v);
            return v;
          }
        } finally {
          readLock.unlock();
        }
      }

      final ReentrantReadWriteLock.WriteLock writeLock = super.writeLock();
      writeLock.lock();
      try {
        int c = count;
        if (c++ > threshold) {
          rehash();
        }
        final HashEntry<K, V>[] tab = table;
        final int index = hash & (tab.length - 1);
        final HashEntry<K, V> first = tab[index];
        HashEntry<K, V> e = first;
        while (e != null && (e.getEntryHash() != hash || !equalityKeyCompare(key, e))) {
          e = e.getNextEntry();
        }

        final V currentValue;
        if (e == null) {
          ++modCount;
          currentValue = valueCreator.newValue(key, context, createParams);
          tab[index] = entryCreator.newEntry(key, hash, first, currentValue);
          count = c; // write-volatile
          return currentValue;
        } else {
          currentValue = e.getMapValue();
          if (lockForRead) {
            // invoke the callback before returning an existing value
            valueCreator.oldValueRead(currentValue);
          }
          return currentValue;
        }
      } finally {
        writeLock.unlock();
      }
    }
Added for GemFire since it stores some keys inline.
geode-core/src/main/java/org/apache/geode/internal/util/concurrent/CustomEntryConcurrentHashMap.java