1 11 package org.eclipse.core.internal.indexing; 12 13 import java.util.HashSet ; 14 15 class IndexNode extends IndexedStoreObject { 16 17 18 public static final int SIZE = MAXIMUM_OBJECT_SIZE; 19 public static final int TYPE = 3; 20 21 22 private static final int EntriesFieldOffset = 64; 23 private static final int EntriesFieldSize = SIZE - EntriesFieldOffset; 24 private static final FieldDef NodeType = new FieldDef(FieldDef.F_INT, 2, 2); 25 private static final FieldDef AnchorAddress = new FieldDef(FieldDef.F_BYTES, 4, 4); 26 private static final FieldDef ParentAddress = new FieldDef(FieldDef.F_BYTES, 8, 4); 27 private static final FieldDef PreviousAddress = new FieldDef(FieldDef.F_BYTES, 12, 4); 28 private static final FieldDef NextAddress = new FieldDef(FieldDef.F_BYTES, 16, 4); 29 private static final FieldDef NumberOfEntries = new FieldDef(FieldDef.F_INT, 20, 2); 30 private static final FieldDef UsedSpace = new FieldDef(FieldDef.F_INT, 22, 2); 31 private static final FieldDef UsedSpaceMax = new FieldDef(FieldDef.F_INT, 24, 2); 32 private static final FieldDef EntriesField = new FieldDef(FieldDef.F_BYTES, EntriesFieldOffset, EntriesFieldSize); 33 34 35 private int nodeType; 36 private ObjectAddress anchorAddress; 37 private ObjectAddress parentAddress; 38 private ObjectAddress previousAddress; 39 private ObjectAddress nextAddress; 40 private int numberOfEntries; 41 private int usedSpace; 42 private int usedSpaceMax; 43 private Field entriesField; 44 45 46 private static final int RootNode = 1; 47 private static final int InteriorNode = 2; 48 private static final int LeafNode = 3; 49 50 51 private static final int DescriptorLength = 6; 52 53 54 private HashSet cursors = new HashSet (); 55 56 59 IndexNode(Field f, ObjectStore store, ObjectAddress address) throws ObjectStoreException { 60 super(f, store, address); 61 } 62 63 66 IndexNode(ObjectAddress anchorAddress) { 67 super(); 68 this.anchorAddress = anchorAddress; 69 this.parentAddress = ObjectAddress.Null; 70 this.previousAddress = ObjectAddress.Null; 71 this.nextAddress = ObjectAddress.Null; 72 this.usedSpace = 0; 73 this.usedSpaceMax = 0; 74 this.numberOfEntries = 0; 75 this.nodeType = RootNode; 76 this.entriesField = new Field(SIZE - EntriesFieldOffset); 77 } 78 79 82 IndexNode(ObjectAddress anchorAddress, ObjectAddress parentAddress) { 83 this(anchorAddress); 84 this.parentAddress = parentAddress; 85 this.nodeType = InteriorNode; 86 } 87 88 91 IndexNode(ObjectAddress anchorAddress, ObjectAddress parentAddress, ObjectAddress previousAddress, ObjectAddress nextAddress) { 92 this(anchorAddress, parentAddress); 93 this.previousAddress = previousAddress; 94 this.nextAddress = nextAddress; 95 this.nodeType = LeafNode; 96 } 97 98 101 void addCursor(IndexCursor cursor) { 102 cursors.add(cursor); 103 } 104 105 108 private int compareEntryToKey(int entryNumber, byte[] key) throws IndexedStoreException { 109 Field keyField = new Field(key); 110 Field entryKeyField = getKeyField(entryNumber); 111 return entryKeyField.compareTo(keyField); 112 } 113 114 117 private void compress() throws IndexedStoreException { 118 119 120 int entriesLength = entriesField.length(); 121 int descriptorBlockSize = numberOfEntries * DescriptorLength; 122 123 124 Field f2 = new Field(entriesField.length()); 125 copyEntries(entriesField, 0, numberOfEntries, f2); 126 127 128 entriesField.put(f2.get()); 129 usedSpaceMax = usedSpace; 130 131 132 int freeBlockSize = entriesLength - (descriptorBlockSize + usedSpaceMax); 133 Field f3 = entriesField.subfield(descriptorBlockSize, freeBlockSize); 134 f3.clear(); 135 setChanged(); 136 } 137 138 142 private void compress(int threshold) throws IndexedStoreException { 143 int entriesLength = entriesField.length(); 144 int descriptorBlockSize = numberOfEntries * DescriptorLength; 145 int freeBlockSize = entriesLength - (descriptorBlockSize + usedSpaceMax); 146 if (freeBlockSize >= threshold) 147 return; 148 compress(); 149 } 150 151 155 private static int copyEntries(Field sourceField, int sourceIndex, int numberOfEntries, Field targetField) { 156 157 Pointer tDescriptor = targetField.pointTo(0); 158 Pointer sDescriptor = sourceField.pointTo(sourceIndex * DescriptorLength); 159 int tEntryOffset = targetField.length(); 160 161 for (int i = 0; i < numberOfEntries; i++) { 163 164 int sEntryOffset = sDescriptor.getField(0, 2).getUInt(); 166 int keyLength = sDescriptor.getField(2, 2).getUInt(); 167 int valueLength = sDescriptor.getField(4, 2).getUInt(); 168 int entryLength = keyLength + valueLength; 169 Field sEntry = sourceField.subfield(sEntryOffset, entryLength); 170 171 tEntryOffset -= entryLength; 173 Field tEntry = targetField.subfield(tEntryOffset, entryLength); 174 tEntry.put(sEntry.get()); 175 176 tDescriptor.getField(0, 2).put(tEntryOffset); 178 tDescriptor.getField(2, 2).put(keyLength); 179 tDescriptor.getField(4, 2).put(valueLength); 180 181 tDescriptor.inc(DescriptorLength); 183 sDescriptor.inc(DescriptorLength); 184 } 185 return targetField.length() - tEntryOffset; 186 } 187 188 192 protected void insertValues(Field f) { 193 super.insertValues(f); 194 f.put(AnchorAddress, anchorAddress); 195 f.put(ParentAddress, parentAddress); 196 f.put(NextAddress, nextAddress); 197 f.put(PreviousAddress, previousAddress); 198 f.put(NodeType, nodeType); 199 f.put(NumberOfEntries, numberOfEntries); 200 f.put(UsedSpace, usedSpace); 201 f.put(UsedSpaceMax, usedSpaceMax); 202 f.put(EntriesField, entriesField); 203 } 204 205 208 void destroyChildren() throws IndexedStoreException { 209 if (!isLeaf()) { 210 for (int i = 0; i < numberOfEntries; i++) { 211 ObjectAddress childNodeAddress = new ObjectAddress(getValue(i)); 212 IndexNode childNode = acquireNode(childNodeAddress); 213 childNode.destroyChildren(); 214 childNode.release(); 215 removeObject(childNodeAddress); 216 } 217 } 218 } 219 220 223 void find(byte[] key, IndexCursor cursor) throws IndexedStoreException { 224 int i; 225 i = findLastEntryLT(key); 226 if (isLeaf()) { 227 cursor.set(address, i + 1); 228 } else if (i >= 0) { 229 IndexNode childNode = acquireNode(new ObjectAddress(getValue(i))); 230 childNode.find(key, cursor); 231 childNode.release(); 232 } else if (numberOfEntries > 0) { 233 IndexNode childNode = acquireNode(new ObjectAddress(getValue(0))); 234 childNode.find(key, cursor); 235 childNode.release(); 236 } else { 237 cursor.reset(); 238 } 239 } 240 241 244 void findFirstEntry(IndexCursor cursor) throws IndexedStoreException { 245 if (numberOfEntries == 0) { 246 cursor.reset(); 247 } else if (!isLeaf()) { 248 IndexNode childNode = acquireNode(new ObjectAddress(getValue(0))); 249 childNode.findFirstEntry(cursor); 250 childNode.release(); 251 } else { 252 cursor.set(address, 0); 253 } 254 } 255 256 259 private int findFirstEntryGT(byte[] key) throws IndexedStoreException { 260 int lo = 0; 261 int hi = numberOfEntries - 1; 262 while (lo <= hi) { 263 int i = (lo + hi) / 2; 264 int c = compareEntryToKey(i, key); 265 if (c <= 0) { 266 lo = i + 1; 267 } else { 268 hi = i - 1; 269 } 270 } 271 return lo; 272 } 273 274 277 void findLastEntry(IndexCursor cursor) throws IndexedStoreException { 278 if (numberOfEntries == 0) { 279 cursor.reset(); 280 return; 281 } 282 int i = numberOfEntries - 1; 283 if (!isLeaf()) { 284 IndexNode childNode = acquireNode(new ObjectAddress(getValue(i))); 285 childNode.findLastEntry(cursor); 286 childNode.release(); 287 } else { 288 cursor.set(address, i); 289 } 290 } 291 292 295 private int findLastEntryLT(byte[] key) throws IndexedStoreException { 296 int lo = 0; 297 int hi = numberOfEntries - 1; 298 Field keyField = new Field(key); 299 while (lo <= hi) { 300 int i = (lo + hi) / 2; 301 int c = getKeyField(i).compareTo(keyField); 302 if (c < 0) { 303 lo = i + 1; 304 } else { 305 hi = i - 1; 306 } 307 } 308 return hi; 309 } 310 311 314 private Field getDescriptor(int i) { 315 return entriesField.subfield(i * DescriptorLength, DescriptorLength); 316 } 317 318 321 private FieldArray getDescriptorArray() { 322 return entriesField.pointTo(0).getArray(DescriptorLength, DescriptorLength, numberOfEntries); 323 } 324 325 private Field getEntriesField() { 326 return entriesField; 327 } 328 329 332 byte[] getKey(int i) { 333 return getKeyField(i).get(); 334 } 335 336 339 private Field getKeyField(int i) { 340 int descriptorOff = i * DescriptorLength; 347 Buffer buffer = entriesField.buffer; 348 return entriesField.subfield(buffer.getUInt(descriptorOff, 2), buffer.getUInt(descriptorOff + 2, 2)); } 351 352 355 private Field getKeyValueField(int i) { 356 Field descriptor = getDescriptor(i); 357 int offset = descriptor.subfield(0, 2).getUInt(); 358 int keyLength = descriptor.subfield(2, 2).getUInt(); 359 int valueLength = descriptor.subfield(4, 2).getUInt(); 360 return entriesField.subfield(offset, keyLength + valueLength); 361 } 362 363 366 private byte[] getLowKey() { 367 if (numberOfEntries == 0) 368 return new byte[0]; 369 return getKey(0); 370 } 371 372 376 protected int getMinimumSize() { 377 return SIZE; 378 } 379 380 ObjectAddress getNextAddress() { 381 return nextAddress; 382 } 383 384 int getNumberOfEntries() { 385 return numberOfEntries; 386 } 387 388 391 int getNumberOfNodes() throws IndexedStoreException { 392 if (isLeaf()) 393 return 1; 394 int sum = 0; 395 for (int i = 0; i < numberOfEntries; i++) { 396 ObjectAddress childAddress = new ObjectAddress(getValue(i)); 397 IndexNode childNode = acquireNode(childAddress); 398 sum += childNode.getNumberOfNodes(); 399 childNode.release(); 400 } 401 return sum + 1; 402 } 403 404 ObjectAddress getParentAddress() { 405 return parentAddress; 406 } 407 408 ObjectAddress getPreviousAddress() { 409 return previousAddress; 410 } 411 412 416 protected int getRequiredType() { 417 return TYPE; 418 } 419 420 private int getUsedSpace() { 421 return usedSpace; 422 } 423 424 427 byte[] getValue(int i) { 428 return getValueField(i).get(); 429 } 430 431 434 private Field getValueField(int i) { 435 Field descriptor = getDescriptor(i); 436 int keyOffset = descriptor.subfield(0, 2).getUInt(); 437 int keyLength = descriptor.subfield(2, 2).getUInt(); 438 int valueLength = descriptor.subfield(4, 2).getUInt(); 439 int valueOffset = keyOffset + keyLength; 440 return entriesField.subfield(valueOffset, valueLength); 441 } 442 443 451 void insertEntry(byte[] key, byte[] value) throws IndexedStoreException { 452 int i = findFirstEntryGT(key); 453 if (isLeaf()) { 454 insertEntryBefore(i, key, value); 455 Object [] cursorArray = cursors.toArray(); 456 for (int j = 0; j < cursorArray.length; j++) { 457 IndexCursor cursor = (IndexCursor) cursorArray[j]; 458 cursor.entryInserted(i); 459 } 460 IndexAnchor anchor = acquireAnchor(anchorAddress); 461 anchor.entryInserted(this); 462 anchor.release(); 463 } else { 464 ObjectAddress childNodeAddress = null; 465 if (getNumberOfEntries() == 0) { 466 IndexNode childNode = new IndexNode(anchorAddress, address, ObjectAddress.Null, ObjectAddress.Null); 467 childNodeAddress = insertObject(childNode); 468 } else { 469 childNodeAddress = new ObjectAddress(getValue(Math.max(0, (i - 1)))); 470 } 471 IndexNode childNode = acquireNode(childNodeAddress); 472 childNode.insertEntry(key, value); 473 childNode.release(); 474 } 475 } 476 477 483 private void insertEntryBefore(int i, byte[] key, byte[] value) throws IndexedStoreException { 484 Field entries = entriesField; 485 int entriesLength = entries.length(); 486 int keyValueLength = key.length + value.length; 487 int neededSpace = keyValueLength + DescriptorLength; 488 int freeSpace = entriesLength - ((numberOfEntries * DescriptorLength) + usedSpace); 489 if (freeSpace < neededSpace) { 490 ObjectAddress newNodeAddress = split(); 491 if (i > numberOfEntries) { 492 if (!isLeaf()) { 493 ObjectAddress childAddress = new ObjectAddress(value); 494 IndexNode child = acquireNode(childAddress); 495 child.setParentAddress(newNodeAddress); 496 child.release(); 497 } 498 IndexNode newNode = acquireNode(newNodeAddress); 499 newNode.insertEntryBefore(i - getNumberOfEntries(), key, value); 500 newNode.release(); 501 } else { 502 insertEntryBefore(i, key, value); 503 } 504 return; 505 } 506 507 508 compress(neededSpace); 509 Pointer p = entries.pointTo(entriesLength - usedSpaceMax); 510 p.dec(value.length).put(value); 511 p.dec(key.length).put(key); 512 usedSpaceMax += keyValueLength; 513 usedSpace += keyValueLength; 514 515 516 Field newDescriptor = getDescriptorArray().insert(i); 517 numberOfEntries++; 518 519 520 newDescriptor.subfield(0, 2).put(entriesLength - usedSpaceMax); 521 newDescriptor.subfield(2, 2).put(key.length); 522 newDescriptor.subfield(4, 2).put(value.length); 523 524 525 if (i == 0 && !parentAddress.isNull()) { 526 IndexNode parent = acquireNode(parentAddress); 527 if (numberOfEntries == 1) { 528 parent.insertKeyForChild(address, key); 529 } else { 530 parent.updateKeyForChild(getKey(1), address, key); 531 } 532 parent.release(); 533 } 534 setChanged(); 535 } 536 537 540 private void insertKeyForChild(ObjectAddress childAddress, byte[] key) throws IndexedStoreException { 541 int i = findFirstEntryGT(key); 542 insertEntryBefore(i, key, childAddress.toByteArray()); 543 if (i == 0 && !parentAddress.isNull()) { 544 IndexNode parent = acquireNode(parentAddress); 545 parent.updateKeyForChild(getKey(1), address, key); 546 parent.release(); 547 } 548 } 549 550 boolean isInterior() { 551 return (nodeType == InteriorNode); 552 } 553 554 boolean isLeaf() { 555 return (nodeType == LeafNode); 556 } 557 558 boolean isRoot() { 559 return (nodeType == RootNode); 560 } 561 562 566 protected void extractValues(Field f) throws ObjectStoreException { 567 super.extractValues(f); 568 anchorAddress = new ObjectAddress(f.get(AnchorAddress)); 569 parentAddress = new ObjectAddress(f.get(ParentAddress)); 570 nextAddress = new ObjectAddress(f.get(NextAddress)); 571 previousAddress = new ObjectAddress(f.get(PreviousAddress)); 572 nodeType = f.getInt(NodeType); 573 numberOfEntries = f.getInt(NumberOfEntries); 574 usedSpace = f.getInt(UsedSpace); 575 usedSpaceMax = f.getInt(UsedSpaceMax); 576 entriesField = new Field(f.get(EntriesField)); 577 } 578 579 582 void removeCursor(IndexCursor cursor) { 583 cursors.remove(cursor); 584 } 585 586 590 void removeEntry(int i) throws IndexedStoreException { 591 592 593 byte[] key = getKey(i); 594 Field f = getKeyValueField(i); 595 f.clear(); 596 usedSpace -= f.length(); 597 598 599 getDescriptorArray().remove(i); 600 numberOfEntries--; 601 602 603 if (i == 0 && !parentAddress.isNull()) { 604 IndexNode parent = acquireNode(parentAddress); 605 if (numberOfEntries > 0) { 606 parent.updateKeyForChild(key, address, getKey(0)); 607 } else { 608 parent.removeKeyForChild(address); 609 } 610 parent.release(); 611 } 612 613 614 Object [] cursorArray = cursors.toArray(); 615 for (int j = 0; j < cursorArray.length; j++) { 616 IndexCursor cursor = (IndexCursor) cursorArray[j]; 617 cursor.entryRemoved(i); 618 } 619 IndexAnchor anchor = acquireAnchor(anchorAddress); 620 anchor.entryRemoved(this); 621 anchor.release(); 622 setChanged(); 623 } 624 625 628 private void removeKeyForChild(ObjectAddress childAddress) throws IndexedStoreException { 629 Field childAddressField = new Field(childAddress); 630 int i = 0; 631 while (i < numberOfEntries) { 632 if (getValueField(i).compareTo(childAddressField) == 0) 633 break; 634 i++; 635 } 636 if (i < numberOfEntries) 637 removeEntry(i); 638 } 639 640 private void setNextAddress(ObjectAddress address) { 641 nextAddress = address; 642 setChanged(); 643 } 644 645 private void setNodeType(int nodeType) { 646 this.nodeType = nodeType; 647 setChanged(); 648 } 649 650 private void setNumberOfEntries(int numberOfEntries) { 651 this.numberOfEntries = numberOfEntries; 652 setChanged(); 653 } 654 655 private void setParentAddress(ObjectAddress address) { 656 parentAddress = address; 657 setChanged(); 658 } 659 660 private void setPreviousAddress(ObjectAddress address) { 661 previousAddress = address; 662 setChanged(); 663 } 664 665 private void setUsedSpace(int usedSpace) { 666 this.usedSpace = usedSpace; 667 setChanged(); 668 } 669 670 private void setUsedSpaceMax(int usedSpaceMax) { 671 this.usedSpaceMax = usedSpaceMax; 672 setChanged(); 673 } 674 675 680 private ObjectAddress split() throws IndexedStoreException { 681 682 683 int n = numberOfEntries; 684 if (n < 2) { 685 throw new IndexedStoreException(IndexedStoreException.IndexNodeNotSplit); 686 } 687 688 693 if (isRoot()) { 694 ObjectAddress newRootNodeAddress = insertObject(new IndexNode(anchorAddress)); 695 parentAddress = newRootNodeAddress; 696 nodeType = InteriorNode; 697 IndexNode newRootNode = acquireNode(newRootNodeAddress); 698 newRootNode.insertKeyForChild(address, getLowKey()); 699 newRootNode.release(); 700 IndexAnchor anchor = acquireAnchor(anchorAddress); 701 anchor.setRootNodeAddress(newRootNodeAddress); 702 anchor.release(); 703 } 704 705 711 ObjectAddress newNodeAddress = insertObject(new IndexNode(anchorAddress, parentAddress)); 712 IndexNode newNode = acquireNode(newNodeAddress); 713 Field f1 = entriesField; 714 Field f2 = newNode.getEntriesField(); 715 int k = n / 2; 716 newNode.setUsedSpace(copyEntries(f1, n - k, k, f2)); 717 newNode.setUsedSpaceMax(newNode.getUsedSpace()); 718 newNode.setNumberOfEntries(k); 719 usedSpace = usedSpace - newNode.getUsedSpace(); 720 numberOfEntries = n - k; 721 compress(); 722 723 727 if (isLeaf()) { 728 newNode.setNodeType(LeafNode); 729 newNode.setNextAddress(nextAddress); 730 newNode.setPreviousAddress(address); 731 if (!nextAddress.isNull()) { 732 IndexNode nextNode = acquireNode(nextAddress); 733 nextNode.setPreviousAddress(newNodeAddress); 734 nextNode.release(); 735 } 736 nextAddress = newNodeAddress; 737 } 738 739 743 if (!isLeaf()) { 744 for (int i = 0; i < k; i++) { 745 ObjectAddress childAddress = new ObjectAddress(newNode.getValue(i)); 746 IndexNode childNode = acquireNode(childAddress); 747 childNode.setParentAddress(newNodeAddress); 748 childNode.release(); 749 } 750 } 751 752 756 IndexNode parentNode = acquireNode(parentAddress); 757 parentNode.insertKeyForChild(newNodeAddress, newNode.getLowKey()); 758 parentNode.release(); 759 760 761 newNode.release(); 762 763 764 Object [] cursorArray = cursors.toArray(); 765 for (int j = 0; j < cursorArray.length; j++) { 766 IndexCursor cursor = (IndexCursor) cursorArray[j]; 767 cursor.nodeSplit(); 768 } 769 setChanged(); 770 return newNodeAddress; 771 } 772 773 777 void unlink() throws IndexedStoreException { 778 if (isRoot()) { 779 IndexAnchor anchor = acquireAnchor(anchorAddress); 780 anchor.setRootNodeAddress(ObjectAddress.Null); 781 anchor.release(); 782 } 783 if (!parentAddress.isNull()) { 784 IndexNode parent = acquireNode(parentAddress); 785 parent.removeKeyForChild(address); 786 parent.release(); 787 } 788 if (!nextAddress.isNull()) { 789 IndexNode next = acquireNode(nextAddress); 790 next.setPreviousAddress(previousAddress); 791 next.release(); 792 } 793 if (!previousAddress.isNull()) { 794 IndexNode previous = acquireNode(previousAddress); 795 previous.setNextAddress(nextAddress); 796 previous.release(); 797 } 798 } 799 800 804 private void updateEntry(int i, byte[] key, byte[] value) throws IndexedStoreException { 805 806 812 Field entries = entriesField; 813 int entriesLength = entries.length(); 814 int newKeyValueLength = key.length + value.length; 815 int oldKeyValueLength = getKeyValueField(i).length(); 816 int neededSpace = newKeyValueLength - oldKeyValueLength; 817 int freeSpace = entriesLength - ((numberOfEntries * DescriptorLength) + usedSpace); 818 if (freeSpace < neededSpace) { 819 ObjectAddress newNodeAddress = split(); 820 if (i >= numberOfEntries) { 821 IndexNode newNode = acquireNode(newNodeAddress); 822 newNode.updateEntry(i - getNumberOfEntries(), key, value); 823 newNode.release(); 824 } else { 825 updateEntry(i, key, value); 826 } 827 return; 828 } 829 830 836 Field keyValueField = getKeyValueField(i); 837 keyValueField.clear(); 838 Field descriptor = getDescriptor(i); 839 descriptor.clear(); 840 usedSpace -= oldKeyValueLength; 841 compress(newKeyValueLength); 842 843 844 Pointer p = entries.pointTo(entriesLength - usedSpaceMax); 845 p.dec(value.length).put(value); 846 p.dec(key.length).put(key); 847 usedSpaceMax += newKeyValueLength; 848 usedSpace += newKeyValueLength; 849 850 851 descriptor.subfield(0, 2).put(entriesLength - usedSpaceMax); 852 descriptor.subfield(2, 2).put(key.length); 853 descriptor.subfield(4, 2).put(value.length); 854 setChanged(); 855 } 856 857 861 private void updateKeyAt(int i, byte[] key) throws IndexedStoreException { 862 updateEntry(i, key, getValue(i)); 863 } 864 865 869 private void updateKeyForChild(byte[] key, ObjectAddress childAddress, byte[] newKey) throws IndexedStoreException { 870 Field childAddressField = new Field(childAddress.toByteArray()); 871 int i = findLastEntryLT(key) + 1; 872 while (i < numberOfEntries) { 873 if (getValueField(i).compareTo(childAddressField) == 0) 874 break; 875 i++; 876 } 877 if (i < numberOfEntries) { 878 updateKeyAt(i, newKey); 879 if (i == 0 && !parentAddress.isNull()) { 880 IndexNode parent = acquireNode(parentAddress); 881 parent.updateKeyForChild(key, address, newKey); 882 parent.release(); 883 } 884 } 885 } 886 887 891 void updateValueAt(int i, byte[] value) throws IndexedStoreException { 892 updateEntry(i, getKey(i), value); 893 } 894 895 public String toString() { 896 StringBuffer b = new StringBuffer (); 897 if (isLeaf()) 898 b.append("LeafNode"); if (isRoot()) 900 b.append("RootNode"); if (isInterior()) 902 b.append("InteriorNode"); b.append("\n Address = "); b.append(address); 905 b.append("\n AnchorAddress = "); b.append(anchorAddress); 907 b.append("\n ParentAddress = "); b.append(parentAddress); 909 b.append("\n PreviousAddress = "); b.append(previousAddress); 911 b.append("\n NextAddress = "); b.append(nextAddress); 913 b.append("\n NumberOfEntries = "); b.append(numberOfEntries); 915 b.append("\n UsedSpace = "); b.append(usedSpace); 917 b.append("\n UsedSpaceMax = "); b.append(usedSpaceMax); 919 return b.toString(); 920 } 921 922 } 923 | Popular Tags |