1
2
3
4
5
6
7
8
9
10
11
12
13 package org.eclipse.jgit.lib;
14
15 import java.util.Iterator;
16 import java.util.NoSuchElementException;
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 public class ObjectIdSubclassMap<V extends ObjectId>
33 implements Iterable<V>, ObjectIdSet {
34 private static final int INITIAL_TABLE_SIZE = 2048;
35
36 int size;
37
38 private int grow;
39
40 private int mask;
41
42 V[] table;
43
44
45
46
47 public ObjectIdSubclassMap() {
48 initTable(INITIAL_TABLE_SIZE);
49 }
50
51
52
53
54 public void clear() {
55 size = 0;
56 initTable(INITIAL_TABLE_SIZE);
57 }
58
59
60
61
62
63
64
65
66 public V get(AnyObjectId toFind) {
67 final int msk = mask;
68 int i = toFind.w1 & msk;
69 final V[] tbl = table;
70 V obj;
71
72 while ((obj = tbl[i]) != null) {
73 if (AnyObjectId.isEqual(obj, toFind)) {
74 return obj;
75 }
76 i = (i + 1) & msk;
77 }
78 return null;
79 }
80
81
82
83
84
85
86 @Override
87 public boolean contains(AnyObjectId toFind) {
88 return get(toFind) != null;
89 }
90
91
92
93
94
95
96
97
98
99
100
101
102 public <Q extends V> void add(Q newValue) {
103 if (++size == grow)
104 grow();
105 insert(newValue);
106 }
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126 public <Q extends V> V addIfAbsent(Q newValue) {
127 final int msk = mask;
128 int i = newValue.w1 & msk;
129 final V[] tbl = table;
130 V obj;
131
132 while ((obj = tbl[i]) != null) {
133 if (AnyObjectId.isEqual(obj, newValue))
134 return obj;
135 i = (i + 1) & msk;
136 }
137
138 if (++size == grow) {
139 grow();
140 insert(newValue);
141 } else {
142 tbl[i] = newValue;
143 }
144 return newValue;
145 }
146
147
148
149
150
151
152 public int size() {
153 return size;
154 }
155
156
157
158
159
160
161 public boolean isEmpty() {
162 return size == 0;
163 }
164
165
166 @Override
167 public Iterator<V> iterator() {
168 return new Iterator<>() {
169 private int found;
170
171 private int i;
172
173 @Override
174 public boolean hasNext() {
175 return found < size;
176 }
177
178 @Override
179 public V next() {
180 while (i < table.length) {
181 final V v = table[i++];
182 if (v != null) {
183 found++;
184 return v;
185 }
186 }
187 throw new NoSuchElementException();
188 }
189
190 @Override
191 public void remove() {
192 throw new UnsupportedOperationException();
193 }
194 };
195 }
196
197 private void insert(V newValue) {
198 final int msk = mask;
199 int j = newValue.w1 & msk;
200 final V[] tbl = table;
201 while (tbl[j] != null)
202 j = (j + 1) & msk;
203 tbl[j] = newValue;
204 }
205
206 private void grow() {
207 final V[] oldTable = table;
208 final int oldSize = table.length;
209
210 initTable(oldSize << 1);
211 for (int i = 0; i < oldSize; i++) {
212 final V obj = oldTable[i];
213 if (obj != null)
214 insert(obj);
215 }
216 }
217
218 private void initTable(int sz) {
219 grow = sz >> 1;
220 mask = sz - 1;
221 table = createArray(sz);
222 }
223
224 @SuppressWarnings("unchecked")
225 private final V[] createArray(int sz) {
226 return (V[]) new ObjectId[sz];
227 }
228 }