(@Nullable V value, @Nullable K key, boolean force)
| 295 | } |
| 296 | |
| 297 | @Nullable |
| 298 | private K putInverse(@Nullable V value, @Nullable K key, boolean force) { |
| 299 | int valueHash = smearedHash(value); |
| 300 | int keyHash = smearedHash(key); |
| 301 | BiEntry<K, V> oldEntryForValue = seekByValue(value, valueHash); |
| 302 | if (oldEntryForValue != null && keyHash == oldEntryForValue.keyHash |
| 303 | && Objects.equal(key, oldEntryForValue.key)) { |
| 304 | return key; |
| 305 | } |
| 306 | BiEntry<K, V> oldEntryForKey = seekByKey(key, keyHash); |
| 307 | if (oldEntryForKey != null) { |
| 308 | if (force) { |
| 309 | delete(oldEntryForKey); |
| 310 | } else { |
| 311 | throw new IllegalArgumentException("value already present: " + key); |
| 312 | } |
| 313 | } |
| 314 | if (oldEntryForValue != null) { |
| 315 | delete(oldEntryForValue); |
| 316 | } |
| 317 | BiEntry<K, V> newEntry = new BiEntry<K, V>(key, keyHash, value, valueHash); |
| 318 | insert(newEntry, oldEntryForKey); |
| 319 | if (oldEntryForKey != null) { |
| 320 | oldEntryForKey.prevInKeyInsertionOrder = null; |
| 321 | oldEntryForKey.nextInKeyInsertionOrder = null; |
| 322 | } |
| 323 | rehashIfNecessary(); |
| 324 | return Maps.keyOrNull(oldEntryForValue); |
| 325 | } |
| 326 | |
| 327 | private void rehashIfNecessary() { |
| 328 | BiEntry<K, V>[] oldKToV = hashTableKToV; |
no test coverage detected