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.
60 * The behavior is similar to what Java 8's ConcurrentHashMap does, which is probably the most consistent handling
61 * of this case without requiring expensive and revalidation.
63 private static final class MutableEntry<K, V> implements Entry<K, V> {
64 private final MutableTrieMap<K, V> map;
65 private final Entry<K, V> delegate;
67 @SuppressWarnings("null")
68 private V newValue = null;
70 MutableEntry(final MutableTrieMap<K, V> map, final Entry<K, V> delegate) {
72 this.delegate = delegate;
77 return delegate.getKey();
84 * This implementation returns the most uptodate value we have observed via this entry. It does not reflect
85 * concurrent modifications, nor does it throw {@link IllegalStateException} if the entry is removed.
89 return newValue != null ? newValue : delegate.getValue();
96 * This implementation returns the most uptodate value we have observed via this entry. It does not reflect
97 * concurrent modifications, nor does it throw {@link IllegalStateException} if the entry is removed.
100 public V setValue(final V value) {
101 final V ret = getValue();
102 map.put(getKey(), value);
108 public int hashCode() {
109 return EntryUtil.hash(getKey(), getValue());
112 @SuppressFBWarnings(value = "EQ_UNUSUAL", justification = "Equality handled by utility methods")
114 public boolean equals(final Object o) {
115 return EntryUtil.equal(o, getKey(), getValue());
119 public String toString() {
120 return EntryUtil.string(getKey(), getValue());