| 1 16 package org.apache.commons.collections.bidimap; 17 18 import java.util.AbstractSet ; 19 import java.util.Collection ; 20 import java.util.ConcurrentModificationException ; 21 import java.util.Iterator ; 22 import java.util.Map ; 23 import java.util.NoSuchElementException ; 24 import java.util.Set ; 25 26 import org.apache.commons.collections.BidiMap; 27 import org.apache.commons.collections.KeyValue; 28 import org.apache.commons.collections.MapIterator; 29 import org.apache.commons.collections.OrderedBidiMap; 30 import org.apache.commons.collections.OrderedIterator; 31 import org.apache.commons.collections.OrderedMapIterator; 32 import org.apache.commons.collections.iterators.EmptyOrderedMapIterator; 33 import org.apache.commons.collections.keyvalue.UnmodifiableMapEntry; 34 35 75 public class TreeBidiMap implements OrderedBidiMap { 76 77 private static final int KEY = 0; 78 private static final int VALUE = 1; 79 private static final int MAPENTRY = 2; 80 private static final int INVERSEMAPENTRY = 3; 81 private static final int SUM_OF_INDICES = KEY + VALUE; 82 private static final int FIRST_INDEX = 0; 83 private static final int NUMBER_OF_INDICES = 2; 84 private static final String [] dataName = new String [] { "key", "value" }; 85 86 private Node[] rootNode = new Node[2]; 87 private int nodeCount = 0; 88 private int modifications = 0; 89 private Set keySet; 90 private Set valuesSet; 91 private Set entrySet; 92 private TreeBidiMap.Inverse inverse = null; 93 94 98 public TreeBidiMap() { 99 super(); 100 } 101 102 110 public TreeBidiMap(final Map map) { 111 super(); 112 putAll(map); 113 } 114 115 121 public int size() { 122 return nodeCount; 123 } 124 125 130 public boolean isEmpty() { 131 return (nodeCount == 0); 132 } 133 134 144 public boolean containsKey(final Object key) { 145 checkKey(key); 146 return (lookup((Comparable ) key, KEY) != null); 147 } 148 149 159 public boolean containsValue(final Object value) { 160 checkValue(value); 161 return (lookup((Comparable ) value, VALUE) != null); 162 } 163 164 176 public Object get(final Object key) { 177 return doGet((Comparable ) key, KEY); 178 } 179 180 204 public Object put(final Object key, final Object value) { 205 return doPut((Comparable ) key, (Comparable ) value, KEY); 206 } 207 208 215 public void putAll(Map map) { 216 Iterator it = map.entrySet().iterator(); 217 while (it.hasNext()) { 218 Map.Entry entry = (Map.Entry ) it.next(); 219 put(entry.getKey(), entry.getValue()); 220 } 221 } 222 223 234 public Object remove(final Object key) { 235 return doRemove((Comparable ) key, KEY); 236 } 237 238 241 public void clear() { 242 modify(); 243 244 nodeCount = 0; 245 rootNode[KEY] = null; 246 rootNode[VALUE] = null; 247 } 248 249 262 public Object getKey(final Object value) { 263 return doGet((Comparable ) value, VALUE); 264 } 265 266 277 public Object removeValue(final Object value) { 278 return doRemove((Comparable ) value, VALUE); 279 } 280 281 288 public Object firstKey() { 289 if (nodeCount == 0) { 290 throw new NoSuchElementException ("Map is empty"); 291 } 292 return leastNode(rootNode[KEY], KEY).getKey(); 293 } 294 295 301 public Object lastKey() { 302 if (nodeCount == 0) { 303 throw new NoSuchElementException ("Map is empty"); 304 } 305 return greatestNode(rootNode[KEY], KEY).getKey(); 306 } 307 308 316 public Object nextKey(Object key) { 317 checkKey(key); 318 Node node = nextGreater(lookup((Comparable ) key, KEY), KEY); 319 return (node == null ? null : node.getKey()); 320 } 321 322 330 public Object previousKey(Object key) { 331 checkKey(key); 332 Node node = nextSmaller(lookup((Comparable ) key, KEY), KEY); 333 return (node == null ? null : node.getKey()); 334 } 335 336 349 public Set keySet() { 350 if (keySet == null) { 351 keySet = new View(this, KEY, KEY); 352 } 353 return keySet; 354 } 355 356 370 public Collection values() { 371 if (valuesSet == null) { 372 valuesSet = new View(this, KEY, VALUE); 373 } 374 return valuesSet; 375 } 376 377 392 public Set entrySet() { 393 if (entrySet == null) { 394 return new EntryView(this, KEY, MAPENTRY); 395 } 396 return entrySet; 397 } 398 399 407 public MapIterator mapIterator() { 408 if (isEmpty()) { 409 return EmptyOrderedMapIterator.INSTANCE; 410 } 411 return new ViewMapIterator(this, KEY); 412 } 413 414 421 public OrderedMapIterator orderedMapIterator() { 422 if (isEmpty()) { 423 return EmptyOrderedMapIterator.INSTANCE; 424 } 425 return new ViewMapIterator(this, KEY); 426 } 427 428 434 public BidiMap inverseBidiMap() { 435 return inverseOrderedBidiMap(); 436 } 437 438 443 public OrderedBidiMap inverseOrderedBidiMap() { 444 if (inverse == null) { 445 inverse = new Inverse(this); 446 } 447 return inverse; 448 } 449 450 457 public boolean equals(Object obj) { 458 return this.doEquals(obj, KEY); 459 } 460 461 466 public int hashCode() { 467 return this.doHashCode(KEY); 468 } 469 470 475 public String toString() { 476 return this.doToString(KEY); 477 } 478 479 489 private Object doGet(final Comparable obj, final int index) { 490 checkNonNullComparable(obj, index); 491 Node node = lookup(obj, index); 492 return ((node == null) ? null : node.getData(oppositeIndex(index))); 493 } 494 495 503 private Object doPut(final Comparable key, final Comparable value, final int index) { 504 checkKeyAndValue(key, value); 505 506 Object prev = (index == KEY ? doGet(key, KEY) : doGet(value, VALUE)); 508 doRemove(key, KEY); 509 doRemove(value, VALUE); 510 511 Node node = rootNode[KEY]; 512 if (node == null) { 513 Node root = new Node(key, value); 515 rootNode[KEY] = root; 516 rootNode[VALUE] = root; 517 grow(); 518 519 } else { 520 while (true) { 522 int cmp = compare(key, node.getData(KEY)); 523 524 if (cmp == 0) { 525 throw new IllegalArgumentException ("Cannot store a duplicate key (\"" + key + "\") in this Map"); 527 } else if (cmp < 0) { 528 if (node.getLeft(KEY) != null) { 529 node = node.getLeft(KEY); 530 } else { 531 Node newNode = new Node(key, value); 532 533 insertValue(newNode); 534 node.setLeft(newNode, KEY); 535 newNode.setParent(node, KEY); 536 doRedBlackInsert(newNode, KEY); 537 grow(); 538 539 break; 540 } 541 } else { if (node.getRight(KEY) != null) { 543 node = node.getRight(KEY); 544 } else { 545 Node newNode = new Node(key, value); 546 547 insertValue(newNode); 548 node.setRight(newNode, KEY); 549 newNode.setParent(node, KEY); 550 doRedBlackInsert(newNode, KEY); 551 grow(); 552 553 break; 554 } 555 } 556 } 557 } 558 return prev; 559 } 560 561 571 private Object doRemove(final Comparable o, final int index) { 572 Node node = lookup(o, index); 573 Object rval = null; 574 if (node != null) { 575 rval = node.getData(oppositeIndex(index)); 576 doRedBlackDelete(node); 577 } 578 return rval; 579 } 580 581 589 private Node lookup(final Comparable data, final int index) { 590 Node rval = null; 591 Node node = rootNode[index]; 592 593 while (node != null) { 594 int cmp = compare(data, node.getData(index)); 595 if (cmp == 0) { 596 rval = node; 597 break; 598 } else { 599 node = (cmp < 0) ? node.getLeft(index) : node.getRight(index); 600 } 601 } 602 603 return rval; 604 } 605 606 613 private Node nextGreater(final Node node, final int index) { 614 Node rval = null; 615 if (node == null) { 616 rval = null; 617 } else if (node.getRight(index) != null) { 618 rval = leastNode(node.getRight(index), index); 621 } else { 622 Node parent = node.getParent(index); 629 Node child = node; 630 631 while ((parent != null) && (child == parent.getRight(index))) { 632 child = parent; 633 parent = parent.getParent(index); 634 } 635 rval = parent; 636 } 637 return rval; 638 } 639 640 647 private Node nextSmaller(final Node node, final int index) { 648 Node rval = null; 649 if (node == null) { 650 rval = null; 651 } else if (node.getLeft(index) != null) { 652 rval = greatestNode(node.getLeft(index), index); 655 } else { 656 Node parent = node.getParent(index); 663 Node child = node; 664 665 while ((parent != null) && (child == parent.getLeft(index))) { 666 child = parent; 667 parent = parent.getParent(index); 668 } 669 rval = parent; 670 } 671 return rval; 672 } 673 674 681 private static int oppositeIndex(final int index) { 682 return SUM_OF_INDICES - index; 686 } 687 688 697 private static int compare(final Comparable o1, final Comparable o2) { 698 return o1.compareTo(o2); 699 } 700 701 709 private static Node leastNode(final Node node, final int index) { 710 Node rval = node; 711 if (rval != null) { 712 while (rval.getLeft(index) != null) { 713 rval = rval.getLeft(index); 714 } 715 } 716 return rval; 717 } 718 719 726 private static Node greatestNode(final Node node, final int index) { 727 Node rval = node; 728 if (rval != null) { 729 while (rval.getRight(index) != null) { 730 rval = rval.getRight(index); 731 } 732 } 733 return rval; 734 } 735 736 744 private static void copyColor(final Node from, final Node to, final int index) { 745 if (to != null) { 746 if (from == null) { 747 to.setBlack(index); 749 } else { 750 to.copyColor(from, index); 751 } 752 } 753 } 754 755 762 private static boolean isRed(final Node node, final int index) { 763 return ((node == null) ? false : node.isRed(index)); 764 } 765 766 773 private static boolean isBlack(final Node node, final int index) { 774 return ((node == null) ? true : node.isBlack(index)); 775 } 776 777 783 private static void makeRed(final Node node, final int index) { 784 if (node != null) { 785 node.setRed(index); 786 } 787 } 788 789 795 private static void makeBlack(final Node node, final int index) { 796 if (node != null) { 797 node.setBlack(index); 798 } 799 } 800 801 808 private static Node getGrandParent(final Node node, final int index) { 809 return getParent(getParent(node, index), index); 810 } 811 812 819 private static Node getParent(final Node node, final int index) { 820 return ((node == null) ? null : node.getParent(index)); 821 } 822 823 830 private static Node getRightChild(final Node node, final int index) { 831 return (node == null) ? null : node.getRight(index); 832 } 833 834 841 private static Node getLeftChild(final Node node, final int index) { 842 return (node == null) ? null : node.getLeft(index); 843 } 844 845 856 private static boolean isLeftChild(final Node node, final int index) { 857 return (node == null) 858 ? true 859 : ((node.getParent(index) == null) ? 860 false : (node == node.getParent(index).getLeft(index))); 861 } 862 863 874 private static boolean isRightChild(final Node node, final int index) { 875 return (node == null) 876 ? true 877 : ((node.getParent(index) == null) ? 878 false : (node == node.getParent(index).getRight(index))); 879 } 880 881 887 private void rotateLeft(final Node node, final int index) { 888 Node rightChild = node.getRight(index); 889 node.setRight(rightChild.getLeft(index), index); 890 891 if (rightChild.getLeft(index) != null) { 892 rightChild.getLeft(index).setParent(node, index); 893 } 894 rightChild.setParent(node.getParent(index), index); 895 896 if (node.getParent(index) == null) { 897 rootNode[index] = rightChild; 899 } else if (node.getParent(index).getLeft(index) == node) { 900 node.getParent(index).setLeft(rightChild, index); 901 } else { 902 node.getParent(index).setRight(rightChild, index); 903 } 904 905 rightChild.setLeft(node, index); 906 node.setParent(rightChild, index); 907 } 908 909 915 private void rotateRight(final Node node, final int index) { 916 Node leftChild = node.getLeft(index); 917 node.setLeft(leftChild.getRight(index), index); 918 if (leftChild.getRight(index) != null) { 919 leftChild.getRight(index).setParent(node, index); 920 } 921 leftChild.setParent(node.getParent(index), index); 922 923 if (node.getParent(index) == null) { 924 rootNode[index] = leftChild; 926 } else if (node.getParent(index).getRight(index) == node) { 927 node.getParent(index).setRight(leftChild, index); 928 |