1 8 9 package com.sleepycat.je.txn; 10 11 import java.io.File ; 12 import java.util.ArrayList ; 13 import java.util.HashSet ; 14 import java.util.Iterator ; 15 import java.util.List ; 16 import java.util.Set ; 17 18 import junit.framework.TestCase; 19 20 import com.sleepycat.je.DatabaseException; 21 import com.sleepycat.je.EnvironmentConfig; 22 import com.sleepycat.je.TransactionConfig; 23 import com.sleepycat.je.config.EnvironmentParams; 24 import com.sleepycat.je.dbi.EnvironmentImpl; 25 import com.sleepycat.je.dbi.MemoryBudget; 26 import com.sleepycat.je.util.TestUtils; 27 28 public class LockTest extends TestCase { 29 private EnvironmentImpl envImpl; 30 private File envHome; 31 32 public LockTest() { 33 envHome = new File (System.getProperty(TestUtils.DEST_DIR)); 34 } 35 36 public void setUp() 37 throws DatabaseException { 38 39 EnvironmentConfig envConfig = TestUtils.initEnvConfig(); 40 envConfig.setConfigParam(EnvironmentParams.NODE_MAX.getName(), "6"); 41 envConfig.setAllowCreate(true); 42 envImpl = new EnvironmentImpl(envHome, envConfig); 43 44 } 45 46 public void tearDown() 47 throws DatabaseException { 48 49 envImpl.close(); 50 } 51 52 public void testLockConflicts() 53 throws Exception { 54 55 Locker txn1 = new BasicLocker(envImpl); 56 Locker txn2 = new BasicLocker(envImpl); 57 Locker txn3 = new BasicLocker(envImpl); 58 MemoryBudget mb = envImpl.getMemoryBudget(); 59 try { 60 65 Lock lock = new Lock(new Long (1)); 66 assertEquals(LockGrantType.NEW, 67 lock.lock(LockType.READ, txn1, false, mb, 0)); 68 assertEquals(LockGrantType.EXISTING, 69 lock.lock(LockType.READ, txn1, false, mb, 0)); 70 assertEquals(1, lock.nOwners()); 71 assertEquals(0, lock.nWaiters()); 72 73 74 assertEquals(LockGrantType.NEW, 75 lock.lock(LockType.READ, txn2, false, mb, 0)); 76 77 assertEquals(LockGrantType.WAIT_PROMOTION, 78 lock.lock(LockType.WRITE, txn1, false, mb, 0)); 79 80 assertEquals(LockGrantType.WAIT_PROMOTION, 81 lock.lock(LockType.WRITE, txn2, false, mb, 0)); 82 assertEquals(2, lock.nOwners()); 83 assertEquals(2, lock.nWaiters()); 84 85 86 87 lock = new Lock(new Long (1)); 88 89 assertEquals(LockGrantType.NEW, 90 lock.lock(LockType.WRITE, txn1, false, mb, 0)); 91 assertEquals(LockGrantType.EXISTING, 92 lock.lock(LockType.READ, txn1, false, mb, 0)); 93 assertEquals(1, lock.nOwners()); 94 assertEquals(0, lock.nWaiters()); 95 96 97 lock = new Lock(new Long (1)); 98 assertEquals(LockGrantType.NEW, 99 lock.lock(LockType.READ, txn1, false, mb, 0)); 100 assertEquals(LockGrantType.PROMOTION, 101 lock.lock(LockType.WRITE, txn1, false, mb, 0)); 102 assertEquals(1, lock.nOwners()); 103 assertEquals(0, lock.nWaiters()); 104 105 109 lock = new Lock(new Long (1)); 110 111 assertEquals(LockGrantType.NEW, 112 lock.lock(LockType.READ, txn1, false, mb, 0)); 113 assertEquals(LockGrantType.DENIED, 114 lock.lock(LockType.WRITE, txn2, true, mb, 0)); 115 assertEquals(1, lock.nOwners()); 116 assertEquals(0, lock.nWaiters()); 117 118 119 lock = new Lock(new Long (1)); 120 assertEquals(LockGrantType.NEW, 121 lock.lock(LockType.WRITE, txn1, false, mb, 0)); 122 assertEquals(LockGrantType.EXISTING, 123 lock.lock(LockType.WRITE, txn1, false, mb, 0)); 124 assertEquals(1, lock.nOwners()); 125 assertEquals(0, lock.nWaiters()); 126 127 131 lock = new Lock(new Long (1)); 132 133 assertEquals(LockGrantType.NEW, 134 lock.lock(LockType.READ, txn1, false, mb, 0)); 135 136 assertEquals(LockGrantType.WAIT_NEW, 137 lock.lock(LockType.WRITE, txn2, false, mb, 0)); 138 139 assertEquals(LockGrantType.WAIT_NEW, 140 lock.lock(LockType.READ, txn3, false, mb, 0)); 141 142 assertEquals(1, lock.nOwners()); 143 assertEquals(2, lock.nWaiters()); 144 145 146 lock = new Lock(new Long (1)); 147 148 assertEquals(LockGrantType.NEW, 149 lock.lock(LockType.READ, txn1, false, mb, 0)); 150 151 153 assertEquals(LockGrantType.DENIED, 154 lock.lock(LockType.WRITE, txn2, true, mb, 0)); 155 assertEquals(LockGrantType.NEW, 156 lock.lock(LockType.READ, txn3, true, mb, 0)); 157 assertEquals(2, lock.nOwners()); 158 assertEquals(0, lock.nWaiters()); 159 160 lock = new Lock(new Long (1)); 161 162 assertEquals(LockGrantType.NEW, 163 lock.lock(LockType.READ, txn1, false, mb, 0)); 164 assertEquals(LockGrantType.NEW, 165 lock.lock(LockType.READ, txn2, false, mb, 0)); 166 assertEquals(LockGrantType.NEW, 167 lock.lock(LockType.READ, txn3, false, mb, 0)); 168 assertEquals(3, lock.nOwners()); 169 assertEquals(0, lock.nWaiters()); 170 } finally { 171 txn1.operationEnd(); 172 txn2.operationEnd(); 173 txn3.operationEnd(); 174 } 175 } 176 177 public void testOwners() 178 throws Exception { 179 180 Locker txn1 = new BasicLocker(envImpl); 181 Locker txn2 = new BasicLocker(envImpl); 182 Locker txn3 = new BasicLocker(envImpl); 183 Locker txn4 = new BasicLocker(envImpl); 184 MemoryBudget mb = envImpl.getMemoryBudget(); 185 186 try { 187 191 Lock lock = new Lock(new Long (1)); 192 193 assertTrue(lock.getWriteOwnerLocker() == null); 194 195 assertEquals(LockGrantType.NEW, 196 lock.lock(LockType.READ, txn1, false, mb, 0)); 197 assertEquals(LockGrantType.NEW, 198 lock.lock(LockType.READ, txn2, false, mb, 0)); 199 assertEquals(LockGrantType.NEW, 200 lock.lock(LockType.READ, txn3, false, mb, 0)); 201 202 203 assertTrue(lock.getWriteOwnerLocker() == null); 204 205 206 assertEquals(1, lock.getNodeId().longValue()); 207 208 209 Set expectedOwners = new HashSet (); 210 expectedOwners.add(new LockInfo(txn1, LockType.READ)); 211 expectedOwners.add(new LockInfo(txn2, LockType.READ)); 212 expectedOwners.add(new LockInfo(txn3, LockType.READ)); 213 checkOwners(expectedOwners, lock, 0); 214 215 216 lock.release(txn1, mb, 0); 217 expectedOwners = new HashSet (); 218 expectedOwners.add(new LockInfo(txn2, LockType.READ)); 219 expectedOwners.add(new LockInfo(txn3, LockType.READ)); 220 checkOwners(expectedOwners, lock, 0); 221 222 223 assertEquals(LockGrantType.NEW, 224 lock.lock(LockType.READ, txn4, false, mb, 0)); 225 expectedOwners = new HashSet (); 226 expectedOwners.add(new LockInfo(txn2, LockType.READ)); 227 expectedOwners.add(new LockInfo(txn3, LockType.READ)); 228 expectedOwners.add(new LockInfo(txn4, LockType.READ)); 229 checkOwners(expectedOwners, lock, 0); 230 231 232 lock.release(txn2, mb, 0); 233 expectedOwners = new HashSet (); 234 expectedOwners.add(new LockInfo(txn3, LockType.READ)); 235 expectedOwners.add(new LockInfo(txn4, LockType.READ)); 236 checkOwners(expectedOwners, lock, 0); 237 238 239 lock.release(txn3, mb, 0); 240 expectedOwners = new HashSet (); 241 expectedOwners.add(new LockInfo(txn4, LockType.READ)); 242 243 assertTrue(lock.getWriteOwnerLocker() == null); 244 245 246 lock.release(txn4, mb, 0); 247 expectedOwners = new HashSet (); 248 checkOwners(expectedOwners, lock, 0); 249 250 251 assertEquals(LockGrantType.NEW, 252 lock.lock(LockType.READ, txn1, false, mb, 0)); 253 assertEquals(LockGrantType.NEW, 254 lock.lock(LockType.READ, txn2, false, mb, 0)); 255 expectedOwners = new HashSet (); 256 expectedOwners.add(new LockInfo(txn1, LockType.READ)); 257 expectedOwners.add(new LockInfo(txn2, LockType.READ)); 258 checkOwners(expectedOwners, lock, 0); 259 260 } catch (Exception e) { 261 e.printStackTrace(); 262 throw e; 263 } finally { 264 txn1.operationEnd(); 265 txn2.operationEnd(); 266 txn3.operationEnd(); 267 txn4.operationEnd(); 268 } 269 } 270 271 public void testWaiters() 272 throws Exception { 273 274 Locker txn1 = new AutoTxn(envImpl, new TransactionConfig()); 275 Locker txn2 = new AutoTxn(envImpl, new TransactionConfig()); 276 Locker txn3 = new AutoTxn(envImpl, new TransactionConfig()); 277 Locker txn4 = new AutoTxn(envImpl, new TransactionConfig()); 278 Locker txn5 = new AutoTxn(envImpl, new TransactionConfig()); 279 MemoryBudget mb = envImpl.getMemoryBudget(); 280 281 try { 282 286 Lock lock = new Lock(new Long (1)); 287 assertEquals(LockGrantType.NEW, 288 lock.lock(LockType.READ, txn1, false, mb, 0)); 289 assertEquals(LockGrantType.NEW, 290 lock.lock(LockType.READ, txn2, false, mb, 0)); 291 assertEquals(LockGrantType.WAIT_NEW, 292 lock.lock(LockType.WRITE, txn3, false, mb, 0)); 293 assertEquals(LockGrantType.WAIT_NEW, 294 lock.lock(LockType.WRITE, txn4, false, mb, 0)); 295 assertEquals(LockGrantType.WAIT_PROMOTION, 296 lock.lock(LockType.WRITE, txn1, false, mb, 0)); 297 298 299 assertTrue(lock.getWriteOwnerLocker() == null); 300 301 302 assertEquals(1, lock.getNodeId().longValue()); 303 304 305 Set expectedOwners = new HashSet (); 306 expectedOwners.add(new LockInfo(txn1, LockType.READ)); 307 expectedOwners.add(new LockInfo(txn2, LockType.READ)); 308 checkOwners(expectedOwners, lock, 3); 309 310 List waiters = new ArrayList (); 311 waiters.add(new LockInfo(txn1, LockType.WRITE)); 312 waiters.add(new LockInfo(txn3, LockType.WRITE)); 313 waiters.add(new LockInfo(txn4, LockType.WRITE)); 314 checkWaiters(waiters, lock); 315 316 317 lock.release(txn4, mb, 0); 318 checkWaiters(waiters, lock); 319 320 324 lock.release(txn2, mb, 0); 325 expectedOwners = new HashSet (); 326 expectedOwners.add(new LockInfo(txn1, LockType.WRITE)); 327 checkOwners(expectedOwners, lock, 2); 328 329 waiters.remove(0); 330 checkWaiters(waiters, lock); 331 332 333 lock.release(txn1, mb, 0); 334 expectedOwners = new HashSet (); 335 expectedOwners.add(new LockInfo(txn3, LockType.WRITE)); 336 checkOwners(expectedOwners, lock, 1); 337 338 waiters.remove(0); 339 checkWaiters(waiters, lock); 340 341 345 assertEquals(LockGrantType.WAIT_NEW, 346 lock.lock(LockType.READ, txn1, false, mb, 0)); 347 assertEquals(LockGrantType.WAIT_NEW, 348 lock.lock(LockType.READ, txn2, false, mb, 0)); 349 assertEquals(LockGrantType.WAIT_NEW, 350 lock.lock(LockType.READ, txn5, false, mb, 0)); 351 352 checkOwners(expectedOwners, lock, 4); 353 waiters.add(new LockInfo(txn1, LockType.READ)); 354 waiters.add(new LockInfo(txn2, LockType.READ)); 355 waiters.add(new LockInfo(txn5, LockType.READ)); 356 checkWaiters(waiters, lock); 357 358 359 lock.flushWaiter(txn5, mb, 0); 360 waiters.remove(3); 361 checkWaiters(waiters, lock); 362 363 364 assertEquals(LockGrantType.WAIT_NEW, 365 lock.lock(LockType.READ, txn5, false, mb, 0)); 366 waiters.add(new LockInfo(txn5, LockType.READ)); 367 368 369 lock.release(txn3, mb, 0); 370 expectedOwners = new HashSet (); 371 expectedOwners.add(new LockInfo(txn4, LockType.WRITE)); 372 checkOwners(expectedOwners, lock, 3); 373 waiters.remove(0); 374 checkWaiters(waiters, lock); 375 376 377 lock.release(txn4, mb, 0); 378 expectedOwners = new HashSet (); 379 expectedOwners.add(new LockInfo(txn1, LockType.READ)); 380 expectedOwners.add(new LockInfo(txn2, LockType.READ)); 381 expectedOwners.add(new LockInfo(txn5, LockType.READ)); 382 checkOwners(expectedOwners, lock, 0); 383 waiters.clear(); 384 checkWaiters(waiters, lock); 385 386 } catch (Exception e) { 387 e.printStackTrace(); 388 throw e; 389 } finally { 390 txn1.operationEnd(); 391 txn2.operationEnd(); 392 txn3.operationEnd(); 393 txn4.operationEnd(); 394 txn5.operationEnd(); 395 } 396 } 397 398 public void testPromotion() 399 throws Exception { 400 401 Locker txn1 = new AutoTxn(envImpl, new TransactionConfig()); 402 Locker txn2 = new AutoTxn(envImpl, new TransactionConfig()); 403 Locker txn3 = new AutoTxn(envImpl, new TransactionConfig()); 404 Locker txn4 = new AutoTxn(envImpl, new TransactionConfig()); 405 Locker txn5 = new AutoTxn(envImpl, new TransactionConfig()); 406 MemoryBudget mb = envImpl.getMemoryBudget(); 407 408 try { 409 413 Lock lock = new Lock(new Long (1)); 414 assertEquals(LockGrantType.NEW, 415 lock.lock(LockType.WRITE, txn1, false, mb, 0)); 416 assertEquals(LockGrantType.WAIT_NEW, 417 lock.lock(LockType.READ, txn2, false, mb, 0)); 418 assertEquals(LockGrantType.WAIT_NEW, 419 lock.lock(LockType.READ, txn3, false, mb, 0)); 420 assertEquals(LockGrantType.WAIT_NEW, 421 lock.lock(LockType.READ, txn4, false, mb, 0)); 422 423 424 Set expectedOwners = new HashSet (); 425 expectedOwners.add(new LockInfo(txn1, LockType.WRITE)); 426 checkOwners(expectedOwners, lock, 3); 427 428 List waiters = new ArrayList (); 429 waiters.add(new LockInfo(txn2, LockType.READ)); 430 waiters.add(new LockInfo(txn3, LockType.READ)); 431 waiters.add(new LockInfo(txn4, LockType.READ)); 432 checkWaiters(waiters, lock); 433 434 435 lock.release(txn1, mb, 0); 436 expectedOwners = new HashSet (); 437 expectedOwners.add(new LockInfo(txn2, LockType.READ)); 438 expectedOwners.add(new LockInfo(txn3, LockType.READ)); 439 expectedOwners.add(new LockInfo(txn4, LockType.READ)); 440 checkOwners(expectedOwners, lock, 0); 441 waiters.clear(); 442 checkWaiters(waiters, lock); 443 } catch (Exception e) { 444 e.printStackTrace(); 445 throw e; 446 } finally { 447 txn1.operationEnd(); 448 txn2.operationEnd(); 449 txn3.operationEnd(); 450 txn4.operationEnd(); 451 txn5.operationEnd(); 452 } 453 } 454 455 458 public void testRangeConflicts() 459 throws Exception { 460 461 462 463 checkConflict(null, 464 LockType.RANGE_READ, 465 LockGrantType.NEW); 466 checkConflict(null, 467 LockType.RANGE_WRITE, 468 LockGrantType.NEW); 469 checkConflict(null, 470 LockType.RANGE_INSERT, 471 LockGrantType.NEW); 472 473 474 checkConflict(LockType.READ, 475 LockType.RANGE_READ, 476 LockGrantType.NEW); 477 checkConflict(LockType.READ, 478 LockType.RANGE_WRITE, 479 LockGrantType.WAIT_NEW); 480 checkConflict(LockType.READ, 481 LockType.RANGE_INSERT, 482 LockGrantType.NEW); 483 484 485 checkConflict(LockType.WRITE, 486 LockType.RANGE_READ, 487 LockGrantType.WAIT_NEW); 488 checkConflict(LockType.WRITE, 489 LockType.RANGE_WRITE, 490 LockGrantType.WAIT_NEW); 491 checkConflict(LockType.WRITE, 492 LockType.RANGE_INSERT, 493 LockGrantType.NEW); 494 495 496 checkConflict(LockType.RANGE_READ, 497 LockType.READ, 498 LockGrantType.NEW); 499 checkConflict(LockType.RANGE_READ, 500 LockType.WRITE, 501 LockGrantType.WAIT_NEW); 502 checkConflict(LockType.RANGE_READ, 503 LockType.RANGE_READ, 504 LockGrantType.NEW); 505 checkConflict(LockType.RANGE_READ, 506 LockType.RANGE_WRITE, 507 LockGrantType.WAIT_NEW); 508 checkConflict(LockType.RANGE_READ, 509 LockType.RANGE_INSERT, 510 LockGrantType.WAIT_NEW); 511 512 513 checkConflict(LockType.RANGE_WRITE, 514 LockType.READ, 515 LockGrantType.WAIT_NEW); 516 checkConflict(LockType.RANGE_WRITE, 517 LockType.WRITE, 518 LockGrantType.WAIT_NEW); 519 checkConflict(LockType.RANGE_WRITE, 520 LockType.RANGE_READ, 521 LockGrantType.WAIT_NEW); 522 checkConflict(LockType.RANGE_WRITE, 523 LockType.RANGE_WRITE, 524 LockGrantType.WAIT_NEW); 525 checkConflict(LockType.RANGE_WRITE, 526 LockType.RANGE_INSERT, 527 LockGrantType.WAIT_NEW); 528 529 530 checkConflict(LockType.RANGE_INSERT, 531 LockType.READ, 532 LockGrantType.NEW); 533 checkConflict(LockType.RANGE_INSERT, 534 LockType.WRITE, 535 LockGrantType.NEW); 536 checkConflict(LockType.RANGE_INSERT, 537 LockType.RANGE_READ, 538 LockGrantType.WAIT_RESTART); 539 checkConflict(LockType.RANGE_INSERT, 540 LockType.RANGE_WRITE, 541 LockGrantType.WAIT_RESTART); 542 checkConflict(LockType.RANGE_INSERT, 543 LockType.RANGE_INSERT, 544 LockGrantType.NEW); 545 } 546 547 551 private void checkConflict(LockType firstRequest, LockType secondRequest, 552 LockGrantType secondGrantType) 553 throws Exception { 554 555 Locker txn1 = new AutoTxn(envImpl, new TransactionConfig()); 556 Locker txn2 = new AutoTxn(envImpl, new TransactionConfig()); 557 MemoryBudget mb = envImpl.getMemoryBudget(); 558 559 try { 560 Lock lock = new Lock(new Long (1)); 561 562 if (firstRequest != null) { 563 assertEquals(LockGrantType.NEW, 564 lock.lock(firstRequest, txn1, false, mb, 0)); 565 } 566 LockGrantType typeGranted = 567 lock.lock(secondRequest, txn2, false, mb, 0); 568 assertEquals(secondGrantType, typeGranted); 569 570 boolean wait = (typeGranted == LockGrantType.WAIT_NEW || 571 typeGranted == LockGrantType.WAIT_PROMOTION || 572 typeGranted == LockGrantType.WAIT_RESTART); 573 boolean given = (typeGranted == LockGrantType.NEW); 574 boolean restart = (typeGranted == LockGrantType.WAIT_RESTART); 575 576 Set expectedOwners = new HashSet (); 577 List expectedWaiters = new ArrayList (); 578 579 if (firstRequest != null) { 580 expectedOwners.add(new LockInfo(txn1, firstRequest)); 581 } 582 if (given) { 583 expectedOwners.add(new LockInfo(txn2, secondRequest)); 584 } else if (wait) { 585 if (restart) { 586 expectedWaiters.add(new LockInfo(txn2, LockType.RESTART)); 587 } else { 588 expectedWaiters.add(new LockInfo(txn2, secondRequest)); 589 } 590 } 591 592 checkOwners(expectedOwners, lock, expectedWaiters.size()); 593 checkWaiters(expectedWaiters, lock); 594 595 lock.release(txn1, mb, 0); 596 if (wait) { 597 if (restart) { 598 checkOwners(new HashSet (), lock, 0); 599 } else { 600 checkOwners(new HashSet (expectedWaiters), lock, 0); 601 } 602 } 603 lock.release(txn2, mb, 0); 604 assertEquals(0, lock.nOwners()); 605 assertEquals(0, lock.nWaiters()); 606 } catch (Exception e) { 607 e.printStackTrace(); 608 throw e; 609 } finally { 610 txn1.operationEnd(); 611 txn2.operationEnd(); 612 } 613 } 614 615 618 public void testRangeUpgrades() 619 throws Exception { 620 621 622 checkUpgrade(LockType.READ, 623 LockType.RANGE_READ, 624 LockGrantType.EXISTING, 625 LockType.RANGE_READ); 626 checkUpgrade(LockType.READ, 627 LockType.RANGE_WRITE, 628 LockGrantType.PROMOTION, 629 LockType.RANGE_WRITE); 630 checkUpgrade(LockType.READ, 631 LockType.RANGE_INSERT, 632 null, 633 LockType.READ); 634 635 636 checkUpgrade(LockType.WRITE, 637 LockType.RANGE_READ, 638 LockGrantType.EXISTING, 639 LockType.RANGE_WRITE); 640 checkUpgrade(LockType.WRITE, 641 LockType.RANGE_WRITE, 642 LockGrantType.EXISTING, 643 LockType.RANGE_WRITE); 644 checkUpgrade(LockType.WRITE, 645 LockType.RANGE_INSERT, 646 null, 647 LockType.WRITE); 648 649 650 checkUpgrade(LockType.RANGE_READ, 651 LockType.READ, 652 LockGrantType.EXISTING, 653 LockType.RANGE_READ); 654 checkUpgrade(LockType.RANGE_READ, 655 LockType.WRITE, 656 LockGrantType.PROMOTION, 657 LockType.RANGE_WRITE); 658 checkUpgrade(LockType.RANGE_READ, 659 LockType.RANGE_READ, 660 LockGrantType.EXISTING, 661 LockType.RANGE_READ); 662 checkUpgrade(LockType.RANGE_READ, 663 LockType.RANGE_WRITE, 664 LockGrantType.PROMOTION, 665 LockType.RANGE_WRITE); 666 checkUpgrade(LockType.RANGE_READ, 667 LockType.RANGE_INSERT, 668 null, 669 LockType.RANGE_READ); 670 671 672 checkUpgrade(LockType.RANGE_WRITE, 673 LockType.READ, 674 LockGrantType.EXISTING, 675 LockType.RANGE_WRITE); 676 checkUpgrade(LockType.RANGE_WRITE, 677 LockType.WRITE, 678 LockGrantType.EXISTING, 679 LockType.RANGE_WRITE); 680 checkUpgrade(LockType.RANGE_WRITE, 681 LockType.RANGE_READ, 682 LockGrantType.EXISTING, 683 LockType.RANGE_WRITE); 684 checkUpgrade(LockType.RANGE_WRITE, 685 LockType.RANGE_WRITE, 686 LockGrantType.EXISTING, 687 LockType.RANGE_WRITE); 688 checkUpgrade(LockType.RANGE_WRITE, 689 LockType.RANGE_INSERT, 690 null, 691 LockType.RANGE_WRITE); 692 693 694 checkUpgrade(LockType.RANGE_INSERT, 695 LockType.READ, 696 null, 697 LockType.RANGE_INSERT); 698 checkUpgrade(LockType.RANGE_INSERT, 699 LockType.WRITE, 700 null, 701 LockType.RANGE_INSERT); 702 checkUpgrade(LockType.RANGE_INSERT, 703 LockType.RANGE_READ, 704 null, 705 LockType.RANGE_INSERT); 706 checkUpgrade(LockType.RANGE_INSERT, 707 LockType.RANGE_WRITE, 708 null, 709 LockType.RANGE_INSERT); 710 checkUpgrade(LockType.RANGE_INSERT, 711 LockType.RANGE_INSERT, 712 LockGrantType.EXISTING, 713 LockType.RANGE_INSERT); 714 } 715 716 721 private void checkUpgrade(LockType firstRequest, LockType secondRequest, 722 LockGrantType secondGrantType, 723 LockType finalType) 724 throws Exception { 725 726 Locker txn1 = new AutoTxn(envImpl, new TransactionConfig()); 727 MemoryBudget mb = envImpl.getMemoryBudget(); 728 729 try { 730 Lock lock = new Lock(new Long (1)); 731 732 assertEquals(LockGrantType.NEW, 733 lock.lock(firstRequest, txn1, false, mb, 0)); 734 LockGrantType typeGranted = null; 735 try { 736 typeGranted = lock.lock(secondRequest, txn1, false, mb, 0); 737 if (secondGrantType == null) { 738 fail("expected AssertionError"); 739 } 740 } catch (AssertionError e) { 741 if (secondGrantType != null) { 742 fail(e.toString()); 743 } 744 } 745 assertEquals(secondGrantType, typeGranted); 746 747 Set expectedOwners = new HashSet (); 748 expectedOwners.add(new LockInfo(txn1, finalType)); 749 checkOwners(expectedOwners, lock, 0); 750 lock.release(txn1, mb, 0); 751 assertEquals(0, lock.nOwners()); 752 assertEquals(0, lock.nWaiters()); 753 } catch (Exception e) { 754 e.printStackTrace(); 755 throw e; 756 } finally { 757 txn1.operationEnd(); 758 } 759 } 760 761 766 public void testRangeInsertWaiterConflict() 767 throws Exception { 768 769 Locker txn1 = new AutoTxn(envImpl, new TransactionConfig()); 770 Locker txn2 = new AutoTxn(envImpl, new TransactionConfig()); 771 Locker txn3 = new AutoTxn(envImpl, new TransactionConfig()); 772 MemoryBudget mb = envImpl.getMemoryBudget(); 773 774 try { 775 Lock lock = new Lock(new Long (1)); 776 assertEquals(LockGrantType.NEW, 777 lock.lock(LockType.RANGE_READ, txn1, false, mb, 0)); 778 assertEquals(LockGrantType.WAIT_NEW, 779 lock.lock(LockType.RANGE_INSERT, txn2, false, mb, 0)); 780 assertEquals(LockGrantType.WAIT_RESTART, 781 lock.lock(LockType.RANGE_READ, txn3, false, mb, 0)); 782 783 784 785 Set expectedOwners = new HashSet (); 786 expectedOwners.add(new LockInfo(txn1, LockType.RANGE_READ)); 787 checkOwners(expectedOwners, lock, 2); 788 789 List waiters = new ArrayList (); 790 waiters.add(new LockInfo(txn2, LockType.RANGE_INSERT)); 791 waiters.add(new LockInfo(txn3, LockType.RESTART)); 792 checkWaiters(waiters, lock); 793 } catch (Exception e) { 794 e.printStackTrace(); 795 throw e; 796 } finally { 797 txn1.operationEnd(); 798 txn2.operationEnd(); 799 txn3.operationEnd(); 800 } 801 } 802 803 private void checkOwners(Set expectedOwners, 804 Lock lock, 805 int numExpectedWaiters) { 806 807 808 Set owners = lock.getOwnersClone(); 809 assertEquals(expectedOwners.size(), owners.size()); 810 811 812 assertEquals(numExpectedWaiters, lock.nWaiters()); 813 814 815 Iterator iter = expectedOwners.iterator(); 816 while (iter.hasNext()) { 817 LockInfo info = (LockInfo) iter.next(); 818 819 820 assertEquals(info.getLockType().isWriteLock(), 821 lock.isOwnedWriteLock(info.getLocker())); 822 assertTrue(lock.isOwner(info.getLocker(), info.getLockType())); 823 } 824 } 825 826 private void checkWaiters(List expectedWaiters, 827 Lock lock) { 828 List waiters = lock.getWaitersListClone(); 829 assertEquals(expectedWaiters.size(), waiters.size()); 830 831 832 for (int i = 0; i < expectedWaiters.size(); i++) { 833 LockInfo info = (LockInfo) expectedWaiters.get(i); 834 LockInfo waiterInfo = (LockInfo) waiters.get(i); 835 assertEquals("i=" + i, info.getLocker(), waiterInfo.getLocker()); 836 assertEquals("i=" + i, 837 info.getLockType(), waiterInfo.getLockType()); 838 assertFalse(lock.isOwner(info.getLocker(), info.getLockType())); 839 assertTrue(lock.isWaiter(info.getLocker())); 840 } 841 842 843 } 844 845 public void testTransfer() 846 throws Exception { 847 848 Locker txn1 = new AutoTxn(envImpl, new TransactionConfig()); 849 Locker txn2 = new AutoTxn(envImpl, new TransactionConfig()); 850 Locker txn3 = new AutoTxn(envImpl, new TransactionConfig()); 851 Locker txn4 = new AutoTxn(envImpl, new TransactionConfig()); 852 Locker txn5 = new AutoTxn(envImpl, new TransactionConfig()); 853 MemoryBudget mb = envImpl.getMemoryBudget(); 854 855 try { 856 857 Lock lock = new Lock(new Long (1)); 858 assertEquals(LockGrantType.NEW, 859 lock.lock(LockType.WRITE, txn1, false, mb, 0)); 860 assertEquals(LockGrantType.WAIT_NEW, 861 lock.lock(LockType.READ, txn2, false, mb, 0)); 862 assertTrue(lock.isOwner(txn1, LockType.WRITE)); 863 assertFalse(lock.isOwner(txn2, LockType.READ)); 864 865 lock.transfer(txn1, txn2, mb, 0); 866 assertFalse(lock.isOwner(txn1, LockType.WRITE)); 867 assertFalse(lock.isOwner(txn1, LockType.READ)); 868 assertTrue(lock.isOwnedWriteLock(txn2)); 869 870 871 Locker [] destLockers = new Locker[3]; 872 destLockers[0] = txn3; 873 destLockers[1] = txn4; 874 destLockers[2] = txn5; 875 lock.demote(txn2); 876 lock.transferMultiple(txn2, destLockers, mb, 0); 877 assertFalse(lock.isOwner(txn2, LockType.WRITE)); 878 assertFalse(lock.isOwner(txn2, LockType.READ)); 879 880 for (int i = 0; i < destLockers.length; i++) { 881 assertTrue(lock.isOwner(destLockers[i], LockType.READ)); 882 assertFalse(lock.isOwner(destLockers[i], LockType.WRITE)); 883 } 884 885 886 } finally { 887 txn1.operationEnd(); 888 txn2.operationEnd(); 889 txn3.operationEnd(); 890 txn4.operationEnd(); 891 txn5.operationEnd(); 892 } 893 } 894 } 895 | Popular Tags |