1 21 22 package org.apache.derby.impl.store.raw.data; 23 24 import org.apache.derby.iapi.reference.SQLState; 25 import org.apache.derby.iapi.services.locks.Lockable; 26 import org.apache.derby.iapi.services.locks.Latch; 27 import org.apache.derby.iapi.services.locks.C_LockFactory; 28 import org.apache.derby.iapi.services.sanity.SanityManager; 29 30 import org.apache.derby.iapi.error.StandardException; 31 32 import org.apache.derby.iapi.store.access.TransactionController; 33 import org.apache.derby.iapi.store.access.SpaceInfo; 34 35 import org.apache.derby.iapi.store.raw.ContainerHandle; 36 import org.apache.derby.iapi.store.raw.LockingPolicy; 37 import org.apache.derby.iapi.store.raw.Page; 38 import org.apache.derby.iapi.store.raw.PageKey; 39 import org.apache.derby.iapi.store.raw.PageTimeStamp; 40 import org.apache.derby.iapi.store.raw.RecordHandle; 41 import org.apache.derby.iapi.store.raw.Transaction; 42 import org.apache.derby.iapi.store.raw.ContainerKey; 43 import org.apache.derby.iapi.store.raw.data.RawContainerHandle; 44 import org.apache.derby.iapi.store.raw.log.LogInstant; 45 import org.apache.derby.iapi.store.raw.xact.RawTransaction; 46 47 import org.apache.derby.iapi.util.ByteArray; 48 49 import java.util.Properties ; 50 import java.util.Hashtable ; 51 52 63 abstract class BaseContainer implements Lockable { 64 65 70 protected ContainerKey identity; 71 72 73 80 protected boolean isDropped; 81 82 83 92 protected boolean isCommittedDrop; 93 94 95 102 protected boolean isReusableRecordId = false; 103 104 BaseContainer() { 105 } 106 107 111 112 protected void fillInIdentity(ContainerKey key) { 113 114 if (SanityManager.DEBUG) { 115 SanityManager.ASSERT(identity == null || (identity == key)); 116 } 117 118 identity = key; 119 } 120 121 public void clearIdentity() { 122 if (SanityManager.DEBUG) { 123 SanityManager.ASSERT(identity != null); 124 } 125 126 identity = null; 127 } 128 129 public Object getIdentity() { 130 return identity; 131 } 132 133 136 137 public void lockEvent(Latch lockInfo) { 138 if (SanityManager.DEBUG) { 139 SanityManager.ASSERT(identity != null); 140 } 141 } 142 143 public boolean requestCompatible(Object requestedQualifier, Object grantedQualifier) { 144 if (SanityManager.DEBUG) { 145 SanityManager.ASSERT(identity != null); 146 } 147 return false; 148 } 149 150 public boolean lockerAlwaysCompatible() { 151 if (SanityManager.DEBUG) { 152 SanityManager.ASSERT(identity != null); 153 } 154 return false; 155 } 156 157 public void unlockEvent(Latch lockInfo) { 158 if (SanityManager.DEBUG) { 159 SanityManager.ASSERT(identity != null); 160 } 161 } 162 163 166 167 168 177 public void compressContainer(BaseContainerHandle handle) 178 throws StandardException 179 { 180 RawTransaction ntt = handle.getTransaction().startNestedTopTransaction(); 181 182 int mode = handle.getMode(); 183 184 if (SanityManager.DEBUG) 185 { 186 SanityManager.ASSERT((mode & ContainerHandle.MODE_FORUPDATE) == 187 ContainerHandle.MODE_FORUPDATE, 188 "addPage handle not for update"); 189 } 190 191 if ((mode & ContainerHandle.MODE_CREATE_UNLOGGED) == 0 && 197 (mode & ContainerHandle.MODE_UNLOGGED) == 198 ContainerHandle.MODE_UNLOGGED) 199 mode &= ~ContainerHandle.MODE_UNLOGGED; 200 201 BaseContainerHandle allocHandle = (BaseContainerHandle) 205 ntt.openContainer(identity, (LockingPolicy)null, mode); 206 207 if (allocHandle == null) 208 { 209 throw StandardException.newException( 210 SQLState.DATA_ALLOC_NTT_CANT_OPEN, 211 new Long (getSegmentId()), 212 new Long (getContainerId())); 213 } 214 215 ntt.getLockFactory().lockObject( 217 ntt, ntt, this, null, C_LockFactory.WAIT_FOREVER); 218 219 try 220 { 221 incrementReusableRecordIdSequenceNumber(); 222 compressContainer(ntt, allocHandle); 223 } 224 finally 225 { 226 ntt.commit(); 227 228 ntt.close(); 229 } 230 } 231 232 242 public abstract long getReusableRecordIdSequenceNumber(); 243 244 247 protected abstract void incrementReusableRecordIdSequenceNumber(); 248 249 250 267 public Page addPage(BaseContainerHandle handle, boolean isOverflow) throws StandardException { 268 269 RawTransaction ntt = handle.getTransaction().startNestedTopTransaction(); 270 271 int mode = handle.getMode(); 272 273 if (SanityManager.DEBUG) 274 { 275 SanityManager.ASSERT((mode & ContainerHandle.MODE_FORUPDATE) == 276 ContainerHandle.MODE_FORUPDATE, 277 "addPage handle not for update"); 278 } 279 280 if ((mode & ContainerHandle.MODE_CREATE_UNLOGGED) == 0 && 286 (mode & ContainerHandle.MODE_UNLOGGED) == 287 ContainerHandle.MODE_UNLOGGED) 288 mode &= ~ContainerHandle.MODE_UNLOGGED; 289 290 BaseContainerHandle allocHandle = (BaseContainerHandle)ntt.openContainer 294 (identity, (LockingPolicy)null, mode); 295 296 if (allocHandle == null) 297 { 298 throw StandardException.newException( 299 SQLState.DATA_ALLOC_NTT_CANT_OPEN, 300 new Long (getSegmentId()), 301 new Long (getContainerId())); 302 } 303 304 ntt.getLockFactory().lockObject( 306 ntt, ntt, this, null, C_LockFactory.WAIT_FOREVER); 307 308 BasePage newPage = null; 309 try 310 { 311 newPage = newPage(handle, ntt, allocHandle, isOverflow); 312 } 313 finally 314 { 315 if (newPage != null) 316 { 317 ntt.commitNoSync(Transaction.RELEASE_LOCKS); 323 } 324 else 325 { 326 ntt.abort(); 327 } 328 ntt.close(); 329 } 330 331 if (SanityManager.DEBUG) { 332 SanityManager.ASSERT(newPage.isLatched()); 333 } 334 335 if (!this.identity.equals(newPage.getPageId().getContainerId())) { 336 337 if (SanityManager.DEBUG) { 338 SanityManager.THROWASSERT("BaseContainer.addPage(), just got a new page from a different container" 339 + "\n this.identity = " + this.identity 340 + "\n newPage.getPageId().getContainerId() = " + newPage.getPageId().getContainerId() 341 + "\n handle is: " + handle 342 + "\n allocHandle is: " + allocHandle 343 + "\n this container is: " + this); 344 } 345 346 throw StandardException.newException( 347 SQLState.DATA_DIFFERENT_CONTAINER, 348 this.identity, newPage.getPageId().getContainerId()); 349 } 350 351 return newPage; 352 } 353 354 382 public abstract void getContainerProperties(Properties prop) 383 throws StandardException; 384 385 401 protected void removePage(BaseContainerHandle handle, BasePage page) 402 throws StandardException 403 { 404 try 405 { 406 if (SanityManager.DEBUG) 407 { 408 SanityManager.ASSERT(page.isLatched(), "page is not latched"); 409 } 410 411 RecordHandle deallocLock = 415 page.makeRecordHandle(RecordHandle.DEALLOCATE_PROTECTION_HANDLE); 416 417 if (!getDeallocLock(handle, deallocLock, 419 false , 420 false )) 421 { 422 throw StandardException.newException( 423 SQLState.DATA_CANNOT_GET_DEALLOC_LOCK, 424 page.getIdentity()); 425 } 426 427 deallocatePage(handle, page); 428 } 429 finally 430 { 431 if (page != null) 432 page.unlatch(); 433 } 434 435 } 436 437 443 protected boolean getDeallocLock(BaseContainerHandle handle, 444 RecordHandle deallocLock, 445 boolean wait, 446 boolean zeroDuration) 447 throws StandardException 448 { 449 RawTransaction tran = handle.getTransaction(); 452 453 LockingPolicy lp = 454 tran.newLockingPolicy( 455 LockingPolicy.MODE_RECORD, 456 TransactionController.ISOLATION_REPEATABLE_READ, 457 true); 459 PageKey pkey = new PageKey(identity, deallocLock.getPageNumber()); 460 if (lp != null) 461 { 462 if (zeroDuration) 463 return lp.zeroDurationLockRecordForWrite( 464 tran, deallocLock, false, wait); 465 else 466 return lp.lockRecordForWrite(tran, deallocLock, false, wait); 467 } 468 else 469 { 470 throw StandardException.newException( 471 SQLState.DATA_CANNOT_GET_DEALLOC_LOCK, pkey); 472 } 473 } 474 475 476 480 protected Page getAllocPage(BaseContainerHandle handle, long pageNumber, boolean wait) 481 throws StandardException 482 { 483 return latchPage(handle, getAllocPage(pageNumber), wait); 484 } 485 486 490 protected Page getAnyPage(BaseContainerHandle handle, long pageNumber, boolean wait) 491 throws StandardException 492 { 493 return latchPage(handle, getAnyPage(handle, pageNumber), wait); 494 } 495 496 497 501 protected Page getFirstPage(BaseContainerHandle handle) throws StandardException 502 { 503 return getFirstHeadPage(handle, true ); 504 } 505 506 510 protected Page getNextPage(BaseContainerHandle handle, long pageNumber) 511 throws StandardException 512 { 513 return getNextHeadPage(handle, pageNumber, true ); 514 } 515 516 519 protected BasePage latchPage(BaseContainerHandle handle, BasePage foundPage, boolean wait) 520 throws StandardException 521 { 522 if (foundPage != null) { 523 if (wait) { 524 foundPage.setExclusive(handle); 525 } else { 526 if (!foundPage.setExclusiveNoWait(handle)) 527 { 528 return null; 530 } 531 } 532 } 533 534 if (SanityManager.DEBUG) { 535 SanityManager.ASSERT((foundPage == null) || foundPage.isLatched()); 536 } 537 538 return foundPage; 539 540 } 541 542 543 552 protected boolean use(BaseContainerHandle handle, boolean forUpdate, 553 boolean droppedOK) 554 throws StandardException { 555 556 if (forUpdate && !canUpdate()) 558 { 559 throw StandardException.newException( 560 SQLState.DATA_CONTAINER_READ_ONLY); 561 } 562 563 if (!droppedOK && (getDroppedState() || getCommittedDropState())) { 565 return false; 566 } 567 568 return true; 569 } 570 571 577 protected void letGo(BaseContainerHandle handle) { 578 579 RawTransaction t = handle.getTransaction(); 580 581 handle.getLockingPolicy().unlockContainer(t, handle); 582 } 583 584 protected boolean getDroppedState() { 585 return isDropped; 586 } 587 588 protected boolean getCommittedDropState() 589 { 590 return isCommittedDrop; 591 } 592 593 594 protected boolean isReusableRecordId() 595 { 596 return isReusableRecordId; 597 } 598 599 public int getContainerStatus() 600 { 601 if (getCommittedDropState()) 602 return RawContainerHandle.COMMITTED_DROP; 603 604 if (getDroppedState()) 605 return RawContainerHandle.DROPPED; 606 607 return RawContainerHandle.NORMAL; 608 } 609 610 public long getContainerId() { 611 return identity.getContainerId(); 612 } 613 614 public long getSegmentId() { 615 return identity.getSegmentId(); 616 } 617 618 619 623 626 627 630 protected abstract SpaceInfo getSpaceInfo(BaseContainerHandle handle) 631 throws StandardException; 632 633 638 protected abstract boolean canUpdate(); 639 640 646 protected abstract void preDirty(boolean preDirtyOn); 647 648 649 655 protected abstract BasePage getPage(BaseContainerHandle handle, long pageNumber, 656 boolean wait) throws StandardException; 657 658 663 protected abstract BasePage getAllocPage(long pageNumber) throws StandardException; 664 665 671 protected abstract BasePage getAnyPage(BaseContainerHandle handle, long pageNumber) 672 throws StandardException; 673 674 708 protected abstract BasePage 709 reCreatePageForRedoRecovery( 710 BaseContainerHandle handle, 711 int pageFormat, 712 long pageNumber, 713 long pageOffset) 714 throws StandardException; 715 716 722 protected abstract ByteArray logCreateContainerInfo() 723 throws StandardException; 724 725 726 732 protected abstract BasePage getHeadPage(BaseContainerHandle handle, 733 long pagenumber, boolean wait) throws StandardException; 734 735 739 protected abstract BasePage getFirstHeadPage(BaseContainerHandle handle, 740 boolean wait) throws StandardException; 741 742 746 protected abstract BasePage getNextHeadPage(BaseContainerHandle handle, 747 long pageNumber, boolean wait) throws StandardException; 748 749 753 protected abstract BasePage getPageForInsert(BaseContainerHandle handle, 754 int flag) 755 throws StandardException; 756 757 protected abstract BasePage getPageForCompress( 758 BaseContainerHandle handle, 759 int flag, 760 long pageno) 761 throws StandardException; 762 763 protected abstract void truncatePages(long lastValidPagenum) 764 throws StandardException; 765 766 767 772 protected abstract BasePage newPage(BaseContainerHandle userhandle, 773 RawTransaction t, 774 BaseContainerHandle allocHandle, 775 boolean isOverflow) throws StandardException; 776 777 protected abstract void compressContainer( 778 RawTransaction t, 779 BaseContainerHandle allocHandle) 780 throws StandardException; 781 782 783 788 protected abstract void deallocatePage(BaseContainerHandle userhandle, 789 BasePage page) throws StandardException; 790 791 792 protected void truncate(BaseContainerHandle handle) throws StandardException { 793 if (SanityManager.DEBUG) { 794 SanityManager.THROWASSERT("truncate not supported"); 795 } 796 } 797 798 802 protected abstract void dropContainer(LogInstant instant, boolean drop); 803 804 805 816 protected abstract void removeContainer(LogInstant instant, boolean leaveStub) throws StandardException; 817 818 823 protected abstract long getContainerVersion() throws StandardException; 824 825 830 protected abstract void flushAll() throws StandardException; 831 832 835 protected abstract void prepareForBulkLoad(BaseContainerHandle handle, 836 int numPage); 837 838 843 protected abstract void clearPreallocThreshold(); 844 845 848 852 public abstract long getEstimatedRowCount(int flag) throws StandardException; 853 854 858 public abstract void setEstimatedRowCount(long count, int flag) throws StandardException; 859 860 864 public abstract long getEstimatedPageCount(BaseContainerHandle handle, int flag) throws StandardException; 865 866 873 protected abstract void backupContainer(BaseContainerHandle handle, 874 String backupContainerPath) throws StandardException ; 875 876 877 885 protected abstract void encryptContainer(BaseContainerHandle handle, 886 String newFilePath) 887 throws StandardException ; 888 889 890 893 894 897 protected void setDroppedState(boolean isDropped) { 898 this.isDropped = isDropped; 899 } 900 901 protected void setCommittedDropState(boolean isCommittedDrop) 902 { 903 this.isCommittedDrop = isCommittedDrop; 904 } 905 906 907 protected void setReusableRecordIdState(boolean isReusableRecordId) 908 { 909 this.isReusableRecordId = isReusableRecordId; 910 } 911 912 916 public boolean lockAttributes(int flag, Hashtable attributes) 918 { 919 return false; 920 } 921 922 923 924 } 925 926 | Popular Tags |