1 8 9 package com.sleepycat.je.dbi; 10 11 import java.util.Comparator ; 12 import java.util.Hashtable ; 13 14 import com.sleepycat.je.Cursor; 15 import com.sleepycat.je.DatabaseEntry; 16 import com.sleepycat.je.DatabaseException; 17 import com.sleepycat.je.LockMode; 18 import com.sleepycat.je.OperationStatus; 19 import com.sleepycat.je.Transaction; 20 import com.sleepycat.je.tree.DuplicateEntryException; 21 import com.sleepycat.je.util.StringDbt; 22 23 26 public class DbCursorDuplicateTest extends DbCursorTestBase { 27 28 public DbCursorDuplicateTest() 29 throws DatabaseException { 30 31 super(); 32 } 33 34 37 public void testDuplicateCreationForward() 38 throws Throwable { 39 40 initEnv(true); 41 try { 42 doDuplicateTest(true, false); 43 } catch (Throwable t) { 44 t.printStackTrace(); 45 throw t; 46 } 47 } 48 49 52 public void testDuplicateCreationForwardKeyLast() 53 throws Throwable { 54 55 initEnv(true); 56 try { 57 doDuplicateTest(true, true); 58 } catch (Throwable t) { 59 t.printStackTrace(); 60 throw t; 61 } 62 } 63 64 67 public void testDuplicateCreationBackwards() 68 throws Throwable { 69 70 initEnv(true); 71 try { 72 doDuplicateTest(false, false); 73 } catch (Throwable t) { 74 t.printStackTrace(); 75 throw t; 76 } 77 } 78 79 84 public void testLargeGetForwardTraverseWithNormalComparisonFunction() 85 throws Throwable { 86 87 try { 88 tearDown(); 89 duplicateComparisonFunction = duplicateComparator; 90 setUp(); 91 initEnv(true); 92 doDuplicateTest(true, false); 93 } catch (Throwable t) { 94 t.printStackTrace(); 95 throw t; 96 } 97 } 98 99 104 public void testLargeGetForwardTraverseWithReverseComparisonFunction() 105 throws Throwable { 106 107 try { 108 tearDown(); 109 duplicateComparisonFunction = reverseDuplicateComparator; 110 setUp(); 111 initEnv(true); 112 doDuplicateTest(false, false); 113 } catch (Throwable t) { 114 t.printStackTrace(); 115 throw t; 116 } 117 } 118 119 124 public void testPutNoDupData() 125 throws Throwable { 126 127 try { 128 initEnv(true); 129 createRandomDuplicateData(null, false); 130 131 DataWalker dw = new DataWalker(simpleDataMap) { 132 void perData(String foundKey, String foundData) 133 throws DatabaseException { 134 135 assertEquals 136 (OperationStatus.KEYEXIST, 137 cursor.putNoDupData(new StringDbt(foundKey), 138 new StringDbt(foundData))); 139 } 140 }; 141 dw.setIgnoreDataMap(true); 142 dw.walkData(); 143 } catch (Throwable t) { 144 t.printStackTrace(); 145 throw t; 146 } 147 } 148 149 public void testPutNoDupData2() 150 throws Throwable { 151 152 try { 153 initEnv(true); 154 for (int i = 0; i < simpleKeyStrings.length; i++) { 155 OperationStatus status = 156 cursor.putNoDupData(new StringDbt("oneKey"), 157 new StringDbt(simpleDataStrings[i])); 158 assertEquals(OperationStatus.SUCCESS, status); 159 } 160 } catch (Throwable t) { 161 t.printStackTrace(); 162 throw t; 163 } 164 } 165 166 public void testAbortDuplicateTreeCreation() 167 throws Throwable { 168 169 try { 170 initEnvTransactional(true); 171 Transaction txn = exampleEnv.beginTransaction(null, null); 172 Cursor c = exampleDb.openCursor(txn, null); 173 OperationStatus status = 174 c.put(new StringDbt("oneKey"), 175 new StringDbt("firstData")); 176 assertEquals(OperationStatus.SUCCESS, status); 177 c.close(); 178 txn.commit(); 179 txn = exampleEnv.beginTransaction(null, null); 180 c = exampleDb.openCursor(txn, null); 181 status = 182 c.put(new StringDbt("oneKey"), 183 new StringDbt("secondData")); 184 assertEquals(OperationStatus.SUCCESS, status); 185 c.close(); 186 txn.abort(); 187 txn = exampleEnv.beginTransaction(null, null); 188 c = exampleDb.openCursor(txn, null); 189 DatabaseEntry keyRet = new DatabaseEntry(); 190 DatabaseEntry dataRet = new DatabaseEntry(); 191 assertEquals(OperationStatus.SUCCESS, 192 c.getFirst(keyRet, dataRet, LockMode.DEFAULT)); 193 assertEquals(1, c.count()); 194 assertEquals(OperationStatus.NOTFOUND, 195 c.getNext(keyRet, dataRet, LockMode.DEFAULT)); 196 c.close(); 197 txn.commit(); 198 } catch (Throwable t) { 199 t.printStackTrace(); 200 throw t; 201 } 202 } 203 204 211 public void testDuplicateCount() 212 throws Throwable { 213 214 try { 215 initEnv(true); 216 Hashtable dataMap = new Hashtable (); 217 218 createRandomDuplicateData(N_COUNT_TOP_KEYS, 219 N_COUNT_DUPLICATES_PER_KEY, 220 dataMap, false, true); 221 222 DataWalker dw = new DataWalker(dataMap) { 223 void perData(String foundKey, String foundData) 224 throws DatabaseException { 225 226 assertEquals(N_COUNT_DUPLICATES_PER_KEY, 227 cursor.count()); 228 } 229 }; 230 dw.setIgnoreDataMap(true); 231 dw.walkData(); 232 assertEquals(N_COUNT_DUPLICATES_PER_KEY, dw.nEntries); 233 } catch (Throwable t) { 234 t.printStackTrace(); 235 throw t; 236 } 237 } 238 239 public void testDuplicateDuplicates() 240 throws Throwable { 241 242 try { 243 initEnv(true); 244 Hashtable dataMap = new Hashtable (); 245 246 String keyString = "aaaa"; 247 String dataString = "d1d1"; 248 DatabaseEntry keyDbt = new DatabaseEntry(); 249 DatabaseEntry dataDbt = new DatabaseEntry(); 250 keyDbt.setData(keyString.getBytes()); 251 dataDbt.setData(dataString.getBytes()); 252 assertTrue(cursor.putNoDupData(keyDbt, dataDbt) == 253 OperationStatus.SUCCESS); 254 assertTrue(cursor.putNoDupData(keyDbt, dataDbt) != 255 OperationStatus.SUCCESS); 256 assertTrue(cursor.put(keyDbt, dataDbt) == 257 OperationStatus.SUCCESS); 258 dataString = "d2d2"; 259 dataDbt.setData(dataString.getBytes()); 260 assertTrue(cursor.putNoDupData(keyDbt, dataDbt) == 261 OperationStatus.SUCCESS); 262 assertTrue(cursor.putNoDupData(keyDbt, dataDbt) != 263 OperationStatus.SUCCESS); 264 assertTrue(cursor.put(keyDbt, dataDbt) == 265 OperationStatus.SUCCESS); 266 DataWalker dw = new DataWalker(dataMap) { 267 void perData(String foundKey, String foundData) { 268 } 269 }; 270 dw.setIgnoreDataMap(true); 271 dw.walkData(); 272 assertTrue(dw.nEntries == 2); 273 } catch (Throwable t) { 274 t.printStackTrace(); 275 throw t; 276 } 277 } 278 279 public void testDuplicateDuplicatesWithComparators() throws Throwable { 281 282 try { 283 tearDown(); 284 duplicateComparisonFunction = invocationCountingComparator; 285 btreeComparisonFunction = invocationCountingComparator; 286 invocationCountingComparator.setInvocationCount(0); 287 setUp(); 288 initEnv(true); 289 290 String keyString = "aaaa"; 291 String dataString = "d1d1"; 292 DatabaseEntry keyDbt = new DatabaseEntry(); 293 DatabaseEntry dataDbt = new DatabaseEntry(); 294 keyDbt.setData(keyString.getBytes()); 295 dataDbt.setData(dataString.getBytes()); 296 assertTrue(cursor.put(keyDbt, dataDbt) == 297 OperationStatus.SUCCESS); 298 assertTrue(cursor.put(keyDbt, dataDbt) == 299 OperationStatus.SUCCESS); 300 301 InvocationCountingBtreeComparator bTreeICC = 302 (InvocationCountingBtreeComparator) 303 (exampleDb.getConfig().getBtreeComparator()); 304 305 InvocationCountingBtreeComparator dupICC = 306 (InvocationCountingBtreeComparator) 307 (exampleDb.getConfig().getDuplicateComparator()); 308 309 assertTrue(bTreeICC.getInvocationCount() == 1); 310 assertTrue(dupICC.getInvocationCount() == 2); 311 } catch (Throwable t) { 312 t.printStackTrace(); 313 throw t; 314 } 315 } 316 317 public void testDuplicateReplacement() 318 throws Throwable { 319 320 try { 321 initEnv(true); 322 String keyString = "aaaa"; 323 String dataString = "d1d1"; 324 DatabaseEntry keyDbt = new DatabaseEntry(); 325 DatabaseEntry dataDbt = new DatabaseEntry(); 326 keyDbt.setData(keyString.getBytes()); 327 dataDbt.setData(dataString.getBytes()); 328 assertTrue(cursor.putNoDupData(keyDbt, dataDbt) == 329 OperationStatus.SUCCESS); 330 assertTrue(cursor.putNoDupData(keyDbt, dataDbt) != 331 OperationStatus.SUCCESS); 332 dataString = "d2d2"; 333 dataDbt.setData(dataString.getBytes()); 334 assertTrue(cursor.putNoDupData(keyDbt, dataDbt) == 335 OperationStatus.SUCCESS); 336 assertTrue(cursor.putNoDupData(keyDbt, dataDbt) != 337 OperationStatus.SUCCESS); 338 DataWalker dw = new DataWalker(null) { 339 void perData(String foundKey, String foundData) 340 throws DatabaseException { 341 342 StringDbt dataDbt = new StringDbt(); 343 dataDbt.setString(foundData); 344 assertEquals(OperationStatus.SUCCESS, 345 cursor.putCurrent(dataDbt)); 346 } 347 }; 348 dw.setIgnoreDataMap(true); 349 dw.walkData(); 350 assertTrue(dw.nEntries == 2); 351 } catch (Throwable t) { 352 t.printStackTrace(); 353 throw t; 354 } 355 } 356 357 public void testDuplicateReplacementFailure() 358 throws Throwable { 359 360 try { 361 initEnv(true); 362 String keyString = "aaaa"; 363 String dataString = "d1d1"; 364 DatabaseEntry keyDbt = new DatabaseEntry(); 365 DatabaseEntry dataDbt = new DatabaseEntry(); 366 keyDbt.setData(keyString.getBytes()); 367 dataDbt.setData(dataString.getBytes()); 368 assertTrue(cursor.putNoDupData(keyDbt, dataDbt) == 369 OperationStatus.SUCCESS); 370 assertTrue(cursor.putNoDupData(keyDbt, dataDbt) != 371 OperationStatus.SUCCESS); 372 dataString = "d2d2"; 373 dataDbt.setData(dataString.getBytes()); 374 assertTrue(cursor.putNoDupData(keyDbt, dataDbt) == 375 OperationStatus.SUCCESS); 376 assertTrue(cursor.putNoDupData(keyDbt, dataDbt) != 377 OperationStatus.SUCCESS); 378 DataWalker dw = new DataWalker(null) { 379 void perData(String foundKey, String foundData) 380 throws DatabaseException { 381 382 StringDbt dataDbt = new StringDbt(); 383 dataDbt.setString("blort"); 384 try { 385 cursor.putCurrent(dataDbt); 386 fail("didn't catch DatabaseException"); 387 } catch (DatabaseException DBE) { 388 } 389 } 390 }; 391 dw.setIgnoreDataMap(true); 392 dw.walkData(); 393 assertTrue(dw.nEntries == 2); 394 } catch (Throwable t) { 395 t.printStackTrace(); 396 throw t; 397 } 398 } 399 400 public void testDuplicateReplacementFailure1Dup() 401 throws Throwable { 402 403 try { 404 initEnv(true); 405 String keyString = "aaaa"; 406 String dataString = "d1d1"; 407 DatabaseEntry keyDbt = new DatabaseEntry(); 408 DatabaseEntry dataDbt = new DatabaseEntry(); 409 keyDbt.setData(keyString.getBytes()); 410 dataDbt.setData(dataString.getBytes()); 411 assertTrue(cursor.putNoDupData(keyDbt, dataDbt) == 412 OperationStatus.SUCCESS); 413 assertTrue(cursor.putNoDupData(keyDbt, dataDbt) != 414 OperationStatus.SUCCESS); 415 DataWalker dw = new DataWalker(null) { 416 void perData(String foundKey, String foundData) 417 throws DatabaseException { 418 419 StringDbt dataDbt = new StringDbt(); 420 dataDbt.setString("blort"); 421 try { 422 cursor.putCurrent(dataDbt); 423 fail("didn't catch DatabaseException"); 424 } catch (DatabaseException DBE) { 425 } 426 } 427 }; 428 dw.setIgnoreDataMap(true); 429 dw.walkData(); 430 assertTrue(dw.nEntries == 1); 431 } catch (Throwable t) { 432 t.printStackTrace(); 433 throw t; 434 } 435 } 436 437 public void testDuplicateReplacementWithComparisonFunction() 438 throws Throwable { 439 440 try { 441 tearDown(); 442 duplicateComparisonFunction = truncatedComparator; 443 setUp(); 444 initEnv(true); 445 String keyString = "aaaa"; 446 String dataString = "d1d1"; 447 DatabaseEntry keyDbt = new DatabaseEntry(); 448 DatabaseEntry dataDbt = new DatabaseEntry(); 449 keyDbt.setData(keyString.getBytes()); 450 dataDbt.setData(dataString.getBytes()); 451 assertTrue(cursor.putNoDupData(keyDbt, dataDbt) == 452 OperationStatus.SUCCESS); 453 assertTrue(cursor.putNoDupData(keyDbt, dataDbt) != 454 OperationStatus.SUCCESS); 455 dataString = "d2d2"; 456 dataDbt.setData(dataString.getBytes()); 457 assertTrue(cursor.putNoDupData(keyDbt, dataDbt) == 458 OperationStatus.SUCCESS); 459 assertTrue(cursor.putNoDupData(keyDbt, dataDbt) != 460 OperationStatus.SUCCESS); 461 DataWalker dw = new DataWalker(null) { 462 void perData(String foundKey, String foundData) 463 throws DatabaseException { 464 465 StringDbt dataDbt = new StringDbt(); 466 StringBuffer sb = new StringBuffer (foundData); 467 sb.replace(3, 3, "3"); 468 sb.setLength(4); 469 dataDbt.setString(sb.toString()); 470 assertEquals(OperationStatus.SUCCESS, 471 cursor.putCurrent(dataDbt)); 472 } 473 }; 474 dw.setIgnoreDataMap(true); 475 dw.walkData(); 476 assertTrue(dw.nEntries == 2); 477 } catch (Throwable t) { 478 t.printStackTrace(); 479 throw t; 480 } 481 } 482 483 public void testDuplicateReplacementFailureWithComparisonFunction() 484 throws Throwable { 485 486 try { 487 tearDown(); 488 duplicateComparisonFunction = truncatedComparator; 489 setUp(); 490 initEnv(true); 491 492 String keyString = "aaaa"; 493 String dataString = "d1d1"; 494 DatabaseEntry keyDbt = new DatabaseEntry(); 495 DatabaseEntry dataDbt = new DatabaseEntry(); 496 keyDbt.setData(keyString.getBytes()); 497 dataDbt.setData(dataString.getBytes()); 498 assertTrue(cursor.putNoDupData(keyDbt, dataDbt) == 499 OperationStatus.SUCCESS); 500 assertTrue(cursor.putNoDupData(keyDbt, dataDbt) != 501 OperationStatus.SUCCESS); 502 dataString = "d2d2"; 503 dataDbt.setData(dataString.getBytes()); 504 assertTrue(cursor.putNoDupData(keyDbt, dataDbt) == 505 OperationStatus.SUCCESS); 506 assertTrue(cursor.putNoDupData(keyDbt, dataDbt) != 507 OperationStatus.SUCCESS); 508 DataWalker dw = new DataWalker(null) { 509 void perData(String foundKey, String foundData) 510 throws DatabaseException { 511 512 StringDbt dataDbt = new StringDbt(); 513 StringBuffer sb = new StringBuffer (foundData); 514 sb.replace(2, 2, "3"); 515 sb.setLength(4); 516 dataDbt.setString(sb.toString()); 517 try { 518 cursor.putCurrent(dataDbt); 519 fail("didn't catch DatabaseException"); 520 } catch (DatabaseException DBE) { 521 } 522 } 523 }; 524 dw.setIgnoreDataMap(true); 525 dw.walkData(); 526 assertTrue(dw.nEntries == 2); 527 } catch (Throwable t) { 528 t.printStackTrace(); 529 throw t; 530 } 531 } 532 533 private void doDuplicateTest(boolean forward, boolean useKeyLast) 534 throws Throwable { 535 536 Hashtable dataMap = new Hashtable (); 537 createRandomDuplicateData(dataMap, useKeyLast); 538 539 DataWalker dw; 540 if (forward) { 541 dw = new DataWalker(dataMap) { 542 void perData(String foundKey, String foundData) { 543 Hashtable ht = (Hashtable ) dataMap.get(foundKey); 544 if (ht == null) { 545 fail("didn't find ht " + foundKey + "/" + 546 foundData); 547 } 548 549 if (ht.get(foundData) != null) { 550 ht.remove(foundData); 551 if (ht.size() == 0) { 552 dataMap.remove(foundKey); 553 } 554 } else { 555 fail("didn't find " + foundKey + "/" + foundData); 556 } 557 558 assertTrue(foundKey.compareTo(prevKey) >= 0); 559 560 if (prevKey.equals(foundKey)) { 561 if (duplicateComparisonFunction == null) { 562 assertTrue(foundData.compareTo(prevData) >= 0); 563 } else { 564 assertTrue 565 (duplicateComparisonFunction.compare 566 (foundData.getBytes(), 567 prevData.getBytes()) >= 0); 568 } 569 prevData = foundData; 570 } else { 571 prevData = ""; 572 } 573 574 prevKey = foundKey; 575 } 576 }; 577 } else { 578 dw = new BackwardsDataWalker(dataMap) { 579 void perData(String foundKey, String foundData) { 580 Hashtable ht = (Hashtable ) dataMap.get(foundKey); 581 if (ht == null) { 582 fail("didn't find ht " + foundKey + "/" + 583 foundData); 584 } 585 586 if (ht.get(foundData) != null) { 587 ht.remove(foundData); 588 if (ht.size() == 0) { 589 dataMap.remove(foundKey); 590 } 591 } else { 592 fail("didn't find " + foundKey + "/" + foundData); 593 } 594 595 if (!prevKey.equals("")) { 596 assertTrue(foundKey.compareTo(prevKey) <= 0); 597 } 598 599 if (prevKey.equals(foundKey)) { 600 if (!prevData.equals("")) { 601 if (duplicateComparisonFunction == null) { 602 assertTrue 603 (foundData.compareTo(prevData) <= 0); 604 } else { 605 assertTrue 606 (duplicateComparisonFunction.compare 607 (foundData.getBytes(), 608 prevData.getBytes()) <= 0); 609 } 610 } 611 prevData = foundData; 612 } else { 613 prevData = ""; 614 } 615 616 prevKey = foundKey; 617 } 618 }; 619 } 620 dw.setIgnoreDataMap(true); 621 dw.walkData(); 622 assertTrue(dataMap.size() == 0); 623 } 624 625 632 public void testGetNextDup() 633 throws Throwable { 634 635 try { 636 initEnv(true); 637 Hashtable dataMap = new Hashtable (); 638 639 createRandomDuplicateData(dataMap, false); 640 641 DataWalker dw = new DupDataWalker(dataMap) { 642 void perData(String foundKey, String foundData) { 643 Hashtable ht = (Hashtable ) dataMap.get(foundKey); 644 if (ht == null) { 645 fail("didn't find ht " + 646 foundKey + "/" + foundData); 647 } 648 649 if (ht.get(foundData) != null) { 650 ht.remove(foundData); 651 if (ht.size() == 0) { 652 dataMap.remove(foundKey); 653 } 654 } else { 655 fail("didn't find " + foundKey + "/" + foundData); 656 } 657 658 assertTrue(foundKey.compareTo(prevKey) >= 0); 659 660 if (prevKey.equals(foundKey)) { 661 if (duplicateComparisonFunction == null) { 662 assertTrue(foundData.compareTo(prevData) >= 0); 663 } else { 664 assertTrue 665 (duplicateComparisonFunction.compare 666 (foundData.getBytes(), 667 prevData.getBytes()) >= 0); 668 } 669 prevData = foundData; 670 } else { 671 prevData = ""; 672 } 673 674 prevKey = foundKey; 675 } 676 677 OperationStatus handleEndOfSet(OperationStatus status) 678 throws DatabaseException { 679 680 String foundKeyString = foundKey.getString(); 681 Hashtable ht = (Hashtable ) dataMap.get(foundKeyString); 682 assertNull(ht); 683 return cursor.getNext(foundKey, foundData, 684 LockMode.DEFAULT); 685 } 686 }; 687 dw.setIgnoreDataMap(true); 688 dw.walkData(); 689 assertEquals(N_TOP_LEVEL_KEYS, dw.nHandleEndOfSet); 690 assertTrue(dataMap.size() == 0); 691 } catch (Throwable t) { 692 t.printStackTrace(); 693 throw t; 694 } 695 } 696 697 704 public void testGetPrevDup() 705 throws Throwable { 706 707 try { 708 initEnv(true); 709 Hashtable dataMap = new Hashtable (); 710 711 createRandomDuplicateData(dataMap, false); 712 713 DataWalker dw = new BackwardsDupDataWalker(dataMap) { 714 void perData(String foundKey, String foundData) { 715 Hashtable ht = (Hashtable ) dataMap.get(foundKey); 716 if (ht == null) { 717 fail("didn't find ht " + 718 foundKey + "/" + foundData); 719 } 720 721 if (ht.get(foundData) != null) { 722 ht.remove(foundData); 723 if (ht.size() == 0) { 724 dataMap.remove(foundKey); 725 } 726 } else { 727 fail("didn't find " + foundKey + "/" + foundData); 728 } 729 730 if (!prevKey.equals("")) { 731 assertTrue(foundKey.compareTo(prevKey) <= 0); 732 } 733 734 if (prevKey.equals(foundKey)) { 735 if (!prevData.equals("")) { 736 if (duplicateComparisonFunction == null) { 737 assertTrue(foundData.compareTo 738 (prevData) <= 0); 739 } else { 740 assertTrue 741 (duplicateComparisonFunction.compare 742 (foundData.getBytes(), 743 prevData.getBytes()) <= 0); 744 } 745 } 746 prevData = foundData; 747 } else { 748 prevData = ""; 749 } 750 751 prevKey = foundKey; 752 } 753 754 OperationStatus handleEndOfSet(OperationStatus status) 755 throws DatabaseException { 756 757 String foundKeyString = foundKey.getString(); 758 Hashtable ht = (Hashtable ) dataMap.get(foundKeyString); 759 assertNull(ht); 760 return cursor.getPrev(foundKey, foundData, 761 LockMode.DEFAULT); 762 } 763 }; 764 dw.setIgnoreDataMap(true); 765 dw.walkData(); 766 assertEquals(N_TOP_LEVEL_KEYS, dw.nHandleEndOfSet); 767 assertTrue(dataMap.size() == 0); 768 } catch (Throwable t) { 769 t.printStackTrace(); 770 throw t; 771 } 772 } 773 774 780 public void testGetNextNoDup() 781 throws Throwable { 782 783 try { 784 initEnv(true); 785 Hashtable dataMap = new Hashtable (); 786 787 createRandomDuplicateData(dataMap, false); 788 789 DataWalker dw = new NoDupDataWalker(dataMap) { 790 void perData(String foundKey, String foundData) { 791 Hashtable ht = (Hashtable ) dataMap.get(foundKey); 792 if (ht == null) { 793 fail("didn't find ht " + 794 foundKey + "/" + foundData); 795 } 796 797 if (ht.get(foundData) != null) { 798 dataMap.remove(foundKey); 799 } else { 800 fail("saw " + 801 foundKey + "/" + foundData + " twice."); 802 } 803 804 assertTrue(foundKey.compareTo(prevKey) > 0); 805 prevKey = foundKey; 806 } 807 }; 808 dw.setIgnoreDataMap(true); 809 dw.walkData(); 810 assertEquals(N_TOP_LEVEL_KEYS, dw.nEntries); 811 assertTrue(dataMap.size() == 0); 812 } catch (Throwable t) { 813 t.printStackTrace(); 814 throw t; 815 } 816 } 817 818 824 public void testGetPrevNoDup() 825 throws Throwable { 826 827 try { 828 initEnv(true); 829 Hashtable dataMap = new Hashtable (); 830 831 createRandomDuplicateData(dataMap, false); 832 833 DataWalker dw = new NoDupBackwardsDataWalker(dataMap) { 834 void perData(String foundKey, String foundData) { 835 Hashtable ht = (Hashtable ) dataMap.get(foundKey); 836 if (ht == null) { 837 fail("didn't find ht " + 838 foundKey + "/" + foundData); 839 } 840 841 if (ht.get(foundData) != null) { 842 dataMap.remove(foundKey); 843 } else { 844 fail("saw " + 845 foundKey + "/" + foundData + " twice."); 846 } 847 848 if (!prevKey.equals("")) { 849 assertTrue(foundKey.compareTo(prevKey) < 0); 850 } 851 prevKey = foundKey; 852 } 853 }; 854 dw.setIgnoreDataMap(true); 855 dw.walkData(); 856 assertEquals(N_TOP_LEVEL_KEYS, dw.nEntries); 857 assertTrue(dataMap.size() == 0); 858 } catch (Throwable t) { 859 t.printStackTrace(); 860 throw t; 861 } 862 } 863 864 public void testIllegalDuplicateCreation() 865 throws Throwable { 866 867 try { 868 initEnv(false); 869 Hashtable dataMap = new Hashtable (); 870 871 try { 872 createRandomDuplicateData(dataMap, false); 873 fail("didn't throw DuplicateEntryException"); 874 } catch (DuplicateEntryException DEE) { 875 } 876 } catch (Throwable t) { 877 t.printStackTrace(); 878 throw t; 879 } 880 } 881 882 885 private static Comparator duplicateComparator = 886 new DuplicateAscendingComparator(); 887 888 private static Comparator reverseDuplicateComparator = 889 new DuplicateReverseComparator(); 890 891 private static InvocationCountingBtreeComparator 892 invocationCountingComparator = 893 new InvocationCountingBtreeComparator(); 894 895 public static class DuplicateAscendingComparator 896 extends BtreeComparator { 897 898 public DuplicateAscendingComparator() { 899 super(); 900 } 901 } 902 903 public static class DuplicateReverseComparator 904 extends ReverseBtreeComparator { 905 906 public DuplicateReverseComparator() { 907 super(); 908 } 909 } 910 911 public static class InvocationCountingBtreeComparator 912 extends BtreeComparator { 913 914 private int invocationCount = 0; 915 916 public int compare(Object o1, Object o2) { 917 invocationCount++; 918 return super.compare(o1, o2); 919 } 920 921 public int getInvocationCount() { 922 return invocationCount; 923 } 924 925 public void setInvocationCount(int invocationCount) { 926 this.invocationCount = invocationCount; 927 } 928 } 929 930 935 private static Comparator truncatedComparator = new TruncatedComparator(); 936 937 protected static class TruncatedComparator implements Comparator { 938 protected TruncatedComparator() { 939 } 940 941 public int compare(Object o1, Object o2) { 942 byte[] arg1; 943 byte[] arg2; 944 arg1 = (byte[]) o1; 945 arg2 = (byte[]) o2; 946 int a1Len = arg1.length - 1; 947 int a2Len = arg2.length - 1; 948 949 int limit = Math.min(a1Len, a2Len); 950 951 for (int i = 0; i < limit; i++) { 952 byte b1 = arg1[i]; 953 byte b2 = arg2[i]; 954 if (b1 == b2) { 955 continue; 956 } else { 957 962 short s1 = (short) (b1 & 0x7F); 963 short s2 = (short) (b2 & 0x7F); 964 if (b1 < 0) { 965 s1 |= 0x80; 966 } 967 if (b2 < 0) { 968 s2 |= 0x80; 969 } 970 return (s1 - s2); 971 } 972 } 973 974 return (a1Len - a2Len); 975 } 976 } 977 } 978 | Popular Tags |