@Override public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) { synchronized (mutex) { delegate().replaceAll(function); } }
@Override public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) { this.delegate.replaceAll(function); inverse.delegate.clear(); Entry<K, V> broken = null; Iterator<Entry<K, V>> itr = this.delegate.entrySet().iterator(); while (itr.hasNext()) { Entry<K, V> entry = itr.next(); K k = entry.getKey(); V v = entry.getValue(); K conflict = inverse.delegate.putIfAbsent(v, k); if (conflict != null) { broken = entry; // We're definitely going to throw, but we'll try to keep the BiMap in an internally // consistent state by removing the bad entry. itr.remove(); } } if (broken != null) { throw new IllegalArgumentException("value already present: " + broken.getValue()); } }
@Override public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) { synchronized (mutex) { delegate().replaceAll(function); } }
private void cleanUp() { // invalidate row final Row deleteRow = materializedTable.get(validRowPosition); if (rowPositionCache.get(deleteRow) == validRowPosition) { // this row has no duplicates in the materialized table, // it can be removed from the cache rowPositionCache.remove(deleteRow); } materializedTable.set(validRowPosition, null); validRowPosition++; // perform clean up in batches if (validRowPosition >= overcommitThreshold) { materializedTable.subList(0, validRowPosition).clear(); // adjust all cached indexes rowPositionCache.replaceAll((k, v) -> v - validRowPosition); validRowPosition = 0; } }
@Override public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) { this.delegate.replaceAll(function); inverse.delegate.clear(); Entry<K, V> broken = null; Iterator<Entry<K, V>> itr = this.delegate.entrySet().iterator(); while (itr.hasNext()) { Entry<K, V> entry = itr.next(); K k = entry.getKey(); V v = entry.getValue(); K conflict = inverse.delegate.putIfAbsent(v, k); if (conflict != null) { broken = entry; // We're definitely going to throw, but we'll try to keep the BiMap in an internally // consistent state by removing the bad entry. itr.remove(); } } if (broken != null) { throw new IllegalArgumentException("value already present: " + broken.getValue()); } }
@Override public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) { synchronized (mutex) { delegate().replaceAll(function); } }
@Override public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) { this.delegate.replaceAll(function); inverse.delegate.clear(); Entry<K, V> broken = null; Iterator<Entry<K, V>> itr = this.delegate.entrySet().iterator(); while (itr.hasNext()) { Entry<K, V> entry = itr.next(); K k = entry.getKey(); V v = entry.getValue(); K conflict = inverse.delegate.putIfAbsent(v, k); if (conflict != null) { broken = entry; // We're definitely going to throw, but we'll try to keep the BiMap in an internally // consistent state by removing the bad entry. itr.remove(); } } if (broken != null) { throw new IllegalArgumentException("value already present: " + broken.getValue()); } }
@MapFeature.Require(absent = SUPPORTS_PUT) public void testReplaceAll_unsupportedNoOpFunction() { try { getMap().replaceAll((K k, V v) -> v); } catch (UnsupportedOperationException tolerated) { } expectUnchanged(); } }
@MapFeature.Require(SUPPORTS_PUT) public void testReplaceAllRotate() { getMap() .replaceAll( (K k, V v) -> { int index = keys().asList().indexOf(k); return values().asList().get(index + 1); }); List<Entry<K, V>> expectedEntries = new ArrayList<>(); for (Entry<K, V> entry : getSampleEntries()) { int index = keys().asList().indexOf(entry.getKey()); expectedEntries.add(Helpers.mapEntry(entry.getKey(), values().asList().get(index + 1))); } expectContents(expectedEntries); }
@MapFeature.Require(SUPPORTS_PUT) @CollectionFeature.Require(KNOWN_ORDER) public void testReplaceAllPreservesOrder() { getMap() .replaceAll( (K k, V v) -> { int index = keys().asList().indexOf(k); return values().asList().get(index + 1); }); List<Entry<K, V>> orderedEntries = getOrderedElements(); int index = 0; for (K key : getMap().keySet()) { assertEquals(orderedEntries.get(index).getKey(), key); index++; } }
@MapFeature.Require(absent = SUPPORTS_PUT) @CollectionSize.Require(ZERO) public void testReplaceAll_unsupportedByEmptyCollection() { try { getMap() .replaceAll( (K k, V v) -> { int index = keys().asList().indexOf(k); return values().asList().get(index + 1); }); } catch (UnsupportedOperationException tolerated) { } expectUnchanged(); }
@MapFeature.Require(absent = SUPPORTS_PUT) @CollectionSize.Require(absent = ZERO) public void testReplaceAll_unsupported() { try { getMap() .replaceAll( (K k, V v) -> { int index = keys().asList().indexOf(k); return values().asList().get(index + 1); }); fail( "replaceAll() should throw UnsupportedOperation if a map does " + "not support it and is not empty."); } catch (UnsupportedOperationException expected) { } expectUnchanged(); }
@CheckNoStats @Test(dataProvider = "caches") @CacheSpec(population = { Population.SINGLETON, Population.PARTIAL, Population.FULL }, removalListener = { Listener.DEFAULT, Listener.CONSUMING }) public void putAll_replace(Map<Integer, Integer> map, CacheContext context) { Map<Integer, Integer> entries = new LinkedHashMap<>(context.original()); entries.replaceAll((key, value) -> key); map.putAll(entries); assertThat(map, is(equalTo(entries))); assertThat(map, hasRemovalNotifications(context, entries.size(), RemovalCause.REPLACED)); verifyWriter(context, (verifier, writer) -> { verifier.wroteAll(entries); }); }
@CheckNoStats @Test(dataProvider = "caches", expectedExceptions = WriteException.class) @CacheSpec(implementation = Implementation.Caffeine, keys = ReferenceType.STRONG, population = { Population.SINGLETON, Population.PARTIAL, Population.FULL }, compute = Compute.SYNC, writer = Writer.EXCEPTIONAL, removalListener = Listener.REJECTING) public void replaceAll_writerFails(Map<Integer, Integer> map, CacheContext context) { try { map.replaceAll((key, value) -> context.absentValue()); } finally { assertThat(map, equalTo(context.original())); } }
@CheckNoWriter @CheckNoStats @CacheSpec(population = { Population.SINGLETON, Population.PARTIAL, Population.FULL }, removalListener = { Listener.DEFAULT, Listener.REJECTING }) @Test(dataProvider = "caches", expectedExceptions = NullPointerException.class) public void replaceAll_nullValue(Map<Integer, Integer> map, CacheContext context) { map.replaceAll((key, value) -> null); }
@CheckNoWriter @CheckNoStats @CacheSpec(removalListener = { Listener.DEFAULT, Listener.REJECTING }) @Test(dataProvider = "caches", expectedExceptions = NullPointerException.class) public void replaceAll_null(Map<Integer, Integer> map, CacheContext context) { map.replaceAll(null); }
@Test(dataProvider = "caches") @CacheSpec(population = { Population.SINGLETON, Population.PARTIAL, Population.FULL }, removalListener = { Listener.DEFAULT, Listener.CONSUMING }) public void putAll_replace(Cache<Integer, Integer> cache, CacheContext context) { Map<Integer, Integer> entries = new HashMap<>(context.original()); entries.replaceAll((key, value) -> value + 1); cache.putAll(entries); assertThat(cache.asMap(), is(equalTo(entries))); assertThat(cache, hasRemovalNotifications(context, entries.size(), RemovalCause.REPLACED)); verifyWriter(context, (verifier, writer) -> { verifier.wroteAll(entries); }); }
@CacheSpec @CheckNoWriter @CheckNoStats @Test(dataProvider = "caches") public void replaceAll_sameValue(Map<Integer, Integer> map, CacheContext context) { map.replaceAll((key, value) -> value); assertThat(map, is(equalTo(context.original()))); if (context.isGuava() || context.isAsync()) { assertThat(map, hasRemovalNotifications(context, map.size(), RemovalCause.REPLACED)); } else { assertThat(context.consumedNotifications(), hasSize(0)); } }
@CacheSpec @CheckNoStats @Test(dataProvider = "caches") public void replaceAll_differentValue(Map<Integer, Integer> map, CacheContext context) { map.replaceAll((key, value) -> key); map.forEach((key, value) -> { assertThat(value, is(equalTo(key))); verifyWriter(context, (verifier, writer) -> verifier.wrote(key, key)); }); assertThat(map, hasRemovalNotifications(context, map.size(), RemovalCause.REPLACED)); verifyWriter(context, (verifier, writer) -> verifier.writes(context.original().size())); }
Function<A, A> downstreamFinisher = (Function<A, A>) downstream.finisher(); Function<Map<K, A>, M> finisher = intermediate -> { intermediate.replaceAll((k, v) -> downstreamFinisher.apply(v)); @SuppressWarnings("unchecked") M castResult = (M) intermediate;