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 package org.spf4j.ds;
33
34 import java.util.Collection;
35 import java.util.Iterator;
36 import java.util.List;
37 import java.util.ListIterator;
38 import java.util.Objects;
39 import javax.annotation.ParametersAreNullableByDefault;
40 import org.spf4j.base.Arrays;
41
42
43
44
45
46
47 @ParametersAreNullableByDefault
48 @SuppressWarnings("checkstyle:VisibilityModifier")
49 public class SimpleStackNullSupport<T>
50 implements List<T> {
51
52
53
54
55 private static final int DEFAULT_SIZE = 32;
56
57
58
59
60 T[] elems;
61
62
63
64
65 int top;
66
67
68
69
70 public SimpleStackNullSupport(final int size) {
71 elems = (T[]) new Object[size];
72 top = 0;
73 }
74
75
76
77
78 public SimpleStackNullSupport() {
79 this(DEFAULT_SIZE);
80 }
81
82
83
84
85
86
87 @Override
88 public final boolean isEmpty() {
89 return top == 0;
90 }
91
92
93
94
95
96
97 public final void push(final T o) {
98 int t = top + 1;
99 ensureCapacity(t);
100 elems[top] = o;
101 top = t;
102 }
103
104
105
106
107
108 public void pushNull() {
109 int t = top + 1;
110 ensureCapacity(t);
111 top = t;
112 }
113
114 public final int pushAndGetIdx(final T o) {
115 int t = top;
116 top++;
117 ensureCapacity(top);
118 elems[t] = o;
119 return t;
120 }
121
122 final void ensureCapacity(final int minCapacity) {
123 int oldCapacity = elems.length;
124 if (minCapacity > oldCapacity) {
125 int newCapacity = (oldCapacity * 3) / 2 + 1;
126 if (newCapacity < minCapacity) {
127 newCapacity = minCapacity;
128 }
129
130 elems = java.util.Arrays.copyOf(elems, newCapacity);
131 }
132 }
133
134
135
136
137
138
139 public final void pushAll(final T... args) {
140 if (args.length == 0) {
141 return;
142 }
143 int newTop = top + args.length;
144 ensureCapacity(newTop);
145 System.arraycopy(args, 0, elems, top, args.length);
146 top = newTop;
147 }
148
149
150
151
152
153
154 public final T pop() {
155 final T o = elems[--top];
156 elems[top] = null;
157 return o;
158 }
159
160
161 public final void remove() {
162 elems[--top] = null;
163 }
164
165 public final T[] pop(final int n) {
166 int ot = top;
167 top -= n;
168 T[] result = (T[]) new Object[n];
169 for (int i = top, j = 0; i < ot; i++, j++) {
170 result[j] = elems[i];
171 elems[i] = null;
172 }
173 return result;
174 }
175
176 public final void popTo(final T[] to, final int n) {
177 int ot = top;
178 top -= n;
179 for (int i = top, j = 0; i < ot; i++, j++) {
180 to[j] = elems[i];
181 elems[i] = null;
182 }
183 }
184
185 public final void removeFromTop(final int n) {
186 int ot = top;
187 top -= n;
188 for (int i = top; i < ot; i++) {
189 elems[i] = null;
190 }
191 }
192
193 public final T[] popUntil(final T until) {
194 int i = top - 1;
195 while (elems[i] != until) {
196 i--;
197 }
198 T[] result = java.util.Arrays.copyOfRange(elems, i + 1, top);
199 java.util.Arrays.fill(elems, i, top, null);
200 top = i;
201 return result;
202 }
203
204 public final boolean hasElements() {
205 return top > 0;
206 }
207
208
209
210
211
212
213
214 public T peek() {
215 return elems[top - 1];
216 }
217
218 public final T peekFromTop(final int n) {
219 return elems[top - 1 - n];
220 }
221
222 public final void replaceFromTop(final int n, final T value) {
223 elems[top - 1 - n] = value;
224 }
225
226 public final T[] peek(final int n) {
227 return java.util.Arrays.copyOfRange(elems, top - n, top);
228 }
229
230 public final T[] peekUntil(final T until) {
231 int i = top - 1;
232 while (elems[i] != until) {
233 i--;
234 }
235 return java.util.Arrays.copyOfRange(elems, i + 1, top);
236 }
237
238 public final T peekElemAfter(final T until) {
239 int i = top - 1;
240 while (elems[i] != until) {
241 i--;
242 }
243 return elems[i - 1];
244 }
245
246
247
248
249 @Override
250 public final void clear() {
251 for (int i = 0; i < top; i++) {
252 elems[i] = null;
253 }
254 top = 0;
255 }
256
257
258
259
260
261
262 public final int getPtr() {
263 return top;
264 }
265
266
267
268
269
270
271
272 public final T getFromPtr(final int ptr) {
273 if (ptr < 0 || ptr >= top) {
274 throw new IndexOutOfBoundsException(
275 "Trying to get from invalid index: " + ptr + " from: " + this);
276 }
277 return elems[ptr];
278 }
279
280
281
282
283
284
285
286 public final String toString(final char separator) {
287 if (top == 0) {
288 return "";
289 }
290 final StringBuilder result = new StringBuilder(32);
291 result.append(elems[0]);
292 for (int i = 1; i < top; i++) {
293 result.append(separator);
294 result.append(elems[i]);
295 }
296 return result.toString();
297 }
298
299
300
301
302 @Override
303 public String toString() {
304 return toString('.');
305 }
306
307 @Override
308 public final int size() {
309 return top;
310 }
311
312
313
314
315 @Override
316 public boolean contains(final Object o) {
317 for (int i = 0; i < top; i++) {
318 if (Objects.equals(elems[i], o)) {
319 return true;
320 }
321 }
322 return false;
323 }
324
325
326
327
328 @Override
329 public Iterator<T> iterator() {
330 throw new UnsupportedOperationException();
331 }
332
333 @Override
334 public final Object[] toArray() {
335 return java.util.Arrays.copyOf(elems, top);
336 }
337
338
339
340
341 @Override
342 public <T> T[] toArray(final T[] a) {
343 throw new UnsupportedOperationException();
344 }
345
346 @Override
347 public final boolean add(final T e) {
348 push(e);
349 return true;
350 }
351
352
353
354
355
356
357 @Override
358 public boolean remove(final Object o) {
359 if (o == null) {
360 for (int i = 0; i < top; i++) {
361 if (elems[i] == null) {
362 fastRemove(i);
363 return true;
364 }
365 }
366 } else {
367 for (int i = 0; i < top; i++) {
368 if (o.equals(elems[i])) {
369 fastRemove(i);
370 return true;
371 }
372 }
373 }
374 return false;
375 }
376
377
378
379
380 @Override
381 public boolean containsAll(final Collection<?> c) {
382 throw new UnsupportedOperationException();
383 }
384
385
386
387
388 @Override
389 public boolean addAll(final Collection<? extends T> c) {
390 throw new UnsupportedOperationException();
391 }
392
393
394
395
396 @Override
397 public boolean removeAll(final Collection<?> c) {
398 throw new UnsupportedOperationException();
399 }
400
401
402
403
404 @Override
405 public boolean retainAll(final Collection<?> c) {
406 throw new UnsupportedOperationException();
407 }
408
409
410 @Override
411 public final boolean equals(final Object obj) {
412 if (obj == null) {
413 return false;
414 }
415 if (getClass() != obj.getClass()) {
416 return false;
417 }
418 final SimpleStackNullSupport<T> other = (SimpleStackNullSupport<T>) obj;
419 if (this.top != other.top) {
420 return false;
421 }
422 return Arrays.deepEquals(this.elems, other.elems, 0, top);
423 }
424
425
426
427
428 @Override
429 public int hashCode() {
430 int hashCode = 7;
431 for (int i = 0; i < top; i++) {
432 Object obj = elems[i];
433 hashCode = 31 * hashCode + (obj == null ? 0 : obj.hashCode());
434 }
435 return hashCode;
436 }
437
438
439
440
441 @Override
442 public boolean addAll(final int index, final Collection<? extends T> c) {
443 throw new UnsupportedOperationException();
444 }
445
446 @Override
447 public final T get(final int index) {
448 return elems[index];
449 }
450
451 @Override
452 public final T set(final int index, final T element) {
453 ensureCapacity(index);
454 T result = elems[index];
455 elems[index] = element;
456 return result;
457 }
458
459
460
461
462 @Override
463 public void add(final int index, final T element) {
464 throw new UnsupportedOperationException();
465 }
466
467 @Override
468 public final T remove(final int index) {
469 if (index >= top && index < 0) {
470 throw new IndexOutOfBoundsException("Invalid index " + index + ", current size " + top);
471 }
472 T result = elems[index];
473 int next = index + 1;
474 int numMoved = top - next;
475 if (numMoved > 0) {
476 System.arraycopy(elems, next, elems, index, numMoved);
477 }
478 elems[--top] = null;
479 return result;
480 }
481
482 final void fastRemove(final int index) {
483 int next = index + 1;
484 int numMoved = top - next;
485 if (numMoved > 0) {
486 System.arraycopy(elems, next, elems, index, numMoved);
487 }
488 elems[--top] = null;
489 }
490
491
492
493
494 @Override
495 public int indexOf(final Object o) {
496 throw new UnsupportedOperationException();
497 }
498
499
500
501
502 @Override
503 public int lastIndexOf(final Object o) {
504 throw new UnsupportedOperationException();
505 }
506
507
508
509
510 @Override
511 public ListIterator<T> listIterator() {
512 throw new UnsupportedOperationException();
513 }
514
515
516
517
518 @Override
519 public ListIterator<T> listIterator(final int index) {
520 throw new UnsupportedOperationException();
521 }
522
523
524
525
526 @Override
527 public List<T> subList(final int fromIndex, final int toIndex) {
528 throw new UnsupportedOperationException();
529 }
530 }