📄 basedatafilefactory.java
字号:
OK = true; } } catch (StandardException se) { se.printStackTrace(istream.getPrintWriter()); } } removeTempDirectory(); if (isReadOnly()) // do enough to close all files, then return { return; } // re-enable stub removal until a better method can be found. // only remove stub if caches are cleaned if (removeStubsOK && OK) removeStubs(); releaseJBMSLockOnDB(); } // end of stop /* ** CacheableFactory */ public Cacheable newCacheable(CacheManager cm) { if (cm == pageCache) { StoredPage sp = new StoredPage(); sp.setFactory(this); return sp; } // container cache return newContainerObject(); } /** Database creation finished @exception StandardException Standard cloudscape exception policy. */ public void createFinished() throws StandardException { if (!inCreateNoLog) { throw StandardException.newException( SQLState.FILE_DATABASE_NOT_IN_CREATE); } // the changes in cache are not logged, they have to be flushed to disk checkpoint(); inCreateNoLog = false; } /* ** Methods of DataFactory */ public ContainerHandle openContainer(RawTransaction t, ContainerKey containerId, LockingPolicy locking, int mode) throws StandardException { return openContainer(t, containerId, locking, mode, false /* is not dropped */); } /** @see DataFactory#openDroppedContainer @exception StandardException Standard Cloudscape error policy */ public RawContainerHandle openDroppedContainer(RawTransaction t, ContainerKey containerId, LockingPolicy locking, int mode) throws StandardException { // since we are opening a possible dropped container // lets not add any actions that will take palce on a commit. mode |= ContainerHandle.MODE_NO_ACTIONS_ON_COMMIT; return openContainer(t, containerId, locking, mode, true /* droppedOK */); } /** @see DataFactory#openContainer @exception StandardException Standard Cloudscape error policy */ private RawContainerHandle openContainer(RawTransaction t, ContainerKey identity, LockingPolicy locking, int mode, boolean droppedOK) throws StandardException { if (SanityManager.DEBUG) { if ((mode & (ContainerHandle.MODE_READONLY | ContainerHandle.MODE_FORUPDATE)) == (ContainerHandle.MODE_READONLY | ContainerHandle.MODE_FORUPDATE)) SanityManager.THROWASSERT("update and readonly mode specified"); } boolean waitForLock = ((mode & ContainerHandle.MODE_LOCK_NOWAIT) == 0); if ((mode & ContainerHandle.MODE_OPEN_FOR_LOCK_ONLY) != 0) { // Open a container for lock only, we don't care if it exists, is // deleted or anything about it. The container handle we return is // closed and cannot be used for fetch or update etc. BaseContainerHandle lockOnlyHandle = new BaseContainerHandle( getIdentifier(), t, identity, locking, mode); if (lockOnlyHandle.useContainer(true, waitForLock)) return lockOnlyHandle; else return null; } BaseContainerHandle c; // see if the container exists FileContainer container = (FileContainer) containerCache.find(identity); if (container == null) return null; if (identity.getSegmentId() == ContainerHandle.TEMPORARY_SEGMENT) { if (SanityManager.DEBUG) { SanityManager.ASSERT(container instanceof TempRAFContainer); } if ((mode & ContainerHandle.MODE_TEMP_IS_KEPT) == ContainerHandle.MODE_TEMP_IS_KEPT) { // if the mode is kept, then, we do not want to truncate mode |= ContainerHandle.MODE_UNLOGGED; } else { // this should be OK even if the table was opened read-only mode |= ContainerHandle.MODE_UNLOGGED | ContainerHandle.MODE_TRUNCATE_ON_ROLLBACK; } locking = t.newLockingPolicy( LockingPolicy.MODE_NONE, TransactionController.ISOLATION_NOLOCK, true); } else { // real tables if (inCreateNoLog) mode |= (ContainerHandle.MODE_UNLOGGED | ContainerHandle.MODE_CREATE_UNLOGGED); // make sure everything is logged if logArchived is turn on // clear all UNLOGGED flag if (!inCreateNoLog && logFactory.logArchived()) mode &= ~(ContainerHandle.MODE_UNLOGGED | ContainerHandle.MODE_CREATE_UNLOGGED); // if mode is UNLOGGED but not CREATE_HNLOGGED, then force the // container from cache when the transaction commits. For // CREATE_UNLOGGED, client has the responsibility of forcing the // cache. if (((mode & ContainerHandle.MODE_UNLOGGED) == ContainerHandle.MODE_UNLOGGED) && ((mode & ContainerHandle.MODE_CREATE_UNLOGGED) == 0)) { mode |= ContainerHandle.MODE_FLUSH_ON_COMMIT; } } PageActions pageActions = null; AllocationActions allocActions = null; if ((mode & ContainerHandle.MODE_FORUPDATE) == ContainerHandle.MODE_FORUPDATE) { if ((mode & ContainerHandle.MODE_UNLOGGED) == 0) { // get the current loggable actions pageActions = getLoggablePageActions(); allocActions = getLoggableAllocationActions(); } else { // unlogged pageActions = new DirectActions(); allocActions = new DirectAllocActions(); // RESOLVE: need to get rid of this automatic escalation if // MODE_CREATE_UNLOGGED for sure, why need it at all? // // locking = t.newLockingPolicy(LockingPolicy.MODE_CONTAINER, // TransactionController.ISOLATION_SERIALIZABLE, true); } } c = new BaseContainerHandle(getIdentifier(), t, pageActions, allocActions, locking, container, mode); // see if we can use the container try { if (!c.useContainer(droppedOK, waitForLock)) { containerCache.release(container); return null; } } catch (StandardException se) { containerCache.release(container); throw se; } return c; } /** Add a container with a specified page size to a segment. @exception StandardException Standard Cloudscape error policy */ public long addContainer( RawTransaction t, long segmentId, long input_containerid, int mode, Properties tableProperties, int temporaryFlag) throws StandardException { if (SanityManager.DEBUG) { if ((mode & ContainerHandle.MODE_CREATE_UNLOGGED) != 0) SanityManager.ASSERT( (mode & ContainerHandle.MODE_UNLOGGED) != 0, "cannot have CREATE_UNLOGGED set but UNLOGGED not set"); } // If client has provided a containerid then use it, else use the // internally generated one from getNextId(). long containerId = ((input_containerid != ContainerHandle.DEFAULT_ASSIGN_ID) ? input_containerid : getNextId()); ContainerKey identity = new ContainerKey(segmentId, containerId); boolean tmpContainer = (segmentId == ContainerHandle.TEMPORARY_SEGMENT); ContainerHandle ch = null; LockingPolicy cl = null; if (!tmpContainer) { // lock the container before we create it. if (isReadOnly()) { throw StandardException.newException( SQLState.DATA_CONTAINER_READ_ONLY); } cl = t.newLockingPolicy(LockingPolicy.MODE_CONTAINER, TransactionController.ISOLATION_SERIALIZABLE, true); if (SanityManager.DEBUG) SanityManager.ASSERT(cl != null); ch = t.openContainer(identity, cl, (ContainerHandle.MODE_FORUPDATE | ContainerHandle.MODE_OPEN_FOR_LOCK_ONLY)); } FileContainer container = (FileContainer) containerCache.create(identity, tableProperties); // create the first alloc page and the first user page, // if this fails for any reason the transaction // will roll back and the container will be dropped (removed) ContainerHandle containerHdl = null; Page firstPage = null; try { // if opening a temporary container with IS_KEPT flag set, // make sure to open it with IS_KEPT too. if (tmpContainer && ((temporaryFlag & TransactionController.IS_KEPT) == TransactionController.IS_KEPT)) { mode |= ContainerHandle.MODE_TEMP_IS_KEPT; } // open no-locking as we already have the container locked containerHdl = t.openContainer( identity, null, (ContainerHandle.MODE_FORUPDATE | mode)); // we just added it, containerHdl should not be null if (SanityManager.DEBUG) SanityManager.ASSERT(containerHdl != null); if (!tmpContainer) { // make it persistent (in concept if not in reality) RawContainerHandle rch = (RawContainerHandle)containerHdl; ContainerOperation lop = new ContainerOperation(rch, ContainerOperation.CREATE); // mark the container as pre-dirtied so that if a checkpoint // happens after the log record is sent to the log stream, the // cache cleaning will wait for this change. rch.preDirty(true); try { t.logAndDo(lop); // flush the log to reduce the window between where // the container is created & synced and the log record // for it makes it to disk. If we fail in this // window we will leave a stranded container file. flush(t.getLastLogInstant()); } finally { // in case logAndDo fail, make sure the container is not // stuck in preDirty state. rch.preDirty(false); } } firstPage = containerHdl.addPage(); } finally { if (firstPage != null) { firstPage.unlatch(); firstPage = null; } containerCache.release(container); if (containerHdl != null) { containerHdl.close(); containerHdl = null; } if (!tmpContainer) { // this should do nothing, since we requested isolation 3 // but we can't assume that, so call the policy correctly. cl.unlockContainer(t, ch); } } return containerId; } /** Add and load a stream container @exception StandardException Standard Cloudscape error policy */ public long addAndLoadStreamContainer(RawTransaction t, long segmentId, Properties tableProperties, RowSource rowSource) throws StandardException { long containerId = getNextId(); ContainerKey identity = new ContainerKey(segmentId, containerId); // create and load the stream container StreamFileContainer sContainer = new StreamFileContainer(identity, this, tableProperties); sContainer.load(rowSource); return containerId; } /** open an exsisting streamContainer @see DataFactory#openStreamContainer @exception StandardException Standard Cloudscape error policy */ public StreamContainerHandle openStreamContainer( RawTransaction t, long segmentId, long containerId, boolean hold) throws StandardException { ContainerKey identity = new ContainerKey(segmentId, containerId); StreamFileContainerHandle c; // open the container with the identity StreamFileContainer container = new StreamFileContainer(identity, this); container = container.open(false); if (container == null) return null; c = new StreamFileContainerHandle(getIdentifier(), t, container, hold); // see if we can use the container if (c.useContainer()) return c; else return null; } /** Drop a stream container. <P><B>Synchronisation</B> <P> This call will remove the container. @exception StandardException Standard Cloudscape error policy */ public void dropStreamContainer(RawTransaction t, long segmentId, long containerId)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -