1
16 package net.sf.ehcache.store.disk.ods;
17
18 import java.util.AbstractSet;
19 import java.util.Comparator;
20 import java.util.Iterator;
21 import java.util.SortedSet;
22 import java.util.Stack;
23
24
31 public class AATreeSet<T extends Comparable> extends AbstractSet<T> implements SortedSet<T> {
32
33 private static final Node<?> TERMINAL = new TerminalNode();
34
35 private Node<T> root = terminal();
36
37 private int size;
38 private boolean mutated;
39
40 private Node<T> item = terminal();
41 private Node<T> heir = terminal();
42 private T removed;
43
44 @Override
45 public boolean add(T o) {
46 try {
47 root = insert(root, o);
48 if (mutated) {
49 size++;
50 }
51 return mutated;
52 } finally {
53 mutated = false;
54 }
55 }
56
57 @Override
58 public boolean remove(Object o) {
59 try {
60 root = remove(root, (T) o);
61 if (mutated) {
62 size--;
63 }
64 return mutated;
65 } finally {
66 heir = terminal();
67 item = terminal();
68 mutated = false;
69 removed = null;
70 }
71 }
72
73
76 public T removeAndReturn(Object o) {
77 try {
78 root = remove(root, (T) o);
79 if (mutated) {
80 size--;
81 }
82 return removed;
83 } finally {
84 heir = terminal();
85 item = terminal();
86 mutated = false;
87 removed = null;
88 }
89 }
90
91 @Override
92 public void clear() {
93 root = terminal();
94 size = 0;
95 }
96
97 @Override
98 public Iterator<T> iterator() {
99 return new TreeIterator();
100 }
101
102 @Override
103 public int size() {
104 return size;
105 }
106
107 @Override
108 public boolean isEmpty() {
109 return root == terminal();
110 }
111
112
115 public Comparator<? super T> comparator() {
116 return null;
117 }
118
119
122 public SortedSet<T> subSet(T fromElement, T toElement) {
123 return new SubSet(fromElement, toElement);
124 }
125
126
129 public SortedSet<T> headSet(T toElement) {
130 return new SubSet(null, toElement);
131 }
132
133
136 public SortedSet<T> tailSet(T fromElement) {
137 return new SubSet(fromElement, null);
138 }
139
140
143 public T first() {
144 Node<T> leftMost = root;
145 while (leftMost.getLeft() != terminal()) {
146 leftMost = leftMost.getLeft();
147 }
148 return leftMost.getPayload();
149 }
150
151
154 public T last() {
155 Node<T> rightMost = root;
156 while (rightMost.getRight() != terminal()) {
157 rightMost = rightMost.getRight();
158 }
159 return rightMost.getPayload();
160 }
161
162
165 public T find(Object probe) {
166 return find(root, (T) probe).getPayload();
167 }
168
169 private Node<T> terminal() {
170 return (Node<T>) TERMINAL;
171 }
172
173
176 protected final Node<T> getRoot() {
177 return root;
178 }
179
180 private Node<T> find(Node<T> top, T probe) {
181 if (top == terminal()) {
182 return top;
183 } else {
184 int direction = top.compareTo(probe);
185 if (direction > 0) {
186 return find(top.getLeft(), probe);
187 } else if (direction < 0) {
188 return find(top.getRight(), probe);
189 } else {
190 return top;
191 }
192 }
193 }
194
195 private Node<T> insert(Node<T> top, T data) {
196 if (top == terminal()) {
197 mutated = true;
198 return createNode(data);
199 } else {
200 int direction = top.compareTo(data);
201 if (direction > 0) {
202 top.setLeft(insert(top.getLeft(), data));
203 } else if (direction < 0) {
204 top.setRight(insert(top.getRight(), data));
205 } else {
206 return top;
207 }
208 top = skew(top);
209 top = split(top);
210 return top;
211 }
212 }
213
214 private Node<T> createNode(T data) {
215 if (data instanceof Node<?>) {
216 return (Node<T>) data;
217 } else {
218 return new TreeNode<T>(data);
219 }
220 }
221
222 private Node<T> remove(Node<T> top, T data) {
223 if (top != terminal()) {
224 int direction = top.compareTo(data);
225
226 heir = top;
227 if (direction > 0) {
228 top.setLeft(remove(top.getLeft(), data));
229 } else {
230 item = top;
231 top.setRight(remove(top.getRight(), data));
232 }
233
234 if (top == heir) {
235 if (item != terminal() && item.compareTo(data) == 0) {
236 mutated = true;
237 item.swapPayload(top);
238 removed = top.getPayload();
239 top = top.getRight();
240 }
241 } else {
242 if (top.getLeft().getLevel() < top.getLevel() - 1 || top.getRight().getLevel() < top.getLevel() - 1) {
243 if (top.getRight().getLevel() > top.decrementLevel()) {
244 top.getRight().setLevel(top.getLevel());
245 }
246
247 top = skew(top);
248 top.setRight(skew(top.getRight()));
249 top.getRight().setRight(skew(top.getRight().getRight()));
250 top = split(top);
251 top.setRight(split(top.getRight()));
252 }
253 }
254 }
255 return top;
256 }
257
258 private static <T> Node<T> skew(Node<T> top) {
259 if (top.getLeft().getLevel() == top.getLevel() && top.getLevel() != 0) {
260 Node<T> save = top.getLeft();
261 top.setLeft(save.getRight());
262 save.setRight(top);
263 top = save;
264 }
265
266 return top;
267 }
268
269 private static <T> Node<T> split(Node<T> top) {
270 if (top.getRight().getRight().getLevel() == top.getLevel() && top.getLevel() != 0) {
271 Node<T> save = top.getRight();
272 top.setRight(save.getLeft());
273 save.setLeft(top);
274 top = save;
275 top.incrementLevel();
276 }
277
278 return top;
279 }
280
281
284 public static interface Node<E> {
285
286
289 public int compareTo(E data);
290
291
294 public void setLeft(Node<E> node);
295
296
299 public void setRight(Node<E> node);
300
301
304 public Node<E> getLeft();
305
306
309 public Node<E> getRight();
310
311
314 public int getLevel();
315
316
319 public void setLevel(int value);
320
321
324 public int decrementLevel();
325
326
329 public int incrementLevel();
330
331
334 public void swapPayload(Node<E> with);
335
336
339 public E getPayload();
340 }
341
342
345 public abstract static class AbstractTreeNode<E> implements Node<E> {
346
347 private Node<E> left;
348 private Node<E> right;
349 private int level;
350
351
354 public AbstractTreeNode() {
355 this(1);
356 }
357
358 private AbstractTreeNode(int level) {
359 this.left = (Node<E>) TERMINAL;
360 this.right = (Node<E>) TERMINAL;
361 this.level = level;
362 }
363
364
367 public void setLeft(Node<E> node) {
368 left = node;
369 }
370
371
374 public void setRight(Node<E> node) {
375 right = node;
376 }
377
378
381 public Node<E> getLeft() {
382 return left;
383 }
384
385
388 public Node<E> getRight() {
389 return right;
390 }
391
392
395 public int getLevel() {
396 return level;
397 }
398
399
402 public void setLevel(int value) {
403 level = value;
404 }
405
406
409 public int decrementLevel() {
410 return --level;
411 }
412
413
416 public int incrementLevel() {
417 return ++level;
418 }
419 }
420
421
424 private static final class TreeNode<E extends Comparable> extends AbstractTreeNode<E> {
425
426 private E payload;
427
428 public TreeNode(E payload) {
429 super();
430 this.payload = payload;
431 }
432
433 public int compareTo(E data) {
434 return payload.compareTo(data);
435 }
436
437 public void swapPayload(Node<E> node) {
438 if (node instanceof TreeNode<?>) {
439 TreeNode<E> treeNode = (TreeNode<E>) node;
440 E temp = treeNode.payload;
441 treeNode.payload = this.payload;
442 this.payload = temp;
443 } else {
444 throw new IllegalArgumentException();
445 }
446 }
447
448 public E getPayload() {
449 return payload;
450 }
451 }
452
453
456 private static final class TerminalNode<E> extends AbstractTreeNode<E> {
457
458 TerminalNode() {
459 super(0);
460 super.setLeft(this);
461 super.setRight(this);
462 }
463
464 public int compareTo(E data) {
465 return 0;
466 }
467
468 @Override
469 public void setLeft(Node<E> right) {
470 if (right != TERMINAL) {
471 throw new AssertionError();
472 }
473 }
474
475 @Override
476 public void setRight(Node<E> left) {
477 if (left != TERMINAL) {
478 throw new AssertionError();
479 }
480 }
481
482 @Override
483 public void setLevel(int value) {
484 throw new AssertionError();
485 }
486
487 @Override
488 public int decrementLevel() {
489 throw new AssertionError();
490 }
491
492 @Override
493 public int incrementLevel() {
494 throw new AssertionError();
495 }
496
497 public void swapPayload(Node<E> payload) {
498 throw new AssertionError();
499 }
500
501 public E getPayload() {
502 return null;
503 }
504 }
505
506
509 private class SubSet extends AbstractSet<T> implements SortedSet<T> {
510
511 private final T start;
512 private final T end;
513
514 SubSet(T start, T end) {
515 this.start = start;
516 this.end = end;
517 }
518
519 @Override
520 public boolean add(T o) {
521 if (inRange(o)) {
522 return AATreeSet.this.add(o);
523 } else {
524 throw new IllegalArgumentException();
525 }
526 }
527
528 @Override
529 public boolean remove(Object o) {
530 if (inRange((T) o)) {
531 return remove(o);
532 } else {
533 return false;
534 }
535 }
536
537 @Override
538 public void clear() {
539 throw new UnsupportedOperationException();
540 }
541
542 @Override
543 public Iterator<T> iterator() {
544 if (end == null) {
545 return new SubTreeIterator(start, end);
546 } else {
547 throw new UnsupportedOperationException();
548 }
549 }
550
551 @Override
552 public int size() {
553 throw new UnsupportedOperationException();
554 }
555
556 @Override
557 public boolean isEmpty() {
558 return !iterator().hasNext();
559 }
560
561 public Comparator<? super T> comparator() {
562 return null;
563 }
564
565 public SortedSet<T> subSet(T fromElement, T toElement) {
566 if (inRangeInclusive(fromElement) && inRangeInclusive(toElement)) {
567 return new SubSet(fromElement, toElement);
568 } else {
569 throw new IllegalArgumentException();
570 }
571 }
572
573 public SortedSet<T> headSet(T toElement) {
574 if (inRangeInclusive(toElement)) {
575 return new SubSet(start, toElement);
576 } else {
577 throw new IllegalArgumentException();
578 }
579 }
580
581 public SortedSet<T> tailSet(T fromElement) {
582 if (inRangeInclusive(fromElement)) {
583 return new SubSet(fromElement, end);
584 } else {
585 throw new IllegalArgumentException();
586 }
587 }
588
589 public T first() {
590 if (start == null) {
591 return AATreeSet.this.first();
592 } else {
593 throw new UnsupportedOperationException();
594 }
595 }
596
597 public T last() {
598 if (end == null) {
599 return AATreeSet.this.last();
600 } else {
601 throw new UnsupportedOperationException();
602 }
603 }
604
605 private boolean inRange(T value) {
606 return (start == null || start.compareTo(value) <= 0) && (end == null || end.compareTo(value) > 0);
607 }
608
609 private boolean inRangeInclusive(T value) {
610 return (start == null || start.compareTo(value) <= 0) && (end == null || end.compareTo(value) >= 0);
611 }
612 }
613
614
617 private class TreeIterator implements Iterator<T> {
618
619 private final Stack<Node<T>> path = new Stack<Node<T>>();
620 private Node<T> next;
621
622 TreeIterator() {
623 path.push(terminal());
624 Node<T> leftMost = root;
625 while (leftMost.getLeft() != terminal()) {
626 path.push(leftMost);
627 leftMost = leftMost.getLeft();
628 }
629 next = leftMost;
630 }
631
632 TreeIterator(T start) {
633 path.push(terminal());
634 Node<T> current = root;
635 while (true) {
636 int direction = current.compareTo(start);
637 if (direction > 0) {
638 if (current.getLeft() == terminal()) {
639 next = current;
640 break;
641 } else {
642 path.push(current);
643 current = current.getLeft();
644 }
645 } else if (direction < 0) {
646 if (current.getRight() == terminal()) {
647 next = path.pop();
648 break;
649 } else {
650 current = current.getRight();
651 }
652 } else {
653 next = current;
654 break;
655 }
656 }
657 }
658
659 public boolean hasNext() {
660 return next != terminal();
661 }
662
663 public T next() {
664 Node<T> current = next;
665 advance();
666 return current.getPayload();
667 }
668
669 private void advance() {
670 Node<T> successor = next.getRight();
671 if (successor != terminal()) {
672 while (successor.getLeft() != terminal()) {
673 path.push(successor);
674 successor = successor.getLeft();
675 }
676 next = successor;
677 } else {
678 next = path.pop();
679 }
680 }
681
682 public void remove() {
683 throw new UnsupportedOperationException();
684 }
685
686 }
687
688
691 private class SubTreeIterator extends TreeIterator {
692 SubTreeIterator(T start, T end) {
693 super(start);
694 }
695 }
696 }
697