2 * (C) Copyright 2016 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 java.util.AbstractMap.SimpleImmutableEntry;
19 import java.util.Iterator;
20 import java.util.Map.Entry;
21 import java.util.NoSuchElementException;
22 import java.util.Optional;
25 * Similar to Scala's ListMap. Stores a linked set of entries, guaranteed to contain unique entry keys.
27 * @author Robert Varga
29 * @param <K> the type of keys
30 * @param <V> the type of values
32 final class LNodeEntries<K, V> extends LNodeEntry<K, V> {
33 // Modified during remove0 only
34 private LNodeEntries<K, V> next;
36 private LNodeEntries(final K k, final V v) {
40 private LNodeEntries(final K k, final V v, final LNodeEntries<K, V> next) {
45 static <K,V> LNodeEntries<K, V> map(final K k1, final V v1, final K k2, final V v2) {
46 return new LNodeEntries<>(k1, v1, new LNodeEntries<>(k2, v2));
49 Optional<Entry<K, V>> maybeSingleton() {
50 return next != null ? Optional.empty() : Optional.of(new SimpleImmutableEntry<>(key(), value()));
55 for (LNodeEntries<?, ?> wlk = next; wlk != null; wlk = wlk.next) {
61 LNodeEntry<K, V> findEntry(final Equivalence<? super K> equiv, final K key) {
62 // We do not perform recursion on purpose here, so we do not run out of stack if the key hashing fails.
63 LNodeEntries<K, V> head = this;
65 if (equiv.equivalent(head.key(), key)) {
70 } while (head != null);
75 LNodeEntries<K,V> insert(final K key, final V value) {
76 return new LNodeEntries<>(key, value, this);
79 LNodeEntries<K, V> replace(final LNodeEntry<K, V> entry, final V v) {
80 return new LNodeEntries<>(entry.key(), v, remove(entry));
83 LNodeEntries<K, V> remove(final LNodeEntry<K, V> entry) {
88 final LNodeEntries<K, V> ret = new LNodeEntries<>(key(), value());
90 LNodeEntries<K, V> last = ret;
91 LNodeEntries<K, V> cur = next;
93 if (entry.equals(cur)) {
98 last.next = new LNodeEntries<>(cur.key(), cur.value());
103 throw new IllegalStateException("Entry " + entry + " not found in entries " + this);
106 Iterator<Entry<K, V>> iterator() {
107 return new NodeIterator<>(this);
110 static final class NodeIterator<K,V> implements Iterator<Entry<K, V>> {
111 private LNodeEntries<K, V> n;
113 NodeIterator(final LNodeEntries<K, V> n) {
118 public boolean hasNext() {
123 public Entry<K, V> next() {
125 throw new NoSuchElementException();
128 final Entry<K, V> res = new SimpleImmutableEntry<>(n.key(), n.value());