2 * (C) Copyright 2017 Pantheon Technologies, s.r.o. and others.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package org.opendaylight.yangtools.triemap;
18 import static com.google.common.base.Preconditions.checkState;
20 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
21 import java.util.Map.Entry;
24 * Specialized immutable iterator for use with {@link ImmutableEntrySet}.
26 * @author Robert Varga
28 * @param <K> the type of entry keys
29 * @param <V> the type of entry values
31 final class MutableIterator<K, V> extends AbstractIterator<K, V> {
32 private final MutableTrieMap<K, V> mutable;
34 private Entry<K, V> lastReturned;
36 MutableIterator(final MutableTrieMap<K, V> map) {
37 super(map.immutableSnapshot());
42 public void remove() {
43 checkState(lastReturned != null);
44 mutable.remove(lastReturned.getKey());
49 Entry<K, V> wrapEntry(final Entry<K, V> entry) {
51 return new MutableEntry<>(mutable, entry);
55 * A mutable view of an entry in the map. Since the backing map is concurrent, its {@link #getValue()} and
56 * {@link #setValue(Object)} methods cannot guarantee consistency with the base map and may produce surprising
57 * results when the map is concurrently modified, either directly or via another entry/iterator.
59 * The behavior is similar to what Java 8's ConcurrentHashMap does, which is probably the most consistent handling
60 * of this case without requiring expensive and revalidation.
62 private static final class MutableEntry<K, V> implements Entry<K, V> {
63 private final MutableTrieMap<K, V> map;
64 private final Entry<K, V> delegate;
66 @SuppressWarnings("null")
67 private V newValue = null;
69 MutableEntry(final MutableTrieMap<K, V> map, final Entry<K, V> delegate) {
71 this.delegate = delegate;
76 return delegate.getKey();
83 * This implementation returns the most uptodate value we have observed via this entry. It does not reflect
84 * concurrent modifications, nor does it throw {@link IllegalStateException} if the entry is removed.
88 return newValue != null ? newValue : delegate.getValue();
95 * This implementation returns the most uptodate value we have observed via this entry. It does not reflect
96 * concurrent modifications, nor does it throw {@link IllegalStateException} if the entry is removed.
99 public V setValue(final V value) {
100 final V ret = getValue();
101 map.put(getKey(), value);
107 public int hashCode() {
108 return EntryUtil.hash(getKey(), getValue());
111 @SuppressFBWarnings(value = "EQ_UNUSUAL", justification = "Equality handled by utility methods")
113 public boolean equals(final Object o) {
114 return EntryUtil.equal(o, getKey(), getValue());
118 public String toString() {
119 return EntryUtil.string(getKey(), getValue());