1
18
19 package io.undertow.util;
20
21 import java.util.Collection;
22 import java.util.Collections;
23 import java.util.HashMap;
24 import java.util.Map;
25 import java.util.Set;
26 import java.util.concurrent.ConcurrentMap;
27
28
37 public class CopyOnWriteMap<K,V> implements ConcurrentMap<K, V> {
38
39 private volatile Map<K, V> delegate = Collections.emptyMap();
40
41 public CopyOnWriteMap() {
42 }
43
44 public CopyOnWriteMap(Map<K, V> existing) {
45 this.delegate = new HashMap<>(existing);
46 }
47
48 @Override
49 public synchronized V putIfAbsent(K key, V value) {
50 final Map<K, V> delegate = this.delegate;
51 V existing = delegate.get(key);
52 if(existing != null) {
53 return existing;
54 }
55 putInternal(key, value);
56 return null;
57 }
58
59 @Override
60 public synchronized boolean remove(Object key, Object value) {
61 final Map<K, V> delegate = this.delegate;
62 V existing = delegate.get(key);
63 if(existing.equals(value)) {
64 removeInternal(key);
65 return true;
66 }
67 return false;
68 }
69
70 @Override
71 public synchronized boolean replace(K key, V oldValue, V newValue) {
72 final Map<K, V> delegate = this.delegate;
73 V existing = delegate.get(key);
74 if(existing.equals(oldValue)) {
75 putInternal(key, newValue);
76 return true;
77 }
78 return false;
79 }
80
81 @Override
82 public synchronized V replace(K key, V value) {
83 final Map<K, V> delegate = this.delegate;
84 V existing = delegate.get(key);
85 if(existing != null) {
86 putInternal(key, value);
87 return existing;
88 }
89 return null;
90 }
91
92 @Override
93 public int size() {
94 return delegate.size();
95 }
96
97 @Override
98 public boolean isEmpty() {
99 return delegate.isEmpty();
100 }
101
102 @Override
103 public boolean containsKey(Object key) {
104 return delegate.containsKey(key);
105 }
106
107 @Override
108 public boolean containsValue(Object value) {
109 return delegate.containsValue(value);
110 }
111
112 @Override
113 public V get(Object key) {
114 return delegate.get(key);
115 }
116
117 @Override
118 public synchronized V put(K key, V value) {
119 return putInternal(key, value);
120 }
121
122 @Override
123 public synchronized V remove(Object key) {
124 return removeInternal(key);
125 }
126
127 @Override
128 public synchronized void putAll(Map<? extends K, ? extends V> m) {
129 final Map<K, V> delegate = new HashMap<>(this.delegate);
130 for(Entry<? extends K, ? extends V> e : m.entrySet()) {
131 delegate.put(e.getKey(), e.getValue());
132 }
133 this.delegate = delegate;
134 }
135
136 @Override
137 public synchronized void clear() {
138 delegate = Collections.emptyMap();
139 }
140
141 @Override
142 public Set<K> keySet() {
143 return delegate.keySet();
144 }
145
146 @Override
147 public Collection<V> values() {
148 return delegate.values();
149 }
150
151 @Override
152 public Set<Entry<K, V>> entrySet() {
153 return delegate.entrySet();
154 }
155
156
157 private V putInternal(final K key, final V value) {
158 final Map<K, V> delegate = new HashMap<>(this.delegate);
159 V existing = delegate.put(key, value);
160 this.delegate = delegate;
161 return existing;
162 }
163
164 public V removeInternal(final Object key) {
165 final Map<K, V> delegate = new HashMap<>(this.delegate);
166 V existing = delegate.remove(key);
167 this.delegate = delegate;
168 return existing;
169 }
170 }
171