1 21 22 package org.apache.derby.impl.store.access.heap; 23 24 import org.apache.derby.iapi.reference.SQLState; 25 26 import org.apache.derby.iapi.services.sanity.SanityManager; 27 28 import org.apache.derby.iapi.error.StandardException; 29 30 import org.apache.derby.iapi.store.access.conglomerate.TransactionManager; 31 32 import org.apache.derby.iapi.store.access.AccessFactoryGlobals; 33 import org.apache.derby.iapi.store.access.ConglomerateController; 34 import org.apache.derby.iapi.store.access.DynamicCompiledOpenConglomInfo; 35 import org.apache.derby.iapi.store.access.RowLocationRetRowSource; 36 import org.apache.derby.iapi.store.access.RowUtil; 37 import org.apache.derby.iapi.store.access.TransactionController; 38 39 import org.apache.derby.iapi.store.raw.ContainerHandle; 40 import org.apache.derby.iapi.store.raw.LockingPolicy; 41 import org.apache.derby.iapi.store.raw.Page; 42 import org.apache.derby.iapi.store.raw.RecordHandle; 43 44 import org.apache.derby.iapi.types.DataValueDescriptor; 45 46 import org.apache.derby.iapi.types.RowLocation; 47 48 import org.apache.derby.impl.store.access.conglomerate.OpenConglomerate; 49 import org.apache.derby.impl.store.access.conglomerate.GenericConglomerateController; 50 import org.apache.derby.impl.store.access.conglomerate.RowPosition; 51 52 import org.apache.derby.iapi.services.io.FormatableBitSet; 53 54 57 58 public class HeapController 59 extends GenericConglomerateController 60 implements ConglomerateController 61 { 62 66 67 71 72 77 protected final void getRowPositionFromRowLocation( 78 RowLocation row_loc, 79 RowPosition pos) 80 throws StandardException 81 { 82 if (SanityManager.DEBUG) 83 { 84 SanityManager.ASSERT(row_loc instanceof HeapRowLocation); 85 } 86 pos.current_rh = 87 ((HeapRowLocation) row_loc).getRecordHandle( 88 open_conglom.getContainer()); 89 pos.current_rh_qualified = true; 90 } 91 92 protected void queueDeletePostCommitWork( 93 RowPosition pos) 94 throws StandardException 95 { 96 TransactionManager xact_mgr = open_conglom.getXactMgr(); 97 98 xact_mgr.addPostCommitWork( 99 new HeapPostCommit( 100 xact_mgr.getAccessManager(), 101 (Heap) open_conglom.getConglomerate(), 102 pos.current_page.getPageNumber())); 103 } 104 105 109 110 124 protected final boolean purgeCommittedDeletes( 125 Page page) 126 throws StandardException 127 { 128 boolean purgingDone = false; 129 130 int num_possible_commit_delete = 133 page.recordCount() - page.nonDeletedRecordCount(); 134 135 if (num_possible_commit_delete > 0) 136 { 137 for (int slot_no = page.recordCount() - 1; 141 slot_no >= 0; 142 slot_no--) 143 { 144 boolean row_is_committed_delete = 145 page.isDeletedAtSlot(slot_no); 146 147 if (row_is_committed_delete) 148 { 149 152 158 RecordHandle rh = 159 page.fetchFromSlot( 160 (RecordHandle) null, 161 slot_no, 162 RowUtil.EMPTY_ROW, 163 RowUtil.EMPTY_ROW_FETCH_DESCRIPTOR, 164 true); 165 166 row_is_committed_delete = 167 this.lockRowAtSlotNoWaitExclusive(rh); 168 169 if (row_is_committed_delete) 170 { 171 purgingDone = true; 172 173 page.purgeAtSlot(slot_no, 1, false); 174 } 175 } 176 } 177 } 178 if (page.recordCount() == 0) 179 { 180 181 this.removePage(page); 183 184 191 purgingDone = true; 192 } 193 194 return(purgingDone); 195 } 196 197 214 private RecordHandle doInsert(DataValueDescriptor[] row) 215 throws StandardException 216 { 217 Page page = null; 218 byte insert_mode; 219 220 RecordHandle rh; 221 222 if (SanityManager.DEBUG) 223 { 224 Heap heap = (Heap) open_conglom.getConglomerate(); 225 229 int invalidColumn = 230 RowUtil.columnOutOfRange( 231 row, null, heap.format_ids.length); 232 233 if (invalidColumn >= 0) 234 { 235 throw(StandardException.newException( 236 SQLState.HEAP_TEMPLATE_MISMATCH, 237 new Long (invalidColumn), 238 new Long (heap.format_ids.length))); 239 } 240 } 241 242 page = open_conglom.getContainer().getPageForInsert(0); 245 246 if (page != null) { 247 248 insert_mode = 250 (page.recordCount() == 0) ? 251 Page.INSERT_OVERFLOW : Page.INSERT_DEFAULT; 252 253 rh = page.insert(row, null, insert_mode, 256 AccessFactoryGlobals.HEAP_OVERFLOW_THRESHOLD); 257 page.unlatch(); 258 page = null; 259 260 if (rh != null) 263 { 264 return rh; 265 266 } 267 } 268 269 274 page = 275 open_conglom.getContainer().getPageForInsert( 276 ContainerHandle.GET_PAGE_UNFILLED); 277 278 if (page != null) 279 { 280 283 insert_mode = 285 (page.recordCount() == 0) ? 286 Page.INSERT_OVERFLOW : Page.INSERT_DEFAULT; 287 288 rh = page.insert(row, null, insert_mode, 289 AccessFactoryGlobals.HEAP_OVERFLOW_THRESHOLD); 290 291 page.unlatch(); 292 page = null; 293 294 if (rh != null) 297 { 298 return rh; 299 } 300 } 301 302 page = open_conglom.getContainer().addPage(); 303 304 307 rh = page.insert(row, null, Page.INSERT_OVERFLOW, 308 AccessFactoryGlobals.HEAP_OVERFLOW_THRESHOLD); 309 page.unlatch(); 310 page = null; 311 312 if (SanityManager.DEBUG) 313 { 314 SanityManager.ASSERT(rh != null); 316 } 317 318 return rh; 319 } 320 321 protected long load( 322 TransactionManager xact_manager, 323 Heap heap, 324 boolean createConglom, 325 RowLocationRetRowSource rowSource) 326 throws StandardException 327 { 328 long num_rows_loaded = 0; 329 330 if (SanityManager.DEBUG) 331 { 332 SanityManager.ASSERT(open_conglom == null, 333 "load expects container handle to be closed on entry."); 334 } 335 336 int mode = 340 (ContainerHandle.MODE_FORUPDATE | ContainerHandle.MODE_UNLOGGED); 341 342 if (createConglom) 345 mode |= ContainerHandle.MODE_CREATE_UNLOGGED; 346 347 OpenConglomerate open_conglom = new OpenHeap(); 348 349 if (open_conglom.init( 350 (ContainerHandle) null, 351 heap, 352 heap.format_ids, 353 xact_manager, 354 xact_manager.getRawStoreXact(), 355 false, 356 mode, 357 TransactionController.MODE_TABLE, 358 xact_manager.getRawStoreXact().newLockingPolicy( 359 LockingPolicy.MODE_CONTAINER, 360 TransactionController.ISOLATION_SERIALIZABLE, true), 361 (DynamicCompiledOpenConglomInfo) null) == null) 362 { 363 throw StandardException.newException( 364 SQLState.HEAP_CONTAINER_NOT_FOUND, 365 new Long (heap.id.getContainerId())); 366 } 367 368 this.init(open_conglom); 369 370 378 Page page = open_conglom.getContainer().addPage(); 379 380 boolean callbackWithRowLocation = rowSource.needsRowLocation(); 381 RecordHandle rh; 382 HeapRowLocation rowlocation; 383 384 if (callbackWithRowLocation) 385 rowlocation = new HeapRowLocation(); 386 else 387 rowlocation = null; 388 389 FormatableBitSet validColumns = rowSource.getValidColumns(); 390 391 try 392 { 393 DataValueDescriptor[] row; 395 while ((row = rowSource.getNextRowFromRowSource()) != null) 396 { 397 num_rows_loaded++; 398 399 if (SanityManager.DEBUG) 400 { 401 int invalidColumn = 405 RowUtil.columnOutOfRange( 406 row, validColumns, heap.format_ids.length); 407 408 if (invalidColumn >= 0) 409 { 410 throw(StandardException.newException( 411 SQLState.HEAP_TEMPLATE_MISMATCH, 412 new Long (invalidColumn), 413 new Long (heap.format_ids.length))); 414 } 415 } 416 417 418 if ((rh = page.insert( 420 row, validColumns, Page.INSERT_DEFAULT, 421 AccessFactoryGlobals.HEAP_OVERFLOW_THRESHOLD)) 422 == null) 423 { 424 426 page.unlatch(); 427 page = null; 428 429 page = open_conglom.getContainer().addPage(); 430 431 rh = page.insert( 438 row, validColumns, Page.INSERT_OVERFLOW, 439 AccessFactoryGlobals.HEAP_OVERFLOW_THRESHOLD); 440 441 } 442 443 if (callbackWithRowLocation) 447 { 448 rowlocation.setFrom(rh); 449 rowSource.rowLocation(rowlocation); 450 } 451 } 452 page.unlatch(); 453 page = null; 454 455 if (!heap.isTemporary()) 458 open_conglom.getContainer().flushContainer(); 459 } 460 finally 461 { 462 close(); 465 } 466 return(num_rows_loaded); 467 } 468 469 protected boolean lockRow( 470 RecordHandle rh, 471 int lock_oper, 472 boolean wait, 473 int lock_duration) 474 throws StandardException 475 { 476 boolean ret_val; 477 boolean forUpdate = 478 ((ConglomerateController.LOCK_UPD & lock_oper) != 0); 479 boolean forUpdateLock = 480 ((ConglomerateController.LOCK_UPDATE_LOCKS & lock_oper) != 0); 481 482 if (forUpdate && !forUpdateLock) 483 { 484 boolean forInsert = 485 ((ConglomerateController.LOCK_INS & lock_oper) != 0); 486 boolean forInsertPrevKey = 487 ((ConglomerateController.LOCK_INS_PREVKEY & lock_oper) != 0); 488 489 if (SanityManager.DEBUG) 490 { 491 SanityManager.ASSERT(!(forInsertPrevKey && forInsert)); 492 } 493 494 if (lock_duration == TransactionManager.LOCK_INSTANT_DURATION) 495 { 496 ret_val = 497 open_conglom.getContainer().getLockingPolicy(). 498 zeroDurationLockRecordForWrite( 499 open_conglom.getRawTran(), rh, forInsertPrevKey, wait); 500 } 501 else 502 { 503 ret_val = 504 open_conglom.getContainer().getLockingPolicy(). 505 lockRecordForWrite( 506 open_conglom.getRawTran(), rh, forInsert, wait); 507 } 508 } 509 else 510 { 511 if (SanityManager.DEBUG) 512 { 513 SanityManager.ASSERT( 514 (ConglomerateController.LOCK_INS & lock_oper) == 0); 515 SanityManager.ASSERT( 516 (ConglomerateController.LOCK_INS_PREVKEY & lock_oper) == 0); 517 } 518 519 ret_val = 520 open_conglom.getContainer().getLockingPolicy().lockRecordForRead( 521 open_conglom.getRawTran(), 522 open_conglom.getContainer(), rh, wait, forUpdate); 523 } 524 525 return(ret_val); 526 } 527 528 protected Page getUserPageNoWait(long pageno) 529 throws StandardException 530 { 531 return(open_conglom.getContainer().getUserPageNoWait(pageno)); 532 } 533 protected Page getUserPageWait(long pageno) 534 throws StandardException 535 { 536 return(open_conglom.getContainer().getUserPageWait(pageno)); 537 } 538 protected boolean lockRowAtSlotNoWaitExclusive(RecordHandle rh) 539 throws StandardException 540 { 541 return( 542 open_conglom.getContainer().getLockingPolicy(). 543 lockRecordForWrite( 544 open_conglom.getRawTran(), rh, false, false)); 545 } 546 protected void removePage(Page page) 547 throws StandardException 548 { 549 open_conglom.getContainer().removePage(page); 550 } 551 552 556 557 public int insert(DataValueDescriptor[] row) 558 throws StandardException 559 { 560 if (open_conglom.isClosed()) 561 { 562 if (open_conglom.getHold()) 563 { 564 open_conglom.reopen(); 565 } 566 else 567 { 568 throw(StandardException.newException( 569 SQLState.HEAP_IS_CLOSED, 570 open_conglom.getConglomerate().getId())); 571 } 572 } 573 574 doInsert(row); 575 576 return(0); 577 } 578 579 public void insertAndFetchLocation( 580 DataValueDescriptor[] row, 581 RowLocation templateRowLocation) 582 throws StandardException 583 { 584 if (open_conglom.isClosed()) 585 { 586 if (open_conglom.getHold()) 587 { 588 open_conglom.reopen(); 589 } 590 else 591 { 592 throw(StandardException.newException( 593 SQLState.HEAP_IS_CLOSED, 594 open_conglom.getConglomerate().getId())); 595 } 596 } 597 598 RecordHandle rh = doInsert(row); 599 if (SanityManager.DEBUG) 600 { 601 SanityManager.ASSERT( 602 templateRowLocation instanceof HeapRowLocation); 603 } 604 HeapRowLocation hrl = (HeapRowLocation) templateRowLocation; 605 hrl.setFrom(rh); 606 } 607 608 626 public boolean lockRow( 627 RowLocation loc, 628 int lock_operation, 629 boolean wait, 630 int lock_duration) 631 throws StandardException 632 { 633 RecordHandle rh = 634 ((HeapRowLocation) loc).getRecordHandle( 635 open_conglom.getContainer()); 636 637 return(lockRow(rh, lock_operation, wait, lock_duration)); 638 } 639 640 656 public void unlockRowAfterRead( 657 RowLocation loc, 658 boolean forUpdate, 659 boolean row_qualified) 660 throws StandardException 661 { 662 663 RecordHandle rh = 664 ((HeapRowLocation) loc).getRecordHandle( 665 open_conglom.getContainer()); 666 667 open_conglom.getContainer().getLockingPolicy(). 668 unlockRecordAfterRead( 669 open_conglom.getRawTran(), 670 open_conglom.getContainer(), 671 rh, 672 open_conglom.isForUpdate(), 673 row_qualified); 674 } 675 676 677 698 public boolean lockRow( 699 long page_num, 700 int record_id, 701 int lock_operation, 702 boolean wait, 703 int lock_duration) 704 throws StandardException 705 { 706 boolean ret_val; 707 708 RecordHandle rh = 709 open_conglom.getContainer().makeRecordHandle(page_num, record_id); 710 711 return(lockRow(rh, lock_operation, wait, lock_duration)); 712 } 713 714 public RowLocation newRowLocationTemplate() 715 throws StandardException 716 { 717 if (open_conglom.isClosed()) 718 { 719 if (open_conglom.getHold()) 720 { 721 open_conglom.reopen(); 722 } 723 else 724 { 725 throw(StandardException.newException( 726 SQLState.HEAP_IS_CLOSED, 727 open_conglom.getConglomerate().getId())); 728 } 729 } 730 731 return new HeapRowLocation(); 732 } 733 734 735 739 } 740 | Popular Tags |