1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.collections4.trie;
18
19 import java.io.Serializable;
20 import java.util.AbstractMap;
21 import java.util.Map;
22 import java.util.Objects;
23
24 import org.apache.commons.collections4.Trie;
25
26
27
28
29
30
31
32
33
34 public abstract class AbstractBitwiseTrie<K, V> extends AbstractMap<K, V>
35 implements Trie<K, V>, Serializable {
36
37
38
39
40
41
42
43 abstract static class BasicEntry<K, V> implements Map.Entry<K, V>, Serializable {
44
45 private static final long serialVersionUID = -944364551314110330L;
46
47
48
49
50 protected K key;
51
52
53
54
55 protected V value;
56
57 BasicEntry(final K key) {
58 this.key = key;
59 }
60
61 BasicEntry(final K key, final V value) {
62 this.key = key;
63 this.value = value;
64 }
65
66 @Override
67 public boolean equals(final Object o) {
68 if (o == this) {
69 return true;
70 }
71 if (!(o instanceof Map.Entry)) {
72 return false;
73 }
74
75 final Map.Entry<?, ?> other = (Map.Entry<?, ?>) o;
76 if (compare(key, other.getKey())
77 && compare(value, other.getValue())) {
78 return true;
79 }
80 return false;
81 }
82
83 @Override
84 public K getKey() {
85 return key;
86 }
87
88 @Override
89 public V getValue() {
90 return value;
91 }
92
93 @Override
94 public int hashCode() {
95 return (getKey() == null ? 0 : getKey().hashCode()) ^
96 (getValue() == null ? 0 : getValue().hashCode());
97 }
98
99
100
101
102
103
104
105
106 public V setKeyValue(final K key, final V value) {
107 this.key = key;
108 return setValue(value);
109 }
110
111 @Override
112 public V setValue(final V value) {
113 final V previous = this.value;
114 this.value = value;
115 return previous;
116 }
117
118 @Override
119 public String toString() {
120 return key + "=" + value;
121 }
122 }
123
124 private static final long serialVersionUID = 5826987063535505652L;
125
126
127
128
129 static boolean compare(final Object a, final Object b) {
130 return Objects.equals(a, b);
131 }
132
133
134
135
136 private final KeyAnalyzer<? super K> keyAnalyzer;
137
138
139
140
141
142
143 protected AbstractBitwiseTrie(final KeyAnalyzer<? super K> keyAnalyzer) {
144 this.keyAnalyzer = Objects.requireNonNull(keyAnalyzer, "keyAnalyzer");
145 }
146
147
148
149
150 final int bitIndex(final K key, final K foundKey) {
151 return keyAnalyzer.bitIndex(key, 0, lengthInBits(key), foundKey, 0, lengthInBits(foundKey));
152 }
153
154
155
156
157
158
159 final int bitsPerElement() {
160 return keyAnalyzer.bitsPerElement();
161 }
162
163
164
165
166 @SuppressWarnings("unchecked")
167 final K castKey(final Object key) {
168 return (K) key;
169 }
170
171
172
173
174 final boolean compareKeys(final K key, final K other) {
175 if (key == null) {
176 return other == null;
177 }
178 if (other == null) {
179 return false;
180 }
181
182 return keyAnalyzer.compare(key, other) == 0;
183 }
184
185
186
187
188
189 protected KeyAnalyzer<? super K> getKeyAnalyzer() {
190 return keyAnalyzer;
191 }
192
193
194
195
196
197
198 final boolean isBitSet(final K key, final int bitIndex, final int lengthInBits) {
199 if (key == null) {
200 return false;
201 }
202 return keyAnalyzer.isBitSet(key, bitIndex, lengthInBits);
203 }
204
205
206
207
208
209
210 final int lengthInBits(final K key) {
211 if (key == null) {
212 return 0;
213 }
214
215 return keyAnalyzer.lengthInBits(key);
216 }
217
218 @Override
219 public String toString() {
220 final StringBuilder buffer = new StringBuilder();
221 buffer.append("Trie[").append(size()).append("]={\n");
222 for (final Map.Entry<K, V> entry : entrySet()) {
223 buffer.append(" ").append(entry).append("\n");
224 }
225 buffer.append("}\n");
226 return buffer.toString();
227 }
228 }