-
Notifications
You must be signed in to change notification settings - Fork 108
/
TrackingMap.java
150 lines (127 loc) · 4.25 KB
/
TrackingMap.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
package com.cedarsoftware.util;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* TrackingMap
*
* @author Sean Kellner
* <br>
* Copyright (c) Cedar Software LLC
* <br><br>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <br><br>
* <a href="http://www.apache.org/licenses/LICENSE-2.0">License</a>
* <br><br>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
public class TrackingMap<K, V> implements Map<K, V> {
private final Map<K, V> internalMap;
private final Set<K> readKeys;
/**
* Wrap the passed in Map with a TrackingMap.
* @param map Map to wrap
*/
public TrackingMap(Map<K, V> map) {
if (map == null)
{
throw new IllegalArgumentException("Cannot construct a TrackingMap() with null");
}
internalMap = map;
readKeys = new HashSet<>();
}
@SuppressWarnings("unchecked")
public V get(Object key) {
V value = internalMap.get(key);
readKeys.add((K) key);
return value;
}
public V put(K key, V value)
{
return internalMap.put(key, value);
}
@SuppressWarnings("unchecked")
public boolean containsKey(Object key) {
boolean containsKey = internalMap.containsKey(key);
readKeys.add((K)key);
return containsKey;
}
public void putAll(Map<? extends K, ? extends V> m) {
internalMap.putAll(m);
}
public V remove(Object key) {
readKeys.remove(key);
return internalMap.remove(key);
}
public int size() {
return internalMap.size();
}
public boolean isEmpty() {
return internalMap.isEmpty();
}
public boolean equals(Object other) {
return other instanceof Map && internalMap.equals(other);
}
public int hashCode() {
return internalMap.hashCode();
}
public String toString() {
return internalMap.toString();
}
public void clear() {
readKeys.clear();
internalMap.clear();
}
public boolean containsValue(Object value) {
return internalMap.containsValue(value);
}
public Collection<V> values() {
return internalMap.values();
}
public Set<K> keySet() {
return internalMap.keySet();
}
public Set<Entry<K, V>> entrySet() {
return internalMap.entrySet();
}
/**
* Remove the entries from the Map that have not been accessed by .get() or .containsKey().
*/
public void expungeUnused() {
internalMap.keySet().retainAll(readKeys);
}
/**
* Add the Collection of keys to the internal list of keys accessed. If there are keys
* in the passed in Map that are not included in the contained Map, the readKeys will
* exceed the keySet() of the wrapped Map.
* @param additional Collection of keys to add to the list of keys read.
*/
public void informAdditionalUsage(Collection<K> additional) {
readKeys.addAll(additional);
}
/**
* Add the used keys from the passed in TrackingMap to this TrackingMap's keysUsed. This can
* cause the readKeys to include entries that are not in wrapped Maps keys.
* @param additional TrackingMap whose used keys are to be added to this maps used keys.
*/
public void informAdditionalUsage(TrackingMap<K, V> additional) {
readKeys.addAll(additional.readKeys);
}
/**
* Fetch the Set of keys that have been accessed via .get() or .containsKey() of the contained Map.
* @return Set of the accessed (read) keys.
*/
public Set<K> keysUsed() { return readKeys; }
/**
* Fetch the Map that this TrackingMap wraps.
* @return Map the wrapped Map
*/
public Map<K, V> getWrappedMap() { return internalMap; }
}