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;
21 import java.util.Map.Entry;
24 * Mimic immutable ListMap in Scala
26 * @author Roman Levenstein <romixlev@gmail.com>
30 abstract class ListMap<K,V> {
34 static <K,V> ListMap<K, V> map(final K k, final V v, final ListMap<K, V> tail){
35 return new Node<> (k, v, tail);
38 static <K,V> ListMap<K, V> map(final K k, final V v){
39 return new Node<> (k, v, null);
42 static <K,V> ListMap<K, V> map(final K k1, final V v1, final K k2, final V v2){
43 return new Node<> (k1, v1, new Node<>(k2,v2, null));
46 public abstract int size ();
48 public abstract boolean isEmpty() ;
50 abstract public boolean contains(K k, V v);
52 abstract public boolean contains(K key);
54 abstract public Option<V> get (K key);
56 abstract public ListMap<K, V> add (K key, V value);
58 abstract public ListMap<K, V> remove (K key);
60 abstract public Iterator<Map.Entry<K, V>> iterator();
63 static class EmptyListMap<K,V> extends ListMap<K, V> {
65 public ListMap<K,V> add (final K key, final V value) {
66 return ListMap.map(key, value, null);
70 public boolean contains(final K k, final V v) {
75 public boolean contains(final K k) {
80 public ListMap<K,V> remove(final K key) {
90 public boolean isEmpty () {
95 public Option<V> get (final K key) {
96 return Option.makeOption (null);
100 public Iterator<Entry<K, V>> iterator () {
101 return new EmptyListMapIterator<> ();
104 static class EmptyListMapIterator<K,V> implements Iterator<Entry<K, V>> {
107 public boolean hasNext () {
112 public Entry<K, V> next () {
117 public void remove () {
118 throw new RuntimeException("Operation not supported");
124 static class Node<K,V> extends ListMap<K, V> {
128 Node(final K k, final V v, final ListMap<K,V> next) {
135 public ListMap<K,V> add (final K key, final V value) {
136 return ListMap.map(key, value, remove (key));
140 public boolean contains(final K k, final V v) {
141 if(k.equals (this.k) && v.equals (this.v)) {
143 } else if(next != null) {
144 return next.contains (k, v);
150 public boolean contains(final K k) {
151 if(k.equals (this.k)) {
153 } else if(next != null) {
154 return next.contains (k);
160 public ListMap<K,V> remove(final K key) {
168 private ListMap<K, V> remove0 (final K key) {
169 ListMap<K, V> n = this;
170 ListMap<K, V> newN = null;
171 ListMap<K, V> lastN = null;
173 if(n instanceof EmptyListMap) {
177 Node<K, V> nn = (Node<K, V>)n;
178 if (key.equals (nn.k)) {
183 lastN.next = ListMap.map (nn.k, nn.v, null);
186 newN = ListMap.map (nn.k, nn.v, null);
200 return 1+next.size ();
205 public boolean isEmpty () {
210 public Option<V> get (final K key) {
212 return Option.makeOption (v);
215 return next.get (key);
217 return Option.makeOption (null);
222 public Iterator<Entry<K, V>> iterator () {
223 return new NodeIterator<> (this);
226 static class NodeIterator<K,V> implements Iterator<Entry<K, V>> {
229 public NodeIterator (final Node<K, V> n) {
234 public boolean hasNext () {
235 // return n!= null && n.next != null && !(n.next instanceof EmptyListMap);
236 return n!= null && !(n instanceof EmptyListMap);
240 public Entry<K, V> next () {
241 if (n instanceof Node) {
242 Node<K, V> nn = (Node<K, V>) n;
243 Entry<K, V> res = new SimpleImmutableEntry<> (nn.k, nn.v);
252 public void remove () {
253 throw new RuntimeException("Operation not supported");