@since 28.1
(
Range<K> range,
@Nullable V value,
BiFunction<? super V, ? super @Nullable V, ? extends @Nullable V> remappingFunction)
| 281 | * @since 28.1 |
| 282 | */ |
| 283 | @Override |
| 284 | public void merge( |
| 285 | Range<K> range, |
| 286 | @Nullable V value, |
| 287 | BiFunction<? super V, ? super @Nullable V, ? extends @Nullable V> remappingFunction) { |
| 288 | checkNotNull(range); |
| 289 | checkNotNull(remappingFunction); |
| 290 | |
| 291 | if (range.isEmpty()) { |
| 292 | return; |
| 293 | } |
| 294 | split(range.lowerBound); |
| 295 | split(range.upperBound); |
| 296 | |
| 297 | // Due to the splitting of any entries spanning the range bounds, we know that any entry with a |
| 298 | // lower bound in the merge range is entirely contained by the merge range. |
| 299 | Set<Entry<Cut<K>, RangeMapEntry<K, V>>> entriesInMergeRange = |
| 300 | entriesByLowerBound.subMap(range.lowerBound, range.upperBound).entrySet(); |
| 301 | |
| 302 | // Create entries mapping any unmapped ranges in the merge range to the specified value. |
| 303 | ImmutableMap.Builder<Cut<K>, RangeMapEntry<K, V>> gaps = ImmutableMap.builder(); |
| 304 | if (value != null) { |
| 305 | Iterator<Entry<Cut<K>, RangeMapEntry<K, V>>> backingItr = entriesInMergeRange.iterator(); |
| 306 | Cut<K> lowerBound = range.lowerBound; |
| 307 | while (backingItr.hasNext()) { |
| 308 | RangeMapEntry<K, V> entry = backingItr.next().getValue(); |
| 309 | Cut<K> upperBound = entry.getLowerBound(); |
| 310 | if (!lowerBound.equals(upperBound)) { |
| 311 | gaps.put(lowerBound, new RangeMapEntry<K, V>(lowerBound, upperBound, value)); |
| 312 | } |
| 313 | lowerBound = entry.getUpperBound(); |
| 314 | } |
| 315 | if (!lowerBound.equals(range.upperBound)) { |
| 316 | gaps.put(lowerBound, new RangeMapEntry<K, V>(lowerBound, range.upperBound, value)); |
| 317 | } |
| 318 | } |
| 319 | |
| 320 | // Remap all existing entries in the merge range. |
| 321 | Iterator<Entry<Cut<K>, RangeMapEntry<K, V>>> backingItr = entriesInMergeRange.iterator(); |
| 322 | while (backingItr.hasNext()) { |
| 323 | Entry<Cut<K>, RangeMapEntry<K, V>> entry = backingItr.next(); |
| 324 | V newValue = remappingFunction.apply(entry.getValue().getValue(), value); |
| 325 | if (newValue == null) { |
| 326 | backingItr.remove(); |
| 327 | } else { |
| 328 | entry.setValue( |
| 329 | new RangeMapEntry<K, V>( |
| 330 | entry.getValue().getLowerBound(), entry.getValue().getUpperBound(), newValue)); |
| 331 | } |
| 332 | } |
| 333 | |
| 334 | entriesByLowerBound.putAll(gaps.build()); |
| 335 | } |
| 336 | |
| 337 | @Override |
| 338 | public Map<Range<K>, V> asMapOfRanges() { |
nothing calls this directly
no test coverage detected