Introduce SharedSingletonMap
[yangtools.git] / common / util / src / main / java / org / opendaylight / yangtools / util / ReadWriteTrieMap.java
1 /*
2  * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.yangtools.util;
9
10 import com.google.common.base.Preconditions;
11 import com.romix.scala.collection.concurrent.TrieMap;
12 import java.util.Collection;
13 import java.util.Collections;
14 import java.util.Map;
15 import java.util.Set;
16 import org.slf4j.Logger;
17 import org.slf4j.LoggerFactory;
18
19 /**
20  * A TrieMap facade tracking modifications. Since we change structures based on
21  * their size, and determining the size of a TrieMap is expensive, we make sure
22  * to update it as we go.
23  *
24  * FIXME: this map does not support modification view the keySet()/values()/entrySet()
25  *        methods.
26  *
27  * @param <K> Key type
28  * @param <V> Value type
29  */
30 final class ReadWriteTrieMap<K, V> implements Map<K, V> {
31     private static final Logger LOG = LoggerFactory.getLogger(ReadOnlyTrieMap.class);
32     private final TrieMap<K, V> delegate;
33     private int size;
34
35     ReadWriteTrieMap() {
36         this.delegate = new TrieMap<K, V>();
37         this.size = 0;
38     }
39
40     ReadWriteTrieMap(final TrieMap<K, V> delegate, final int size) {
41         this.delegate = Preconditions.checkNotNull(delegate);
42         this.size = size;
43     }
44
45     Map<K, V> toReadOnly() {
46         final Map<K, V> ret = new ReadOnlyTrieMap<>(delegate, size);
47         LOG.trace("Converted read-write TrieMap {} to read-only {}", this, ret);
48         return ret;
49     }
50
51     @Override
52     public int size() {
53         return size;
54     }
55
56     @Override
57     public boolean isEmpty() {
58         return size == 0;
59     }
60
61     @Override
62     public boolean containsKey(final Object key) {
63         return delegate.containsKey(key);
64     }
65
66     @Override
67     public boolean containsValue(final Object value) {
68         return delegate.containsValue(value);
69     }
70
71     @Override
72     public V get(final Object key) {
73         return delegate.get(key);
74     }
75
76     @Override
77     public V put(final K key, final V value) {
78         final V ret = delegate.put(key, value);
79         if (ret == null) {
80             size++;
81         }
82         return ret;
83     }
84
85     @Override
86     public V remove(final Object key) {
87         final V ret = delegate.remove(key);
88         if (ret != null) {
89             size--;
90         }
91         return ret;
92     }
93
94     @Override
95     public void putAll(final Map<? extends K, ? extends V> m) {
96         for (Entry<? extends K, ? extends V> e : m.entrySet()) {
97             put(e.getKey(), e.getValue());
98         }
99     }
100
101     @Override
102     public void clear() {
103         delegate.clear();
104         size = 0;
105     }
106
107     @Override
108     public Set<K> keySet() {
109         return Collections.unmodifiableSet(delegate.keySet());
110     }
111
112     @Override
113     public Collection<V> values() {
114         return Collections.unmodifiableCollection(delegate.values());
115     }
116
117     @Override
118     public Set<Entry<K, V>> entrySet() {
119         return Collections.unmodifiableSet(delegate.entrySet());
120     }
121
122     @Override
123     public boolean equals(final Object o) {
124         return delegate.equals(o);
125     }
126
127     @Override
128     public int hashCode() {
129         return delegate.hashCode();
130     }
131 }