788c2d9b66834c961b6e4d1f3ef49c5ae0c35bcf
[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.google.common.collect.ForwardingMap;
12 import java.util.Collection;
13 import java.util.Collections;
14 import java.util.Map;
15 import java.util.Set;
16 import javax.annotation.Nonnull;
17 import org.opendaylight.yangtools.triemap.MutableTrieMap;
18 import org.opendaylight.yangtools.triemap.TrieMap;
19 import org.slf4j.Logger;
20 import org.slf4j.LoggerFactory;
21
22 /**
23  * A TrieMap facade tracking modifications. Since we change structures based on
24  * their size, and determining the size of a TrieMap is expensive, we make sure
25  * to update it as we go.
26  *
27  * <p>
28  * FIXME: this map does not support modification view the keySet()/values()/entrySet() methods.
29  *
30  * @param <K> Key type
31  * @param <V> Value type
32  */
33 final class ReadWriteTrieMap<K, V> extends ForwardingMap<K, V> {
34     private static final Logger LOG = LoggerFactory.getLogger(ReadOnlyTrieMap.class);
35
36     private final MutableTrieMap<K, V> delegate;
37
38     private int size;
39
40     ReadWriteTrieMap() {
41         this.delegate = TrieMap.create();
42         this.size = 0;
43     }
44
45     ReadWriteTrieMap(final MutableTrieMap<K, V> delegate, final int size) {
46         this.delegate = Preconditions.checkNotNull(delegate);
47         this.size = size;
48     }
49
50     @Override
51     protected Map<K, V> delegate() {
52         return delegate;
53     }
54
55     Map<K, V> toReadOnly() {
56         final Map<K, V> ret = new ReadOnlyTrieMap<>(delegate, size);
57         LOG.trace("Converted read-write TrieMap {} to read-only {}", this, ret);
58         return ret;
59     }
60
61     @Override
62     public int size() {
63         return size;
64     }
65
66     @Override
67     public boolean isEmpty() {
68         return size == 0;
69     }
70
71     @Override
72     public V put(final K key, final V value) {
73         final V ret = delegate.put(key, value);
74         if (ret == null) {
75             size++;
76         }
77         return ret;
78     }
79
80     @Override
81     public V remove(final Object key) {
82         final V ret = delegate.remove(key);
83         if (ret != null) {
84             size--;
85         }
86         return ret;
87     }
88
89     @Override
90     @SuppressWarnings("checkstyle:parameterName")
91     public void putAll(@Nonnull final Map<? extends K, ? extends V> m) {
92         for (Entry<? extends K, ? extends V> e : m.entrySet()) {
93             put(e.getKey(), e.getValue());
94         }
95     }
96
97     @Override
98     public void clear() {
99         delegate.clear();
100         size = 0;
101     }
102
103     @Override
104     public Set<K> keySet() {
105         return Collections.unmodifiableSet(delegate.keySet());
106     }
107
108     @Override
109     public Collection<V> values() {
110         return Collections.unmodifiableCollection(delegate.values());
111     }
112
113     @Override
114     public Set<Entry<K, V>> entrySet() {
115         return Collections.unmodifiableSet(delegate.entrySet());
116     }
117 }