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