/**
  * Add an entry to the cache. The entry may or may not exist in the cache yet. This method will
  * usually mark unknown entries as cold and known entries as hot.
  *
  * @param key the key (may not be null)
  * @param value the value (may not be null)
  * @param memory the memory used for the given entry
  * @return the old value, or null if there was no resident entry
  */
 public V put(long key, V value, int memory) {
   int hash = getHash(key);
   int segmentIndex = getSegmentIndex(hash);
   Segment<V> s = segments[segmentIndex];
   // check whether resize is required: synchronize on s, to avoid
   // concurrent resizes (concurrent reads read
   // from the old segment)
   synchronized (s) {
     s = resizeIfNeeded(s, segmentIndex);
     return s.put(key, hash, value, memory);
   }
 }
 @Override
 public boolean replace(@NotNull K key, @NotNull V oldValue, @NotNull V newValue) {
   long h = hasher.hash(key);
   int segment = hasher.getSegment();
   Segment<K, V> segment2 = segments[segment];
   //noinspection SynchronizationOnLocalVariableOrMethodParameter
   synchronized (segment2) {
     V value2 = get(key);
     if (value2 != null && oldValue.equals(value2)) {
       segment2.put(h, key, newValue, true, true);
       return true;
     }
     return false;
   }
 }