📄 openconglomerate.java
字号:
/* Derby - Class org.apache.derby.impl.store.access.conglomerate.OpenConglomerate Copyright 2000, 2004 The Apache Software Foundation or its licensors, as applicable. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */package org.apache.derby.impl.store.access.conglomerate;import org.apache.derby.iapi.reference.SQLState;import org.apache.derby.iapi.services.sanity.SanityManager;import org.apache.derby.iapi.error.StandardException; import org.apache.derby.iapi.store.access.conglomerate.Conglomerate;import org.apache.derby.iapi.store.access.conglomerate.TransactionManager;import org.apache.derby.iapi.store.access.ConglomPropertyQueryable;import org.apache.derby.iapi.store.access.ConglomerateController;import org.apache.derby.iapi.store.access.DynamicCompiledOpenConglomInfo;import org.apache.derby.iapi.store.access.Qualifier;import org.apache.derby.iapi.store.access.RowUtil;import org.apache.derby.iapi.store.access.SpaceInfo;import org.apache.derby.iapi.store.access.TransactionController;import org.apache.derby.iapi.store.raw.ContainerHandle;import org.apache.derby.iapi.store.raw.FetchDescriptor;import org.apache.derby.iapi.store.raw.LockingPolicy;import org.apache.derby.iapi.store.raw.Page;import org.apache.derby.iapi.store.raw.RecordHandle;import org.apache.derby.iapi.store.raw.Transaction;import org.apache.derby.iapi.types.DataValueDescriptor;import org.apache.derby.iapi.types.RowLocation;import java.util.Properties; /**A Generic class which implements the basic functionality needed to operateon an "open" conglomerate. This class assumes the following general thingsabout the access method.<p>The access method is page based and contained in a single container maintainedby raw store. **/public abstract class OpenConglomerate{ /************************************************************************** * Fields of the class ************************************************************************** */ /** * The following group of fields are all basic input parameters which are * provided by the calling code when doing any sort of operation requiring * an open conglomerate (openScan(), open(), openCostController(), ...). * These are just saved values from what was initially input. **/ private Conglomerate init_conglomerate; private TransactionManager init_xact_manager; private Transaction init_rawtran; private int init_openmode; private int init_lock_level; private DynamicCompiledOpenConglomInfo init_dynamic_info; private boolean init_hold; private LockingPolicy init_locking_policy; /** * convenience boolean's for various mode's **/ private boolean useUpdateLocks; private boolean forUpdate; private boolean getBaseTableLocks; /** * scratch space used for stuff like templates, export rows, ... **/ private OpenConglomerateScratchSpace runtime_mem; /* * The open raw store container associated with this open conglomerate **/ private ContainerHandle container; /************************************************************************** * Constructors for This class: ************************************************************************** */ /************************************************************************** * Private methods for This class: ************************************************************************** */ /************************************************************************** * abstract methods of This class: ************************************************************************** */ /** * Return an "empty" row location object of the correct type. * <p> * * @return The empty Rowlocation. * * @exception StandardException Standard exception policy. **/ protected abstract RowLocation newRowLocationTemplate() throws StandardException; abstract public int[] getFormatIds(); /************************************************************************** * Public Methods implementing standard store row locking interfaces: * latchPage(RowPosition) * latchPageAndRepositionScan(RowPosition) * lockPositionForRead(RowPosition, aux_pos, moveForwardIfRowDisappears) * lockPositionForWrite(RowPosition, forInsert, wait) * unlockPositionAfterRead(RowPosition) ************************************************************************** */ /** * Latch the page containing the current RowPosition, and reposition scan. * <p> * Upon return the scan will hold a latch on the page to continue the * scan on. The scan will positioned on the record, just before the * next record to return. * * Note that for both hold cursor and read uncommitted support this routine * handles all cases of either the current position "dissappearing" (either * the row and/or page). The row and/or page can disappear by deleted * space being reclaimed post commit of that delete, and for some reason * the code requesting the reposition does not have locks which prevented * the space reclamation. Both hold cursor and read uncommitted scans are * examples of ways the caller will not prevent space reclamation from * claiming the position. * * This implementation also automatically updates the RowPosition to * point at the slot containing the current RowPosition. This slot * value is only valid while the latch is held. * * @return true if scan had to reposition because a row disappeared. * * @exception StandardException Standard exception policy. **/ public boolean latchPageAndRepositionScan(RowPosition pos) throws StandardException { boolean scan_repositioned = false; // Get the page the record handle refers to. pos.current_page = null; try { if (pos.current_rh != null) { pos.current_page = container.getPage(pos.current_rh.getPageNumber()); } } catch (Throwable t) { // Assume all errors are caused by the page "disappearing", will // handle this by positioning on next page in code below. // Note that in most cases if the page does not exist, getPage() // will return null rather than throw an exception, so this path // is hard to reach. // just continue on first record of the next page. // This should only happen if the page on which the scan was // positioned had all of it's row deleted and the page was // purged. // This can happen in a cursor held across a commit, where the // scan needs to be repositioned after the first "next()" in the // subsequent reopen() of the held cursor. } if (pos.current_page != null) { try { // reposition scan at the old position, now that latch is held. pos.current_slot = pos.current_page.getSlotNumber(pos.current_rh); } catch (StandardException se) { scan_repositioned = true; // The record that the scan was positioned on, no longer exists. // The normal way this happens is if we were positioned on // a deleted row, without holding a lock on it, and while // the scan did not hold the latch on the page a post commit // job purged the row as part of space reclamation. This can // happen in all ISOLATION level scans below serializable. pos.current_slot = pos.current_page.getNextSlotNumber(pos.current_rh); if (pos.current_slot == -1) { // in this case we there are no more rows on this page // to visit, so position on the next page. In this case // the row that the scan was positioned on was purged, // and there exists no rows now which are greater than this // record id. pos.current_page.unlatch(); pos.current_page = null; } else { // The way scans work, need to position on the row just // before the one to return "next". The first thing the // next loop will do is move the scan forward one row. pos.current_slot--; } } } if (pos.current_page == null) { // position on the next page. long current_pageno; if (pos.current_rh != null) { current_pageno = pos.current_rh.getPageNumber(); } else if (pos.current_pageno != ContainerHandle.INVALID_PAGE_NUMBER) { current_pageno = pos.current_pageno; } else { // no valid position, return a null page return(false); } pos.current_page = container.getNextPage(current_pageno); pos.current_slot = Page.FIRST_SLOT_NUMBER - 1; // now position is tracked by active page pos.current_pageno = ContainerHandle.INVALID_PAGE_NUMBER; scan_repositioned = true; } if (scan_repositioned) { pos.current_rh = null; } return(scan_repositioned); } /** * Latch the page containing the current RowPosition. * <p> * This implementation also automatically updates the RowPosition to * point at the slot containing the current RowPosition. This slot * value is only valid while the latch is held. * * @exception StandardException Standard exception policy. **/ public boolean latchPage(RowPosition pos) throws StandardException { pos.current_page = null; try { pos.current_page = container.getPage(pos.current_rh.getPageNumber()); } catch (Throwable t) { // Assume all errors are caused by the page "disappearing", will // handle this by returning false indicating that row can't be // found. This can easily happen when using read uncommitted // isolation level. }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -