1 package org.modelmapper.internal.util;
2
3 import java.util.Collection;
4 import java.util.LinkedHashMap;
5 import java.util.Map;
6 import java.util.Set;
7
8 /**
9  * A thread-safe {@link LinkedHashMap} which creates a copy of the underlying map on write
10  * operations.
11  * 
12  * <p>
13  * Read operations, including iteration, do not interfere with writes since the underlying map is
14  * never modified.
15  * 
16  * @author Jonathan Halterman
17  */

18 public class CopyOnWriteLinkedHashMap<K, V> implements Map<K, V> {
19   private volatile Map<K, V> map;
20
21   public CopyOnWriteLinkedHashMap() {
22     map = new LinkedHashMap<K, V>();
23   }
24
25   public CopyOnWriteLinkedHashMap(Map<K, V> data) {
26     map = new LinkedHashMap<K, V>(data);
27   }
28
29   public synchronized void clear() {
30     map = new LinkedHashMap<K, V>();
31   }
32
33   public boolean containsKey(Object key) {
34     return map.containsKey(key);
35   }
36
37   public boolean containsValue(Object value) {
38     return map.containsValue(value);
39   }
40
41   public Set<Entry<K, V>> entrySet() {
42     return map.entrySet();
43   }
44
45   public V get(Object key) {
46     return map.get(key);
47   }
48
49   public boolean isEmpty() {
50     return map.isEmpty();
51   }
52
53   public Set<K> keySet() {
54     return map.keySet();
55   }
56
57   public synchronized V put(K key, V value) {
58     Map<K, V> newMap = new LinkedHashMap<K, V>(map);
59     V previous = newMap.put(key, value);
60     map = newMap;
61     return previous;
62   }
63
64   public synchronized void putAll(Map<? extends K, ? extends V> newData) {
65     Map<K, V> newMap = new LinkedHashMap<K, V>(map);
66     newMap.putAll(newData);
67     map = newMap;
68   }
69
70   public synchronized V remove(Object key) {
71     Map<K, V> newMap = new LinkedHashMap<K, V>(map);
72     V previous = newMap.remove(key);
73     map = newMap;
74     return previous;
75   }
76
77   public int size() {
78     return map.size();
79   }
80
81   public Collection<V> values() {
82     return map.values();
83   }
84 }