V put(K key, int hash, V value, boolean onlyIfAbsent) {
      lock();
      try {
        int c = count;
        HashEntry[] tab = table;
        int index = hash & (tab.length - 1);
        HashEntry<K, V> first = (HashEntry<K, V>) tab[index];

        for (HashEntry<K, V> e = first; e != null; e = (HashEntry<K, V>) e.next) {
          if (e.hash == hash && key.equals(e.key)) {
            V oldValue = e.value;
            if (!onlyIfAbsent) e.value = value;
            ++modCount;
            count = c; // write-volatile
            return oldValue;
          }
        }

        tab[index] = new HashEntry<K, V>(hash, key, value, first);
        ++modCount;
        ++c;
        count = c; // write-volatile
        if (c > threshold) setTable(rehash(tab));
        return null;
      } finally {
        unlock();
      }
    }
    boolean replace(K key, int hash, V oldValue, V newValue) {
      lock();
      try {
        int c = count;
        HashEntry[] tab = table;
        int index = hash & (tab.length - 1);
        HashEntry<K, V> first = (HashEntry<K, V>) tab[index];
        HashEntry<K, V> e = first;
        for (; ; ) {
          if (e == null) return false;
          if (e.hash == hash && key.equals(e.key)) break;
          e = e.next;
        }

        V v = e.value;
        if (v == null || !oldValue.equals(v)) return false;

        e.value = newValue;
        count = c; // write-volatile
        return true;

      } finally {
        unlock();
      }
    }