001: /*
002:
003: Derby - Class org.apache.derby.impl.store.raw.data.BaseContainer
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to you under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: package org.apache.derby.impl.store.raw.data;
023:
024: import org.apache.derby.iapi.reference.SQLState;
025: import org.apache.derby.iapi.services.locks.Lockable;
026: import org.apache.derby.iapi.services.locks.Latch;
027: import org.apache.derby.iapi.services.locks.C_LockFactory;
028: import org.apache.derby.iapi.services.sanity.SanityManager;
029:
030: import org.apache.derby.iapi.error.StandardException;
031:
032: import org.apache.derby.iapi.store.access.TransactionController;
033: import org.apache.derby.iapi.store.access.SpaceInfo;
034:
035: import org.apache.derby.iapi.store.raw.ContainerHandle;
036: import org.apache.derby.iapi.store.raw.LockingPolicy;
037: import org.apache.derby.iapi.store.raw.Page;
038: import org.apache.derby.iapi.store.raw.PageKey;
039: import org.apache.derby.iapi.store.raw.PageTimeStamp;
040: import org.apache.derby.iapi.store.raw.RecordHandle;
041: import org.apache.derby.iapi.store.raw.Transaction;
042: import org.apache.derby.iapi.store.raw.ContainerKey;
043: import org.apache.derby.iapi.store.raw.data.RawContainerHandle;
044: import org.apache.derby.iapi.store.raw.log.LogInstant;
045: import org.apache.derby.iapi.store.raw.xact.RawTransaction;
046:
047: import org.apache.derby.iapi.util.ByteArray;
048:
049: import java.util.Properties;
050: import java.util.Hashtable;
051:
052: /**
053: BaseContainer is an abstract class that provides the locking bahaviour
054: for an object representing an active container, that is the actual
055: storage container, not the ContainerHandle interface. This class is designed
056: so that it can change the container it represents to avoid creating
057: a new object for every container.
058: <P>
059: This object implements lockable to provide an object to lock while a page is being
060: allocated.
061: <BR> MT - Mutable - mutable identity :
062: */
063: abstract class BaseContainer implements Lockable {
064:
065: /**
066: Identity of the container.
067:
068: <BR> MT - Mutable
069: */
070: protected ContainerKey identity;
071:
072: /**
073: Dropped state of the container.
074:
075: <BR> MT - mutable : single thread required. Either the container must be exclusive
076: locked by this thread, or the container must have no identity (ie. it is being created
077: or opened).
078: */
079: protected boolean isDropped;
080:
081: /**
082: Committed Drop state of the container. If a post comit action
083: determined that the drop container operation is committed, the whole
084: container may be removed and space reclaimed.
085:
086: <BR> MT - mutable : single thread required. Either the container must be exclusive
087: locked by this thread, or the container must have no identity (ie. it is being created
088: or opened).
089: */
090: protected boolean isCommittedDrop;
091:
092: /**
093: Is reusable recordId. By default, record Ids are not reusable when a
094: page is reused. However, under special circumstances, clients to raw
095: store may decide that record Ids may be reused after the page is
096: reused. When this flag is set, pages that are reused will have its
097: next recordId set to RecordHandle.FIRST_RECORD_ID
098: */
099: protected boolean isReusableRecordId = false;
100:
101: BaseContainer() {
102: }
103:
104: /*
105: ** portions of Cacheable interface, interface is actually implemented by
106: ** sub-class. This section also contains methods related to this interface.
107: */
108:
109: protected void fillInIdentity(ContainerKey key) {
110:
111: if (SanityManager.DEBUG) {
112: SanityManager.ASSERT(identity == null || (identity == key));
113: }
114:
115: identity = key;
116: }
117:
118: public void clearIdentity() {
119: if (SanityManager.DEBUG) {
120: SanityManager.ASSERT(identity != null);
121: }
122:
123: identity = null;
124: }
125:
126: public Object getIdentity() {
127: return identity;
128: }
129:
130: /*
131: ** Methods from Lockable, just require a single exclusive locker
132: */
133:
134: public void lockEvent(Latch lockInfo) {
135: if (SanityManager.DEBUG) {
136: SanityManager.ASSERT(identity != null);
137: }
138: }
139:
140: public boolean requestCompatible(Object requestedQualifier,
141: Object grantedQualifier) {
142: if (SanityManager.DEBUG) {
143: SanityManager.ASSERT(identity != null);
144: }
145: return false;
146: }
147:
148: public boolean lockerAlwaysCompatible() {
149: if (SanityManager.DEBUG) {
150: SanityManager.ASSERT(identity != null);
151: }
152: return false;
153: }
154:
155: public void unlockEvent(Latch lockInfo) {
156: if (SanityManager.DEBUG) {
157: SanityManager.ASSERT(identity != null);
158: }
159: }
160:
161: /*
162: ** Implementation specific methods
163: */
164:
165: /**
166: Release free space to the OS.
167: <P>
168: As is possible release any free space to the operating system. This
169: will usually mean releasing any free pages located at the end of the
170: file using the java truncate() interface.
171:
172: @exception StandardException Standard Cloudscape error policy
173: */
174: public void compressContainer(BaseContainerHandle handle)
175: throws StandardException {
176: RawTransaction ntt = handle.getTransaction()
177: .startNestedTopTransaction();
178:
179: int mode = handle.getMode();
180:
181: if (SanityManager.DEBUG) {
182: SanityManager
183: .ASSERT(
184: (mode & ContainerHandle.MODE_FORUPDATE) == ContainerHandle.MODE_FORUPDATE,
185: "addPage handle not for update");
186: }
187:
188: // if we are not in the same transaction as the one which created the
189: // container and the container may have logged some operation already,
190: // then we need to log allocation regardless of whether user changes
191: // are logged. Otherwise, the database will be corrupted if it
192: // crashed.
193: if ((mode & ContainerHandle.MODE_CREATE_UNLOGGED) == 0
194: && (mode & ContainerHandle.MODE_UNLOGGED) == ContainerHandle.MODE_UNLOGGED)
195: mode &= ~ContainerHandle.MODE_UNLOGGED;
196:
197: // make a handle which is tied to the ntt, not to the user transaction
198: // this handle is tied to. The container is already locked by the
199: // user transaction, open it nolock
200: BaseContainerHandle allocHandle = (BaseContainerHandle) ntt
201: .openContainer(identity, (LockingPolicy) null, mode);
202:
203: if (allocHandle == null) {
204: throw StandardException
205: .newException(SQLState.DATA_ALLOC_NTT_CANT_OPEN,
206: new Long(getSegmentId()), new Long(
207: getContainerId()));
208: }
209:
210: // Latch this container, the commit will release the latch
211: ntt.getLockFactory().lockObject(ntt, ntt, this , null,
212: C_LockFactory.WAIT_FOREVER);
213:
214: try {
215: incrementReusableRecordIdSequenceNumber();
216: compressContainer(ntt, allocHandle);
217: } finally {
218: ntt.commit();
219:
220: ntt.close();
221: }
222: }
223:
224: /**
225: * Get the reusable RecordId sequence number for the
226: * container. This sequence number should be incremented every time
227: * there is an operation which may cause RecorIds to be reused.
228: * This method can be used by clients to check if a RecordId they
229: * obtained is still guaranteed to be valid.
230: * If the sequence number has changed, the RecordId may have been
231: * reused for another row.
232: * @return sequence number for reusable RecordId
233: */
234: public abstract long getReusableRecordIdSequenceNumber();
235:
236: /**
237: * Increment the reusable RecordId sequence number.
238: */
239: protected abstract void incrementReusableRecordIdSequenceNumber();
240:
241: /**
242: Add a page to this container.
243:
244: <BR> MT - thread aware -
245:
246: The add page operation involves 2 transactions, one is the user
247: transaction (the transaction which owns the passed in handle), the
248: other one is a NestedTopTransaction created by this BaseContainer.
249:
250: The nestedTopTransaction is used by the underlying container to change
251: high contention structures, such as link list anchor or bit map pages.
252: The nestedTopTransaction commits or aborts before this routine returns.
253:
254: The user transaction is used to latch the newly created page.
255:
256: @exception StandardException Standard Cloudscape error policy
257: */
258: public Page addPage(BaseContainerHandle handle, boolean isOverflow)
259: throws StandardException {
260:
261: RawTransaction ntt = handle.getTransaction()
262: .startNestedTopTransaction();
263:
264: int mode = handle.getMode();
265:
266: if (SanityManager.DEBUG) {
267: SanityManager
268: .ASSERT(
269: (mode & ContainerHandle.MODE_FORUPDATE) == ContainerHandle.MODE_FORUPDATE,
270: "addPage handle not for update");
271: }
272:
273: // if we are not in the same transaction as the one which created the
274: // container and the container may have logged some operation already,
275: // then we need to log allocation regardless of whether user changes
276: // are logged. Otherwise, the database will be corrupted if it
277: // crashed.
278: if ((mode & ContainerHandle.MODE_CREATE_UNLOGGED) == 0
279: && (mode & ContainerHandle.MODE_UNLOGGED) == ContainerHandle.MODE_UNLOGGED)
280: mode &= ~ContainerHandle.MODE_UNLOGGED;
281:
282: // make a handle which is tied to the ntt, not to the user transaction this
283: // handle is tied to. The container is already locked by the user transaction,
284: // open it nolock
285: BaseContainerHandle allocHandle = (BaseContainerHandle) ntt
286: .openContainer(identity, (LockingPolicy) null, mode);
287:
288: if (allocHandle == null) {
289: throw StandardException
290: .newException(SQLState.DATA_ALLOC_NTT_CANT_OPEN,
291: new Long(getSegmentId()), new Long(
292: getContainerId()));
293: }
294:
295: // Latch this container, the commit will release the latch
296: ntt.getLockFactory().lockObject(ntt, ntt, this , null,
297: C_LockFactory.WAIT_FOREVER);
298:
299: BasePage newPage = null;
300: try {
301: newPage = newPage(handle, ntt, allocHandle, isOverflow);
302: } finally {
303: if (newPage != null) {
304: // it is ok to commit without syncing, as it is ok if this
305: // transaction never makes it to the db, if no subsequent
306: // log record makes it to the log. If any subsequent log
307: // record is sync'd then this transaction will be sync'd
308: // as well.
309: ntt.commitNoSync(Transaction.RELEASE_LOCKS);
310: } else {
311: ntt.abort();
312: }
313: ntt.close();
314: }
315:
316: if (SanityManager.DEBUG) {
317: SanityManager.ASSERT(newPage.isLatched());
318: }
319:
320: if (!this .identity.equals(newPage.getPageId().getContainerId())) {
321:
322: if (SanityManager.DEBUG) {
323: SanityManager
324: .THROWASSERT("BaseContainer.addPage(), just got a new page from a different container"
325: + "\n this.identity = "
326: + this .identity
327: + "\n newPage.getPageId().getContainerId() = "
328: + newPage.getPageId().getContainerId()
329: + "\n handle is: "
330: + handle
331: + "\n allocHandle is: "
332: + allocHandle
333: + "\n this container is: " + this );
334: }
335:
336: throw StandardException.newException(
337: SQLState.DATA_DIFFERENT_CONTAINER, this .identity,
338: newPage.getPageId().getContainerId());
339: }
340:
341: return newPage;
342: }
343:
344: /**
345: * Request the system properties associated with a container.
346: * <p>
347: * Request the value of properties that are associated with a container.
348: * The following properties can be requested:
349: * derby.storage.pageSize
350: * derby.storage.pageReservedSpace
351: * derby.storage.minimumRecordSize
352: * <p>
353: * To get the value of a particular property add it to the property list,
354: * and on return the value of the property will be set to it's current
355: * value. For example:
356: *
357: * get_prop(BaseContainer base)
358: * {
359: * Properties prop = new Properties();
360: * prop.put("derby.storage.pageSize", "");
361: * base.getContainerProperties(prop);
362: *
363: * System.out.println(
364: * "container's page size = " +
365: * prop.getProperty("derby.storage.pageSize");
366: * }
367: *
368: * @param prop Property list to fill in.
369: *
370: * @exception StandardException Standard exception policy.
371: **/
372: public abstract void getContainerProperties(Properties prop)
373: throws StandardException;
374:
375: /**
376: Remove a page from this container. The page will be unlatched by this
377: routine before it returns.
378:
379: Unlike addPage, this method done as part of the user transaction.
380: The removed page is not usable by anyone until the user transaction
381: comits.
382: If the user transaction rolls back, the removed page is un-removed.
383:
384: <BR> MT - thread aware -
385:
386: @param handle the container handle that has opened the container and latched the page
387: @param page the latched page that is to be deallocated
388:
389: @exception StandardException Standard Cloudscape error policy
390: */
391: protected void removePage(BaseContainerHandle handle, BasePage page)
392: throws StandardException {
393: try {
394: if (SanityManager.DEBUG) {
395: SanityManager.ASSERT(page.isLatched(),
396: "page is not latched");
397: }
398:
399: // get dealloc lock nowait on the page to be deallocated
400: // this lock is held until this transaction commits.
401: // then gc can free this page
402: RecordHandle deallocLock = page
403: .makeRecordHandle(RecordHandle.DEALLOCATE_PROTECTION_HANDLE);
404:
405: // don't get deallocLock wait because caller have a page latched
406: if (!getDeallocLock(handle, deallocLock,
407: false /* no wait */, false /* not zeroDuration */)) {
408: throw StandardException.newException(
409: SQLState.DATA_CANNOT_GET_DEALLOC_LOCK, page
410: .getIdentity());
411: }
412:
413: deallocatePage(handle, page);
414: } finally {
415: if (page != null)
416: page.unlatch();
417: }
418:
419: }
420:
421: /**
422: Get the special dealloc lock on the page - the lock is gotten by the
423: transaction that owns the container handle
424:
425: @exception StandardException Standard Cloudscape error policy
426: */
427: protected boolean getDeallocLock(BaseContainerHandle handle,
428: RecordHandle deallocLock, boolean wait, boolean zeroDuration)
429: throws StandardException {
430: // get deallocate lock on page so that the GC won't attempt to
431: // free and re-allocate it until the transaction commits
432: RawTransaction tran = handle.getTransaction();
433:
434: LockingPolicy lp = tran.newLockingPolicy(
435: LockingPolicy.MODE_RECORD,
436: TransactionController.ISOLATION_REPEATABLE_READ, true); // striterOK
437:
438: PageKey pkey = new PageKey(identity, deallocLock
439: .getPageNumber());
440: if (lp != null) {
441: if (zeroDuration)
442: return lp.zeroDurationLockRecordForWrite(tran,
443: deallocLock, false, wait);
444: else
445: return lp.lockRecordForWrite(tran, deallocLock, false,
446: wait);
447: } else {
448: throw StandardException.newException(
449: SQLState.DATA_CANNOT_GET_DEALLOC_LOCK, pkey);
450: }
451: }
452:
453: /**
454: Get an allocation page and latch it.
455: @exception StandardException Standard Cloudscape error policy
456: */
457: protected Page getAllocPage(BaseContainerHandle handle,
458: long pageNumber, boolean wait) throws StandardException {
459: return latchPage(handle, getAllocPage(pageNumber), wait);
460: }
461:
462: /**
463: Get any page and latch it .
464: @exception StandardException Standard Cloudscape error policy
465: */
466: protected Page getAnyPage(BaseContainerHandle handle,
467: long pageNumber, boolean wait) throws StandardException {
468: return latchPage(handle, getAnyPage(handle, pageNumber), wait);
469: }
470:
471: /**
472: Get the first valid page. Result is latched.
473: @exception StandardException Standard Cloudscape error policy
474: */
475: protected Page getFirstPage(BaseContainerHandle handle)
476: throws StandardException {
477: return getFirstHeadPage(handle, true /* wait */);
478: }
479:
480: /**
481: Get the next valid page and latch it
482: @exception StandardException Standard Cloudscape error policy
483: */
484: protected Page getNextPage(BaseContainerHandle handle,
485: long pageNumber) throws StandardException {
486: return getNextHeadPage(handle, pageNumber, true /* wait */);
487: }
488:
489: /*
490: utility to latch a page
491: */
492: protected BasePage latchPage(BaseContainerHandle handle,
493: BasePage foundPage, boolean wait) throws StandardException {
494: if (foundPage != null) {
495: if (wait) {
496: foundPage.setExclusive(handle);
497: } else {
498: if (!foundPage.setExclusiveNoWait(handle)) {
499: // sub-class will release page from the cache if required.
500: return null;
501: }
502: }
503: }
504:
505: if (SanityManager.DEBUG) {
506: SanityManager.ASSERT((foundPage == null)
507: || foundPage.isLatched());
508: }
509:
510: return foundPage;
511:
512: }
513:
514: /**
515: Lock the container and mark the container as in-use by this container handle.
516:
517: @param droppedOK if true, use this container even if it is dropped.,
518: @return true if the container can be used, false if it has been dropped
519: since the lock was requested and droppedOK is not true.
520:
521: @exception StandardException I cannot be opened for update.
522: */
523: protected boolean use(BaseContainerHandle handle,
524: boolean forUpdate, boolean droppedOK)
525: throws StandardException {
526:
527: // see if the container can be updated
528: if (forUpdate && !canUpdate()) {
529: throw StandardException
530: .newException(SQLState.DATA_CONTAINER_READ_ONLY);
531: }
532:
533: // if the container is dropped, cannot see if unless droppedOK is set
534: if (!droppedOK
535: && (getDroppedState() || getCommittedDropState())) {
536: return false;
537: }
538:
539: return true;
540: }
541:
542: /**
543: Discontinue use of this container. Note that the unlockContainer
544: call made from this method may not release any locks. The container
545: lock may be held until the end of the transaction.
546:
547: */
548: protected void letGo(BaseContainerHandle handle) {
549:
550: RawTransaction t = handle.getTransaction();
551:
552: handle.getLockingPolicy().unlockContainer(t, handle);
553: }
554:
555: protected boolean getDroppedState() {
556: return isDropped;
557: }
558:
559: protected boolean getCommittedDropState() {
560: return isCommittedDrop;
561: }
562:
563: protected boolean isReusableRecordId() {
564: return isReusableRecordId;
565: }
566:
567: public int getContainerStatus() {
568: if (getCommittedDropState())
569: return RawContainerHandle.COMMITTED_DROP;
570:
571: if (getDroppedState())
572: return RawContainerHandle.DROPPED;
573:
574: return RawContainerHandle.NORMAL;
575: }
576:
577: public long getContainerId() {
578: return identity.getContainerId();
579: }
580:
581: public long getSegmentId() {
582: return identity.getSegmentId();
583: }
584:
585: //public int getPageSize() {
586: // return pageSize();
587: //}
588:
589: /*
590: ** Methods that need to be provided by a sub-class.
591: */
592:
593: /**
594: Get information about space used by the container.
595: **/
596: protected abstract SpaceInfo getSpaceInfo(BaseContainerHandle handle)
597: throws StandardException;
598:
599: /**
600: Can the container be updated.
601:
602: @return true if the container can be updated, false otherwise.
603: */
604: protected abstract boolean canUpdate();
605:
606: /**
607: The container is about to be modified.
608: Loggable actions use this to make sure the container gets cleaned if a
609: checkpoint is taken after any log record is sent to the log stream but
610: before the container is actually dirtied.
611: */
612: protected abstract void preDirty(boolean preDirtyOn);
613:
614: /**
615: Return a BasePage that represents the given page number in this container.
616: The resulting page is latched.
617:
618: @exception StandardException Standard Cloudscape error policy
619: */
620: protected abstract BasePage getPage(BaseContainerHandle handle,
621: long pageNumber, boolean wait) throws StandardException;
622:
623: /**
624: Return a BasePage that represents the given alloc page number in this container.
625:
626: @exception StandardException Standard Cloudscape error policy
627: */
628: protected abstract BasePage getAllocPage(long pageNumber)
629: throws StandardException;
630:
631: /**
632: Return a BasePage that represents any page - alloc page, valid page, free page,
633: dealloced page etc. The only requirement is that the page is initialized...
634:
635: @exception StandardException Cloudscape Standard error policy
636: */
637: protected abstract BasePage getAnyPage(BaseContainerHandle handle,
638: long pageNumber) throws StandardException;
639:
640: /**
641: * ReCreate a page for rollforward recovery.
642: * <p>
643: * During redo recovery it is possible for the system to try to redo
644: * the creation of a page (ie. going from non-existence to version 0).
645: * It first trys to read the page from disk, but a few different types
646: * of errors can occur:
647: * o the page does not exist at all on disk, this can happen during
648: * rollforward recovery applied to a backup where the file was
649: * copied and the page was added to the file during the time frame
650: * of the backup but after the physical file was copied.
651: * o space in the file exists, but it was never initalized. This
652: * can happen if you happen to crash at just the right moment during
653: * the allocation process. Also
654: * on some OS's it is possible to read from a part of the file that
655: * was not ever written - resulting in garbage from the store's
656: * point of view (often the result is all 0's).
657: *
658: * All these errors are easy to recover from as the system can easily
659: * create a version 0 from scratch and write it to disk.
660: *
661: * Because the system does not sync allocation of data pages, it is also
662: * possible at this point that whlie writing the version 0 to disk to
663: * create it we may encounter an out of disk space error (caught in this
664: * routine as a StandardException from the create() call. We can't
665: * recovery from this without help from outside, so the caught exception
666: * is nested and a new exception thrown which the recovery system will
667: * output to the user asking them to check their disk for space/errors.
668: *
669: * The arguments passed in need to be sufficient for the page cache to
670: * materialize a brand new page and write it to disk.
671: *
672: * @exception StandardException Standard exception policy.
673: **/
674: protected abstract BasePage reCreatePageForRedoRecovery(
675: BaseContainerHandle handle, int pageFormat,
676: long pageNumber, long pageOffset) throws StandardException;
677:
678: /**
679: Log all information on the container creation necessary to recreate teh
680: container during a load tran.
681:
682: @exception StandardException Cloudscape Standard error policy
683: */
684: protected abstract ByteArray logCreateContainerInfo()
685: throws StandardException;
686:
687: /**
688: Get only a valid, non-overflow page. If page number is either invalid
689: or overflow, returns null
690:
691: @exception StandardException Cloudscape Standard error policy
692: */
693: protected abstract BasePage getHeadPage(BaseContainerHandle handle,
694: long pagenumber, boolean wait) throws StandardException;
695:
696: /**
697: Get the first page in the container.
698: @exception StandardException Standard Cloudscape error policy
699: */
700: protected abstract BasePage getFirstHeadPage(
701: BaseContainerHandle handle, boolean wait)
702: throws StandardException;
703:
704: /**
705: Get the next page in the container.
706: @exception StandardException Standard Cloudscape error policy
707: */
708: protected abstract BasePage getNextHeadPage(
709: BaseContainerHandle handle, long pageNumber, boolean wait)
710: throws StandardException;
711:
712: /**
713: Get a potentially suitable page for insert and latch it.
714: @exception StandardException Standard Cloudscape error policy
715: */
716: protected abstract BasePage getPageForInsert(
717: BaseContainerHandle handle, int flag)
718: throws StandardException;
719:
720: protected abstract BasePage getPageForCompress(
721: BaseContainerHandle handle, int flag, long pageno)
722: throws StandardException;
723:
724: protected abstract void truncatePages(long lastValidPagenum)
725: throws StandardException;
726:
727: /**
728: Create a new page in the container.
729:
730: @exception StandardException Standard Cloudscape error policy
731: */
732: protected abstract BasePage newPage(BaseContainerHandle userhandle,
733: RawTransaction t, BaseContainerHandle allocHandle,
734: boolean isOverflow) throws StandardException;
735:
736: protected abstract void compressContainer(RawTransaction t,
737: BaseContainerHandle allocHandle) throws StandardException;
738:
739: /**
740: Deallocate a page from the container.
741:
742: @exception StandardException Standard Cloudscape error policy
743: */
744: protected abstract void deallocatePage(
745: BaseContainerHandle userhandle, BasePage page)
746: throws StandardException;
747:
748: protected void truncate(BaseContainerHandle handle)
749: throws StandardException {
750: if (SanityManager.DEBUG) {
751: SanityManager.THROWASSERT("truncate not supported");
752: }
753: }
754:
755: /**
756: Mark the container as drop or not drop depending on the input value.
757:
758: */
759: protected abstract void dropContainer(LogInstant instant,
760: boolean drop);
761:
762: /**
763: Remove the container and reclaim its space. Once executed, this
764: operation cannot be undone - as opposed to dropContainer which only
765: marks the container as dropped and can be rolled back.
766: <BR><B> This operation should only be called by post commit clean up </B>
767:
768: @param leaveStub if true, leave a stub. If false, remove everything
769: @see org.apache.derby.iapi.store.raw.data.RawContainerHandle#removeContainer
770:
771: @exception StandardException Standard Cloudscape error policy
772: */
773: protected abstract void removeContainer(LogInstant instant,
774: boolean leaveStub) throws StandardException;
775:
776: /**
777: Get the logged container version.
778:
779: @exception StandardException Standard Cloudscape error policy
780: */
781: protected abstract long getContainerVersion()
782: throws StandardException;
783:
784: /**
785: Flush all outstanding changes in this container to persistent storage.
786:
787: @exception StandardException Standard Cloudscape error policy
788: */
789: protected abstract void flushAll() throws StandardException;
790:
791: /**
792: The container will be grown vastly, prepare for it.
793: */
794: protected abstract void prepareForBulkLoad(
795: BaseContainerHandle handle, int numPage);
796:
797: /**
798: The container will have no pre-allocate threshold, i.e., if the
799: implementation supports it, page preallocation will happen
800: the next time a new page is allocated.
801: */
802: protected abstract void clearPreallocThreshold();
803:
804: /*
805: Cost estimates
806: */
807: /**
808: @see ContainerHandle#getEstimatedRowCount
809: @exception StandardException Standard Cloudscape error policy
810: */
811: public abstract long getEstimatedRowCount(int flag)
812: throws StandardException;
813:
814: /**
815: @see ContainerHandle#setEstimatedRowCount
816: @exception StandardException Standard Cloudscape error policy
817: */
818: public abstract void setEstimatedRowCount(long count, int flag)
819: throws StandardException;
820:
821: /**
822: @see ContainerHandle#getEstimatedPageCount
823: @exception StandardException Standard Cloudscape error policy
824: */
825: public abstract long getEstimatedPageCount(
826: BaseContainerHandle handle, int flag)
827: throws StandardException;
828:
829: /**
830: * Backup the container to the specified path.
831: *
832: * @param handle the container handle.
833: * @param backupContainerPath location of the backup container.
834: * @exception StandardException Standard Derby error policy
835: */
836: protected abstract void backupContainer(BaseContainerHandle handle,
837: String backupContainerPath) throws StandardException;
838:
839: /**
840: * Create encrypted version of the container with the
841: * user specified encryption properties.
842: *
843: * @param handle the container handle.
844: * @param newFilePath file to store the new encrypted version of the container
845: * @exception StandardException Standard Derby error policy
846: */
847: protected abstract void encryptContainer(
848: BaseContainerHandle handle, String newFilePath)
849: throws StandardException;
850:
851: /*
852: ** Methods to be used by sub-classes.
853: */
854:
855: /**
856: Set the container's dropped state
857: */
858: protected void setDroppedState(boolean isDropped) {
859: this .isDropped = isDropped;
860: }
861:
862: protected void setCommittedDropState(boolean isCommittedDrop) {
863: this .isCommittedDrop = isCommittedDrop;
864: }
865:
866: protected void setReusableRecordIdState(boolean isReusableRecordId) {
867: this .isReusableRecordId = isReusableRecordId;
868: }
869:
870: //protected void setPageSize(int pageSize) {
871: // identity.setPageSize(pageSize);
872: //}
873:
874: // Not interested in participating in the diagnostic virtual lock table.
875: public boolean lockAttributes(int flag, Hashtable attributes) {
876: return false;
877: }
878:
879: }
|