public V compute(final K key, final BiFunction<? super K, ? super V, ? extends V> remappingFunction) { return backingMap.compute(key, remappingFunction); }
/** * Updates the progress for {@link Allocation} atomically relative to the {@code allocation}. * * <p>For any {@link Allocation}, this method <em>must</em> have been called on all of its parents * beforehand. * * @param allocation the {@link Allocation} to update progress for * @param units the units of progress * @return {@code true} if the map was updated; {@code false} if {@code allocation} was already * present. Note that this may return {@code true} even if the map was not updated if called * concurrently, but never {@code false} if the map was updated. */ boolean updateProgress(Allocation allocation, long units) { if (units == 0L) { // Puts the allocation in the map if not present, with progress initialized to 0. boolean alreadyPresent = completionMap.containsKey(allocation); completionMap.computeIfAbsent(allocation, InsertionOrderUnits::new); return !alreadyPresent; } completionMap.compute( allocation, (ignored, insertionOrderUnits) -> { if (insertionOrderUnits == null) { insertionOrderUnits = new InsertionOrderUnits(allocation); } updateInsertionOrderUnits(insertionOrderUnits, units); return insertionOrderUnits; }); return true; }
/** * If {@code key} is not already associated with a value or if {@code key} is associated with * zero, associate it with {@code newValue}. Returns the previous value associated with {@code * key}, or zero if there was no mapping for {@code key}. */ long putIfAbsent(K key, long newValue) { AtomicBoolean noValue = new AtomicBoolean(false); Long result = map.compute( key, (k, oldValue) -> { if (oldValue == null || oldValue == 0) { noValue.set(true); return newValue; } else { return oldValue; } }); return noValue.get() ? 0L : result.longValue(); }
/** * Updates the value currently associated with {@code key} with the specified function, and * returns the new value. If there is not currently a value associated with {@code key}, the * function is applied to {@code 0L}. * * @since 21.0 */ @CanIgnoreReturnValue public long updateAndGet(K key, LongUnaryOperator updaterFunction) { checkNotNull(updaterFunction); return map.compute( key, (k, value) -> updaterFunction.applyAsLong((value == null) ? 0L : value.longValue())); }
/** * If {@code key} is not already associated with a value or if {@code key} is associated with * zero, associate it with {@code newValue}. Returns the previous value associated with {@code * key}, or zero if there was no mapping for {@code key}. */ long putIfAbsent(K key, long newValue) { AtomicBoolean noValue = new AtomicBoolean(false); Long result = map.compute( key, (k, oldValue) -> { if (oldValue == null || oldValue == 0) { noValue.set(true); return newValue; } else { return oldValue; } }); return noValue.get() ? 0L : result.longValue(); }
/** * Updates the value currently associated with {@code key} with the specified function, and * returns the old value. If there is not currently a value associated with {@code key}, the * function is applied to {@code 0L}. * * @since 21.0 */ @CanIgnoreReturnValue public long getAndUpdate(K key, LongUnaryOperator updaterFunction) { checkNotNull(updaterFunction); AtomicLong holder = new AtomicLong(); map.compute( key, (k, value) -> { long oldValue = (value == null) ? 0L : value.longValue(); holder.set(oldValue); return updaterFunction.applyAsLong(oldValue); }); return holder.get(); }
V put(K k, Supplier<V> supplier) { return ((Payload<V>)map.compute(k, (k1, oldValue) -> { if (oldValue != null) { oldValue.refCount++; return oldValue; } else { return new Payload(supplier.get()); } })).v; }
/** * If {@code key} is not already associated with a value or if {@code key} is associated with * zero, associate it with {@code newValue}. Returns the previous value associated with {@code * key}, or zero if there was no mapping for {@code key}. */ long putIfAbsent(K key, long newValue) { AtomicBoolean noValue = new AtomicBoolean(false); Long result = map.compute( key, (k, oldValue) -> { if (oldValue == null || oldValue == 0) { noValue.set(true); return newValue; } else { return oldValue; } }); return noValue.get() ? 0L : result.longValue(); }
void evict() { cacheMap.forEachKey(evictParallelismThreshold, key -> cacheMap.compute(key, (key1, cacheRecord) -> { if ((null == cacheRecord) || evictor.apply(cacheRecord.getKey(), cacheRecord.getValue())) { return null; } else { if (cacheRecord.isValid(cacheTimoutNanos)) { return cacheRecord; } else { return null; } } })); }
@Override public void put(RegionInfo regionInfo, long size) { if (LOG.isTraceEnabled()) { LOG.trace("Setting space quota size for " + regionInfo + " to " + size); } // Atomic. Either sets the new size for the first time, or replaces the existing value. store.compute(regionInfo, (key,value) -> value == null ? new RegionSizeImpl(size) : value.setSize(size)); }
@Override public void incrementRegionSize(RegionInfo regionInfo, long delta) { if (LOG.isTraceEnabled()) { LOG.trace("Updating space quota size for " + regionInfo + " with a delta of " + delta); } // Atomic. Recomputes the stored value with the delta if there is one, otherwise use the delta. store.compute(regionInfo, (key,value) -> value == null ? new RegionSizeImpl(delta) : value.incrementSize(delta)); }
/** * Updates the value currently associated with {@code key} with the specified function, and * returns the new value. If there is not currently a value associated with {@code key}, the * function is applied to {@code 0L}. * * @since 21.0 */ @CanIgnoreReturnValue public long updateAndGet(K key, LongUnaryOperator updaterFunction) { checkNotNull(updaterFunction); return map.compute( key, (k, value) -> updaterFunction.applyAsLong((value == null) ? 0L : value.longValue())); }
/** * Updates the value currently associated with {@code key} with the specified function, and * returns the old value. If there is not currently a value associated with {@code key}, the * function is applied to {@code 0L}. * * @since 21.0 */ @CanIgnoreReturnValue public long getAndUpdate(K key, LongUnaryOperator updaterFunction) { checkNotNull(updaterFunction); AtomicLong holder = new AtomicLong(); map.compute( key, (k, value) -> { long oldValue = (value == null) ? 0L : value.longValue(); holder.set(oldValue); return updaterFunction.applyAsLong(oldValue); }); return holder.get(); }
/** * Updates the value currently associated with {@code key} with the specified function, and * returns the new value. If there is not currently a value associated with {@code key}, the * function is applied to {@code 0L}. * * @since 21.0 */ @CanIgnoreReturnValue public long updateAndGet(K key, LongUnaryOperator updaterFunction) { checkNotNull(updaterFunction); return map.compute( key, (k, value) -> updaterFunction.applyAsLong((value == null) ? 0L : value.longValue())); }
/** * A {@link Map#compute(Object, BiFunction)} that does not directly record any cache statistics. * * @param key key with which the specified value is to be associated * @param remappingFunction the function to compute a value * @return the new value associated with the specified key, or null if none */ V remap(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) { // ensures that the removal notification is processed after the removal has completed @SuppressWarnings({"unchecked", "rawtypes"}) V[] oldValue = (V[]) new Object[1]; RemovalCause[] cause = new RemovalCause[1]; V nv = data.compute(key, (K k, V value) -> { V newValue = remappingFunction.apply(k, value); if ((value == null) && (newValue == null)) { return null; } cause[0] = (newValue == null) ? RemovalCause.EXPLICIT : RemovalCause.REPLACED; if (hasRemovalListener() && (value != null) && (newValue != value)) { oldValue[0] = value; } return newValue; }); if (oldValue[0] != null) { notifyRemoval(key, oldValue[0], cause[0]); } return nv; }
public DruidServer addDataSegment(DataSegment segment) { // ConcurrentHashMap.compute() ensures that all actions for specific dataSource are linearizable. dataSources.compute( segment.getDataSource(), (dataSourceName, dataSource) -> { if (dataSource == null) { dataSource = new DruidDataSource(dataSourceName, ImmutableMap.of("client", "side")); } if (dataSource.addSegmentIfAbsent(segment)) { currSize.addAndGet(segment.getSize()); totalSegments.incrementAndGet(); } else { log.warn("Asked to add data segment that already exists!? server[%s], segment[%s]", getName(), segment); } return dataSource; } ); return this; }
@Override public @Nullable V put(K key, V value, boolean notifyWriter) { requireNonNull(value); // ensures that the removal notification is processed after the removal has completed @SuppressWarnings({"unchecked", "rawtypes"}) V[] oldValue = (V[]) new Object[1]; if ((writer == CacheWriter.disabledWriter()) || !notifyWriter) { oldValue[0] = data.put(key, value); } else { data.compute(key, (k, v) -> { if (value != v) { writer.write(key, value); } oldValue[0] = v; return value; }); } if (hasRemovalListener() && (oldValue[0] != null) && (oldValue[0] != value)) { notifyRemoval(key, oldValue[0], RemovalCause.REPLACED); } return oldValue[0]; }
dataSources.compute( segmentId.getDataSource(), (dataSourceName, dataSource) -> {
@Test public void shouldPickEvenly() throws Exception { int n = 4; int m = 25; Scheduler scheduler = Schedulers.newParallel("test", n); CountDownLatch latch = new CountDownLatch(m*n); ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>(); for (int i = 0; i < m * n; i++) { scheduler.schedule(() -> { String threadName = Thread.currentThread().getName(); map.compute(threadName, (name, val) -> Optional.ofNullable(val).map(x -> x+1).orElse(1)); latch.countDown(); }); } latch.await(); assertThat(map.values()).containsOnly(m); }
/** * Writes a key/value pair to the cache. * * @param key the key * @param value the value */ public void put(K key, V value) { mMap.compute(key, (k, entry) -> { onPut(key, value); if (entry == null && cacheIsFull()) { writeToBackingStore(key, value); return null; } if (entry == null || entry.mValue == null) { onCacheUpdate(key, value); return new Entry(key, value); } entry.mValue = value; entry.mReferenced = true; entry.mDirty = true; return entry; }); wakeEvictionThreadIfNecessary(); }