1 2 17 18 19 20 package org.apache.poi.hdf.model.util; 21 22 import java.util.*; 23 24 import org.apache.poi.hdf.model.hdftypes.PropertyNode; 25 26 40 41 public class BTreeSet extends AbstractSet 42 { 43 44 47 public BTreeNode root; 48 private Comparator comparator = null; 49 private int order; 50 private int size = 0; 51 52 58 59 public BTreeSet() 60 { 61 this(6); } 63 64 public BTreeSet(Collection c) 65 { 66 this(6); addAll(c); 68 } 69 70 public BTreeSet(int order) 71 { 72 this(order, null); 73 } 74 75 public BTreeSet(int order, Comparator comparator) 76 { 77 this.order = order; 78 this.comparator = comparator; 79 root = new BTreeNode(null); 80 } 81 82 83 86 public boolean add(Object x) throws IllegalArgumentException 87 { 88 if (x == null) throw new IllegalArgumentException (); 89 return root.insert(x, -1); 90 } 91 92 public boolean contains(Object x) 93 { 94 return root.includes(x); 95 } 96 97 public boolean remove(Object x) 98 { 99 if (x == null) return false; 100 return root.delete(x, -1); 101 } 102 103 public int size() 104 { 105 return size; 106 } 107 108 public void clear() 109 { 110 root = new BTreeNode(null); 111 size = 0; 112 } 113 114 public java.util.Iterator iterator() 115 { 116 return new Iterator(); 117 } 118 119 public static ArrayList findProperties(int start, int end, BTreeSet.BTreeNode root) 120 { 121 ArrayList results = new ArrayList(); 122 BTreeSet.Entry[] entries = root.entries; 123 124 for(int x = 0; x < entries.length; x++) 125 { 126 if(entries[x] != null) 127 { 128 BTreeSet.BTreeNode child = entries[x].child; 129 PropertyNode xNode = (PropertyNode)entries[x].element; 130 if(xNode != null) 131 { 132 int xStart = xNode.getStart(); 133 int xEnd = xNode.getEnd(); 134 if(xStart < end) 135 { 136 if(xStart >= start) 137 { 138 if(child != null) 139 { 140 ArrayList beforeItems = findProperties(start, end, child); 141 results.addAll(beforeItems); 142 } 143 results.add(xNode); 144 } 145 else if(start < xEnd) 146 { 147 results.add(xNode); 148 } 150 } 151 else 152 { 153 if(child != null) 154 { 155 ArrayList beforeItems = findProperties(start, end, child); 156 results.addAll(beforeItems); 157 } 158 break; 159 } 160 } 161 else if(child != null) 162 { 163 ArrayList afterItems = findProperties(start, end, child); 164 results.addAll(afterItems); 165 } 166 } 167 else 168 { 169 break; 170 } 171 } 172 return results; 173 } 174 177 private int compare(Object x, Object y) 178 { 179 return (comparator == null ? ((Comparable )x).compareTo(y) : comparator.compare(x, y)); 180 } 181 182 183 184 187 188 196 197 private class Iterator implements java.util.Iterator 198 { 199 private int index = 0; 200 private Stack parentIndex = new Stack(); private Object lastReturned = null; 202 private Object next; 203 private BTreeNode currentNode; 204 205 Iterator() 206 { 207 currentNode = firstNode(); 208 next = nextElement(); 209 } 210 211 public boolean hasNext() 212 { 213 return next != null; 214 } 215 216 public Object next() 217 { 218 if (next == null) throw new NoSuchElementException(); 219 220 lastReturned = next; 221 next = nextElement(); 222 return lastReturned; 223 } 224 225 public void remove() 226 { 227 if (lastReturned == null) throw new NoSuchElementException(); 228 229 BTreeSet.this.remove(lastReturned); 230 lastReturned = null; 231 } 232 233 private BTreeNode firstNode() 234 { 235 BTreeNode temp = BTreeSet.this.root; 236 237 while (temp.entries[0].child != null) 238 { 239 temp = temp.entries[0].child; 240 parentIndex.push(new Integer (0)); 241 } 242 243 return temp; 244 } 245 246 private Object nextElement() 247 { 248 if (currentNode.isLeaf()) 249 { 250 if (index < currentNode.nrElements) return currentNode.entries[index++].element; 251 252 else if (!parentIndex.empty()) 253 { currentNode = currentNode.parent; 255 index = ((Integer )parentIndex.pop()).intValue(); 256 257 while (index == currentNode.nrElements) 258 { 259 if (parentIndex.empty()) break; 260 currentNode = currentNode.parent; 261 index = ((Integer )parentIndex.pop()).intValue(); 262 } 263 264 if (index == currentNode.nrElements) return null; return currentNode.entries[index++].element; 266 } 267 268 else 269 { if (index == currentNode.nrElements) return null; 271 return currentNode.entries[index++].element; 272 } 273 } 274 275 else 276 { currentNode = currentNode.entries[index].child; 278 parentIndex.push(new Integer (index)); 279 280 while (currentNode.entries[0].child != null) 281 { 282 currentNode = currentNode.entries[0].child; 283 parentIndex.push(new Integer (0)); 284 } 285 286 index = 1; 287 return currentNode.entries[0].element; 288 } 289 } 290 } 291 292 293 public static class Entry 294 { 295 296 public Object element; 297 public BTreeNode child; 298 } 299 300 301 public class BTreeNode 302 { 303 304 public Entry[] entries; 305 public BTreeNode parent; 306 private int nrElements = 0; 307 private final int MIN = (BTreeSet.this.order - 1) / 2; 308 309 BTreeNode(BTreeNode parent) 310 { 311 this.parent = parent; 312 entries = new Entry[BTreeSet.this.order]; 313 entries[0] = new Entry(); 314 } 315 316 boolean insert(Object x, int parentIndex) 317 { 318 if (isFull()) 319 { Object splitNode = entries[nrElements / 2].element; 321 BTreeNode rightSibling = split(); 322 323 if (isRoot()) 324 { splitRoot(splitNode, this, rightSibling); 326 if (BTreeSet.this.compare(x, BTreeSet.this.root.entries[0].element) < 0) insert(x, 0); 328 else rightSibling.insert(x, 1); 329 } 330 331 else 332 { parent.insertSplitNode(splitNode, this, rightSibling, parentIndex); 334 if (BTreeSet.this.compare(x, parent.entries[parentIndex].element) < 0) return insert(x, parentIndex); 335 else return rightSibling.insert(x, parentIndex + 1); 336 } 337 } 338 339 else if (isLeaf()) 340 { int insertAt = childToInsertAt(x, true); 342 if (insertAt == -1) return false; else 344 { 345 insertNewElement(x, insertAt); 346 BTreeSet.this.size++; 347 return true; 348 } 349 } 350 351 else 352 { int insertAt = childToInsertAt(x, true); 354 return (insertAt == -1 ? false : entries[insertAt].child.insert(x, insertAt)); 355 } 356 return false; 357 } 358 359 boolean includes(Object x) 360 { 361 int index = childToInsertAt(x, true); 362 if (index == -1) return true; 363 if (entries[index] == null || entries[index].child == null) return false; 364 return entries[index].child.includes(x); 365 } 366 367 boolean delete(Object x, int parentIndex) 368 { 369 int i = childToInsertAt(x, true); 370 int priorParentIndex = parentIndex; 371 BTreeNode temp = this; 372 if (i != -1) 373 { 374 do 375 { 376 if (temp.entries[i] == null || temp.entries[i].child == null) return false; 377 temp = temp.entries[i].child; 378 priorParentIndex = parentIndex; 379 parentIndex = i; 380 i = temp.childToInsertAt(x, true); 381 } while (i != -1); 382 } 384 if (temp.isLeaf()) 385 { if (temp.nrElements > MIN) 387 { 388 temp.deleteElement(x); 389 BTreeSet.this.size--; 390 return true; 391 } 392 393 else 394 { temp.prepareForDeletion(parentIndex); 396 temp.deleteElement(x); 397 BTreeSet.this.size--; 398 temp.fixAfterDeletion(priorParentIndex); 399 return true; 400 } 401 } 402 403 else 404 { temp.switchWithSuccessor(x); 406 parentIndex = temp.childToInsertAt(x, false) + 1; 407 return temp.entries[parentIndex].child.delete(x, parentIndex); 408 } 409 } 410 411 412 private boolean isFull() { return nrElements == (BTreeSet.this.order - 1); } 413 414 private boolean isLeaf() { return entries[0].child == null; } 415 416 private boolean isRoot() { return parent == null; } 417 418 422 private BTreeNode split() 423 { 424 BTreeNode rightSibling = new BTreeNode(parent); 425 int index = nrElements / 2; 426 entries[index++].element = null; 427 428 for (int i = 0, nr = nrElements; index <= nr; i++, index++) 429 { 430 rightSibling.entries[i] = entries[index]; 431 if (rightSibling.entries[i] != null && rightSibling.entries[i].child != null) 432 rightSibling.entries[i].child.parent = rightSibling; 433 entries[index] = null; 434 nrElements--; 435 rightSibling.nrElements++; 436 } 437 438 rightSibling.nrElements--; return rightSibling; 440 } 441 442 446 private void splitRoot(Object splitNode, BTreeNode left, BTreeNode right) 447 { 448 BTreeNode newRoot = new BTreeNode(null); 449 newRoot.entries[0].element = splitNode; 450 newRoot.entries[0].child = left; 451 newRoot.entries[1] = new Entry(); 452 newRoot.entries[1].child = right; 453 newRoot.nrElements = 1; 454 left.parent = right.parent = newRoot; 455 BTreeSet.this.root = newRoot; 456 } 457 458 private void insertSplitNode(Object splitNode, BTreeNode left, BTreeNode right, int insertAt) 459 { 460 for (int i = nrElements; i >= insertAt; i--) entries[i + 1] = entries[i]; 461 462 entries[insertAt] = new Entry(); 463 entries[insertAt].element = splitNode; 464 entries[insertAt].child = left; 465 entries[insertAt + 1].child = right; 466 467 nrElements++; 468 } 469 470 private void insertNewElement(Object x, int insertAt) 471 { 472 473 for (int i = nrElements; i > insertAt; i--) entries[i] = entries[i - 1]; 474 475 entries[insertAt] = new Entry(); 476 entries[insertAt].element = x; 477 478 nrElements++; 479 } 480 481 490 private int childToInsertAt(Object x, boolean position) 491 { 492 int index = nrElements / 2; 493 494 if (entries[index] == null || entries[index].element == null) return index; 495 496 int lo = 0, hi = nrElements - 1; 497 while (lo <= hi) 498 { 499 if (BTreeSet.this.compare(x, entries[index].element) > 0) 500 { 501 lo = index + 1; 502 index = (hi + lo) / 2; 503 } 504 else 505 { 506 hi = index - 1; 507 index = (hi + lo) / 2; 508 } 509 } 510 511 hi++; 512 if (entries[hi] == null || entries[hi].element == null) return hi; 513 return (!position ? hi : BTreeSet.this.compare(x, entries[hi].element) == 0 ? -1 : hi); 514 } 515 516 517 private void deleteElement(Object x) 518 { 519 int index = childToInsertAt(x, false); 520 for (; index < (nrElements - 1); index++) entries[index] = entries[index + 1]; 521 522 if (nrElements == 1) entries[index] = new Entry(); else entries[index] = null; 524 525 nrElements--; 526 } 527 528 private void prepareForDeletion(int parentIndex) 529 { 530 if (isRoot()) return; 532 else if (parentIndex != 0 && parent.entries[parentIndex - 1].child.nrElements > MIN) 534 { 535 stealLeft(parentIndex); 536 return; 537 } 538 539 else if (parentIndex < entries.length && parent.entries[parentIndex + 1] != null && parent.entries[parentIndex + 1].child != null && parent.entries[parentIndex + 1].child.nrElements > MIN) 541 { 542 stealRight(parentIndex); 543 return; 544 } 545 546 else if (parentIndex != 0) { 548 mergeLeft(parentIndex); 549 return; 550 } 551 552 else mergeRight(parentIndex); 554 } 555 556 private void fixAfterDeletion(int parentIndex) 557 { 558 if (isRoot() || parent.isRoot()) return; 560 if (parent.nrElements < MIN) 561 { BTreeNode temp = parent; 563 temp.prepareForDeletion(parentIndex); 564 if (temp.parent == null) return; if (!temp.parent.isRoot() && temp.parent.nrElements < MIN) 566 { BTreeNode x = temp.parent.parent; 568 int i = 0; 569 for (; i < entries.length; i++) if (x.entries[i].child == temp.parent) break; 571 temp.parent.fixAfterDeletion(i); 572 } 573 } 574 } 575 576 private void switchWithSuccessor(Object x) 577 { 578 int index = childToInsertAt(x, false); 579 BTreeNode temp = entries[index + 1].child; 580 while (temp.entries[0] != null && temp.entries[0].child != null) temp = temp.entries[0].child; 581 Object successor = temp.entries[0].element; 582 temp.entries[0].element = entries[index].element; 583 entries[index].element = successor; 584 } 585 586 590 private void stealLeft(int parentIndex) 591 { 592 BTreeNode p = parent; 593 BTreeNode ls = parent.entries[parentIndex - 1].child; 594 595 if (isLeaf()) 596 { int add = childToInsertAt(p.entries[parentIndex - 1].element, true); 598 insertNewElement(p.entries[parentIndex - 1].element, add); 599 p.entries[parentIndex - 1].element = ls.entries[ls.nrElements - 1].element; 600 ls.entries[ls.nrElements - 1] = null; 601 ls.nrElements--; 602 } 603 604 else 605 { entries[0].element = p.entries[parentIndex - 1].element; 607 p.entries[parentIndex - 1].element = ls.entries[ls.nrElements - 1].element; 608 entries[0].child = ls.entries[ls.nrElements].child; 609 entries[0].child.parent = this; 610 ls.entries[ls.nrElements] = null; 611 ls.entries[ls.nrElements - 1].element = null; 612 nrElements++; 613 ls.nrElements--; 614 } 615 } 616 617 622 private void stealRight(int parentIndex) 623 { 624 BTreeNode p = parent; 625 BTreeNode rs = p.entries[parentIndex + 1].child; 626 627 if (isLeaf()) 628 { entries[nrElements] = new Entry(); 630 entries[nrElements].element = p.entries[parentIndex].element; 631 p.entries[parentIndex].element = rs.entries[0].element; 632 for (int i = 0; i < rs.nrElements; i++) rs.entries[i] = rs.entries[i + 1]; 633 rs.entries[rs.nrElements - 1] = null; 634 nrElements++; 635 rs.nrElements--; 636 } 637 638 else 639 { for (int i = 0; i <= nrElements; i++) entries[i] = entries[i + 1]; 641 entries[nrElements].element = p.entries[parentIndex].element; 642 p.entries[parentIndex].element = rs.entries[0].element; 643 entries[nrElements + 1] = new Entry(); 644 entries[nrElements + 1].child = rs.entries[0].child; 645 entries[nrElements + 1].child.parent = this; 646 for (int i = 0; i <= rs.nrElements; i++) rs.entries[i] = rs.entries[i + 1]; 647 rs.entries[rs.nrElements] = null; 648 nrElements++; 649 rs.nrElements--; 650 } 651 } 652 653 662 private void mergeLeft(int parentIndex) 663 { 664 BTreeNode p = parent; 665 BTreeNode ls = p.entries[parentIndex - 1].child; 666 667 if (isLeaf()) 668 { int add = childToInsertAt(p.entries[parentIndex - 1].element, true); 670 insertNewElement(p.entries[parentIndex - 1].element, add); p.entries[parentIndex - 1].element = null; 672 673 for (int i = nrElements - 1, nr = ls.nrElements; i >= 0; i--) 674 entries[i + nr] = entries[i]; 675 676 for (int i = ls.nrElements - 1; i >= 0; i--) 677 { 678 entries[i] = ls.entries[i]; 679 nrElements++; 680 } 681 682 if (p.nrElements == MIN && p != BTreeSet.this.root) 683 { 684 685 for (int x = parentIndex - 1, y = parentIndex - 2; y >= 0; x--, y--) 686 p.entries[x] = p.entries[y]; 687 p.entries[0] = new Entry(); 688 p.entries[0].child = ls; } 690 691 else 692 { 693 694 for (int x = parentIndex - 1, y = parentIndex; y <= p.nrElements; x++, y++) 695 p.entries[x] = p.entries[y]; 696 p.entries[p.nrElements] = null; 697 } 698 699 p.nrElements--; 700 701 if (p.isRoot() && p.nrElements == 0) 702 { BTreeSet.this.root = this; 704 parent = null; 705 } 706 } 707 708 else 709 { entries[0].element = p.entries[parentIndex - 1].element; 711 entries[0].child = ls.entries[ls.nrElements].child; 712 nrElements++; 713 714 for (int x = nrElements, nr = ls.nrElements; x >= 0; x--) 715 entries[x + nr] = entries[x]; 716 717 for (int x = ls.nrElements - 1; x >= 0; x--) 718 { 719 entries[x] = ls.entries[x]; 720 entries[x].child.parent = this; 721 nrElements++; 722 } 723 724 if (p.nrElements == MIN && p != BTreeSet.this.root) 725 { for (int x = parentIndex - 1, y = parentIndex - 2; y >= 0; x++, y++) 727 { 728 System.out.println(x + " " + y); 729 p.entries[x] = p.entries[y]; 730 } 731 p.entries[0] = new Entry(); 732 } 733 734 else 735 { for (int x = parentIndex - 1, y = parentIndex; y <= p.nrElements; x++, y++) 737 p.entries[x] = p.entries[y]; 738 p.entries[p.nrElements] = null; 739 } 740 741 p.nrElements--; 742 743 if (p.isRoot() && p.nrElements == 0) 744 { BTreeSet.this.root = this; 746 parent = null; 747 } 748 } 749 } 750 751 760 private void mergeRight(int parentIndex) 761 { 762 BTreeNode p = parent; 763 BTreeNode rs = p.entries[parentIndex + 1].child; 764 765 if (isLeaf()) 766 { entries[nrElements] = new Entry(); 768 entries[nrElements].element = p.entries[parentIndex].element; 769 nrElements++; 770 for (int i = 0, nr = nrElements; i < rs.nrElements; i++, nr++) 771 { 772 entries[nr] = rs.entries[i]; 773 nrElements++; 774 } 775 p.entries[parentIndex].element = p.entries[parentIndex + 1].element; 776 if (p.nrElements == MIN && p != BTreeSet.this.root) 777 { 778 for (int x = parentIndex + 1, y = parentIndex; y >= 0; x--, y--) 779 p.entries[x] = p.entries[y]; 780 p.entries[0] = new Entry(); 781 p.entries[0].child = rs; } 783 784 else 785 { 786 for (int x = parentIndex + 1, y = parentIndex + 2; y <= p.nrElements; x++, y++) 787 p.entries[x] = p.entries[y]; 788 p.entries[p.nrElements] = null; 789 } 790 791 p.nrElements--; 792 if (p.isRoot() && p.nrElements == 0) 793 { BTreeSet.this.root = this; 795 parent = null; 796 } 797 } 798 799 else 800 { 802 entries[nrElements].element = p.entries[parentIndex].element; 803 nrElements++; 804 805 for (int x = nrElements + 1, y = 0; y <= rs.nrElements; x++, y++) 806 { 807 entries[x] = rs.entries[y]; 808 rs.entries[y].child.parent = this; 809 nrElements++; 810 } 811 nrElements--; 812 813 p.entries[++parentIndex].child = this; 814 815 if (p.nrElements == MIN && p != BTreeSet.this.root) 816 { 817 for (int x = parentIndex - 1, y = parentIndex - 2; y >= 0; x--, y--) 818 p.entries[x] = p.entries[y]; 819 p.entries[0] = new Entry(); 820 } 821 822 else 823 { 824 for (int x = parentIndex - 1, y = parentIndex; y <= p.nrElements; x++, y++) 825 p.entries[x] = p.entries[y]; 826 p.entries[p.nrElements] = null; 827 } 828 829 p.nrElements--; 830 831 if (p.isRoot() && p.nrElements == 0) 832 { BTreeSet.this.root = this; 834 parent = null; 835 } 836 } 837 } 838 } 839 840 } 841 842 | Popular Tags |