📄 branchcontrolrow.java
字号:
/* Derby - Class org.apache.derby.impl.store.access.btree.BranchControlRow Copyright 1997, 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.btree;import org.apache.derby.iapi.reference.SQLState;import org.apache.derby.iapi.services.io.FormatIdUtil;import org.apache.derby.iapi.services.io.Storable;import org.apache.derby.iapi.services.io.StoredFormatIds;import org.apache.derby.iapi.services.sanity.SanityManager;import org.apache.derby.iapi.error.StandardException;import org.apache.derby.iapi.store.access.conglomerate.LogicalUndo;import org.apache.derby.iapi.store.access.AccessFactoryGlobals;import org.apache.derby.iapi.store.access.Qualifier;import org.apache.derby.iapi.store.access.RowUtil;import org.apache.derby.iapi.store.access.ScanController;import org.apache.derby.iapi.store.raw.ContainerHandle;import org.apache.derby.iapi.store.raw.FetchDescriptor;import org.apache.derby.iapi.store.raw.Page;import org.apache.derby.iapi.store.raw.RecordHandle;import org.apache.derby.iapi.types.DataValueDescriptor;import org.apache.derby.iapi.types.SQLLongint;import org.apache.derby.iapi.services.io.FormatableBitSet;/** * @format_id ACCESS_BTREE_BRANCHCONTROLROW_V1_ID * * @purpose Btree pages all have a control row at the front of every page. * To determine the type of row, read the first column which is a * format id and it tells what kind of control row it is. * * @upgrade RESOLVE. * * @disk_layout * column 1 - control row type : StorableFormatId * column 2 - left sibling page number : SQLLongint * column 3 - right sibling page number: SQLLongint * column 4 - parent page number : SQLLongint * column 5 - level number (0 is leaf) : SQLLongint * column 6 - isRoot : SQLLongint * column 7 - Conglomerate object : null unless it is root else * a Conglomerate object, matching * that of current table. * Currently this field * is only used by logical undo and * the type of object is inferred by * the logical undo code. * column 8 - left child page number : SQLLongint **//**A branch row contains key fields and the pointer to the child page.**/public class BranchControlRow extends ControlRow{ protected SQLLongint left_child_page = null; /** * Only allocate one child_pageno_buf to read the page pointer field into, * then cache to "empty" object for reuse by the page itself. **/ transient SQLLongint child_pageno_buf = null; /* Column assignments */ private static final int CR_LEFTCHILD = ControlRow.CR_COLID_LAST + 1; private static final int CR_COLID_LAST = CR_LEFTCHILD; private static final int CR_NCOLUMNS = CR_COLID_LAST + 1; /** * bit sets used to fetch single columns at a time. **/ protected static final FormatableBitSet CR_LEFTCHILD_BITMAP = new FormatableBitSet(CR_LEFTCHILD + 1); /* ** Constructors of BranchControlRow */ static { CR_LEFTCHILD_BITMAP.set(CR_LEFTCHILD); } /** * No arg constructor. * <p> * Public no arg constructor is for the monitor to call for format * id implementation, it should not be called for any other reason. **/ public BranchControlRow() { } public BranchControlRow( OpenBTree open_btree, Page page, int level, ControlRow parent, boolean isRoot, long left_child) throws StandardException { super(open_btree, page, level, parent, isRoot); this.left_child_page = new SQLLongint(left_child); // finish initializing the row to be used for interacting with // raw store to insert, fetch, and update the control row on the page. this.row[CR_LEFTCHILD] = left_child_page; // set up buffer to read a branch row's page number into. child_pageno_buf = new SQLLongint(); } /* ** Non - Debug/consistency check Methods of ControlRow: */ /** * Perform page specific initialization. * <p> * * @return The identifier to be used to open the conglomerate later. * **/ protected final void ControlRowInit() { child_pageno_buf = new SQLLongint(); } /** * Is the current page the leftmost leaf of tree? * <p> * * @return true if the current page is the leftmost leaf of the tree, * else return false. * * @exception StandardException Standard exception policy. **/ public boolean isLeftmostLeaf() throws StandardException { return(false); } /** * Is the current page the rightmost leaf of tree? * <p> * * @return true if the current page is the rightmost leaf of the tree, * else return false. * * @exception StandardException Standard exception policy. **/ public boolean isRightmostLeaf() throws StandardException { return(false); } /** * Get the number of columns in the control row. * <p> * Control rows all share the first columns as defined by this class and * then add columns to the end of the control row. For instance a branch * control row add a child page pointer field. * <p> * * @return The total number of columns in the control row. **/ protected final int getNumberOfControlRowColumns() { return(this.CR_NCOLUMNS); } public static long restartSplitFor( OpenBTree open_btree, DataValueDescriptor[] template, BranchControlRow parent, ControlRow child, DataValueDescriptor[] newbranchrow, DataValueDescriptor[] splitrow, int flag) throws StandardException { // release parent and current latch parent.release(); child.release(); parent = null; child = null; // Get the root page back, and perform a split following the // branch row which would not fit. ControlRow root = ControlRow.Get(open_btree, BTree.ROOTPAGEID); if (SanityManager.DEBUG) SanityManager.ASSERT(root.page.isLatched()); return(root.splitFor(open_btree, template, null, newbranchrow, flag)); } /** ** Perform a recursive search, ultimately returning the latched ** leaf page and row slot after which the given key belongs. ** The slot is returned in the result structure. If the key ** exists on the page, the result.exact will be true. Otherwise, ** result.exact will be false, and the row slot returned will be ** the one immediately preceding the position at which the key ** belongs. ** ** @exception StandardException Standard exception policy. **/ public ControlRow search(SearchParameters sp) throws StandardException { ControlRow childpage = null; long childpageid; boolean got_error = true; try { searchForEntry(sp); if (sp.searchForOptimizer) { // Update left_fraction to be used to esitimate the number of // rows left of the current search key. // Some search results leave the search positioned on the 0th // slot which is a control row, in branch pages this results // in following the left page pointer, there is no key // associated with this slot. Set left_rows to be the number // of leaf page pointers on the page which are left // of the current slot. float left_rows = sp.resultSlot; // include the control row count here, as it accounts for the // left page pointer which has no associated key. int row_count = this.page.recordCount(); if (this.getIsRoot()) { sp.current_fraction = 1; sp.left_fraction = 0; } // calculate the fraction of rows in the table which are left // of the current slot in the search. This number represents // the fraction of rows in the sub-tree which includes all // rows left of rows pointed at by the sub-tree to be followed // by the code below which descends the child page pointer. // After the search is // completed (sp.left_fraction * number of rows), is the // estimated number of rows to the left of the current row. sp.left_fraction += (sp.current_fraction) * (left_rows / row_count); sp.current_fraction = (sp.current_fraction) * (((float) 1) / row_count); } childpage = this.getChildPageAtSlot(sp.btree, sp.resultSlot); this.release(); got_error = false; return childpage.search(sp); } finally { if (got_error) { if (childpage != null) childpage.release(); if (this.page.isLatched()) this.release(); } } } /** * Search and return the left most leaf page. * <p> * Perform a recursive search, ultimately returning the * leftmost leaf page which is the first leaf page in the * leaf sibling chain. (This method might better be called * getFirstLeafPage()). * * @return The leftmost leaf page. * * @param btree The open btree to associate latches/locks with. * * @exception StandardException Standard exception policy. **/ protected ControlRow searchLeft(OpenBTree btree) throws StandardException { ControlRow childpage = null; boolean got_error = true; try { childpage = this.getLeftChild(btree); this.release(); got_error = false; return childpage.searchLeft(btree); } finally { if (got_error) { if (childpage != null) childpage.release(); if (this.page.isLatched()) this.release(); } } } /** * Search and return the right most leaf page. * <p> * Perform a recursive search, ultimately returning the * rightmost leaf page which is the last leaf page in the * leaf sibling chain. (This method might better be called * getLastLeafPage()). * * @return The rightmost leaf page. * * @param btree The open btree to associate latches/locks with. * * @exception StandardException Standard exception policy. **/ protected ControlRow searchRight(OpenBTree btree) throws StandardException { ControlRow childpage = null; boolean got_error = true; try { childpage = this.getRightChild(btree); this.release(); got_error = false; return(childpage.searchRight(btree)); } finally { if (got_error) { if (childpage != null) childpage.release(); if (this.page.isLatched()) this.release(); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -