📄 branchcontrolrow.java
字号:
** RESOLVE: (mikem) does order of release matter. ** o ROOT : released. ** o ROOT_NEWCHILD: released. ** o ROOT_OLDCHILD: released. **/ private static void growRoot( OpenBTree open_btree, DataValueDescriptor[] template, BranchControlRow root) throws StandardException { ControlRow leftchild = null; BranchControlRow branch = null; try { if (SanityManager.DEBUG) { SanityManager.ASSERT(root.page.isLatched()); SanityManager.ASSERT(root.getIsRoot()); } // System.out.println("Growing root: control row = " + root); // System.out.println("Growing root: page = " + root.page); // Get and latch the current root's left child. This will become // the left child on the new branch page (and the new // branch will become the left child of the root). leftchild = root.getLeftChild(open_btree); // Allocate a new branch page. This one will take the // rows from the root, and remain at the old root's level. // Its parent is the root. branch = BranchControlRow.Allocate( open_btree, leftchild, root.getLevel(), root); // Copy all the index rows from the root to the new branch. // Purge the index rows from the root now that they're safely on the // new branch page. Leave the branch control row on the page. root.page.copyAndPurge(branch.page, 1, root.page.recordCount() - 1, 1); // Set the root's left child to be the new branch. root.setLeftChild(branch); // Move the root up a level root.setLevel(root.getLevel() + 1); // The parent of the old root's children has changed. // It used to be page 0 (the old root, but now it's // the new branch page. Fix this up. branch.fixChildrensParents(open_btree, leftchild); if (SanityManager.DEBUG) { if (SanityManager.DEBUG_ON("enableBtreeConsistencyCheck")) { root.checkConsistency(open_btree, null, false); branch.checkConsistency(open_btree, root, false); leftchild.checkConsistency(open_btree, branch, false); } } // At this point a unit of work in the split down the tree has // been performed in an internal transaction. This work must // be committed before any latches are released. open_btree.getXactMgr().commit(); } finally { // At the end of a growRoot() no latches are held, the caller must // restart at the root. // root.release(); if (branch != null) branch.release(); if (leftchild != null) leftchild.release(); } return; } /** * Allocate a new leaf page to the conglomerate. * * @exception StandardException Standard exception policy. */ private static BranchControlRow Allocate( OpenBTree open_btree, ControlRow leftchild, int level, ControlRow parent) throws StandardException { Page page = open_btree.container.addPage(); // Create a control row for the new page. BranchControlRow control_row = new BranchControlRow( open_btree, page, level, parent, false, leftchild.page.getPageNumber()); // Insert the control row on the page. byte insertFlag = Page.INSERT_INITIAL; insertFlag |= Page.INSERT_DEFAULT; page.insertAtSlot( Page.FIRST_SLOT_NUMBER, control_row.getRow(), (FormatableBitSet) null, (LogicalUndo)null, insertFlag, AccessFactoryGlobals.BTREE_OVERFLOW_THRESHOLD); // Page is returned latched. return(control_row); } protected void setLeftChildPageno(long leftchild_pageno) throws StandardException { // Store the field. if (left_child_page == null) left_child_page = new SQLLongint(leftchild_pageno); else this.left_child_page.setValue(leftchild_pageno); // Write the field through to the underlying row this.page.updateFieldAtSlot( CR_SLOT, CR_LEFTCHILD, this.left_child_page, null); } protected void setLeftChild(ControlRow leftchild) throws StandardException { this.setLeftChildPageno(leftchild.page.getPageNumber()); } /** ** A branch page that has just been allocated as part ** of a split has index rows and a left child pointer ** that were copied from another page. The parent ** link on the corresponding pages will still point to ** the original page. This method fixes their parent ** pointers so that they point to the curren page like ** they're supposed to. ** <P> ** Note that maintaining the parent link is kind of a ** pain, and will slow down applications. It's only ** needed for consistency checks, so we may want to ** have implementations that don't bother to maintain it. ** <P) ** This **/ private void fixChildrensParents( OpenBTree btree, ControlRow leftchild) throws StandardException { ControlRow child = null; try { if (leftchild == null) { child = this.getLeftChild(btree); child.setParent(this.page.getPageNumber()); if (SanityManager.DEBUG) { if (SanityManager.DEBUG_ON("enableBtreeConsistencyCheck")) { child.checkConsistency(btree, this, false); } } child.release(); child = null; } else { leftchild.setParent(this.page.getPageNumber()); if (SanityManager.DEBUG) { if (SanityManager.DEBUG_ON("enableBtreeConsistencyCheck")) { leftchild.checkConsistency(btree, this, false); } } } int numslots = this.page.recordCount(); for (int slot = 1; slot < numslots; slot++) { child = getChildPageAtSlot(btree, slot); child.setParent(this.page.getPageNumber()); if (SanityManager.DEBUG) { if (SanityManager.DEBUG_ON("enableBtreeConsistencyCheck")) { child.checkConsistency(btree, this, false); } } child.release(); child = null; } } finally { if (child != null) child.release(); } } private long getChildPageIdAtSlot( OpenBTree btree, int slot) throws StandardException { long child_page_id; if (slot == 0) { child_page_id = this.getLeftChildPageno(); } else { this.page.fetchFieldFromSlot( slot, btree.getConglomerate().nKeyFields, child_pageno_buf); child_page_id = child_pageno_buf.getLong(); } return(child_page_id); } protected ControlRow getChildPageAtSlot( OpenBTree open_btree, int slot) throws StandardException { ControlRow child_control_row; if (slot == 0) { child_control_row = this.getLeftChild(open_btree); } else { this.page.fetchFieldFromSlot( slot, open_btree.getConglomerate().nKeyFields, child_pageno_buf); child_control_row = ControlRow.Get(open_btree, child_pageno_buf.getLong()); } return(child_control_row); } /** * Return the left child pointer for the page. * <p> * Leaf pages don't have children, so they override this and return null. * * @return The page which is the leftmost child of this page. * * @param open_btree The open btree to associate latches/locks with. * * @exception StandardException Standard exception policy. **/ public ControlRow getLeftChild(OpenBTree open_btree) throws StandardException { return(ControlRow.Get(open_btree, this.getLeftChildPageno())); } /** * Return the right child pointer for the page. * <p> * Leaf pages don't have children, so they override this and return null. * * @return The page which is the rightmost child of this page. * * @param open_btree The open btree to associate latches/locks with. * * @exception StandardException Standard exception policy. **/ protected ControlRow getRightChild(OpenBTree open_btree) throws StandardException { ControlRow right_child; int num_slots = this.page.recordCount(); // if num_slots is 1 then there are no branch rows, so just follow // the left page pointer, else if num_slots is > 1 then follow the // last branch row to find the rightmost child. right_child = (num_slots == 1 ? ControlRow.Get(open_btree, this.getLeftChildPageno()) : getChildPageAtSlot(open_btree, (num_slots - 1))); return(right_child); } /** ** Return the left child page number for the page. Leaf pages ** don't have left children, so they override this and return ** null. **/ long getLeftChildPageno() throws StandardException { if (this.left_child_page == null) { this.left_child_page = new SQLLongint(); scratch_row[CR_LEFTCHILD] = this.left_child_page; fetchDesc.setValidColumns(CR_LEFTCHILD_BITMAP); this.page.fetchFromSlot( (RecordHandle) null, CR_SLOT, scratch_row, fetchDesc, false); } return(left_child_page.getLong()); } /* * TypedFormat: */ /** Return my format identifier. @see org.apache.derby.iapi.services.io.TypedFormat#getTypeFormatId */ public int getTypeFormatId() { return StoredFormatIds.ACCESS_BTREE_BRANCHCONTROLROW_V1_ID; } /** * Return a new template for reading a data row from the current page. * <p> * Default implementation for rows which are the same as the conglomerates * template, sub-classes can alter if underlying template is different * (for instance branch rows add an extra field at the end). * * @return Newly allocated template. * * @exception StandardException Standard exception policy. **/ public DataValueDescriptor[] getRowTemplate(OpenBTree open_btree) throws StandardException { return(BranchRow.createEmptyTemplate( open_btree.getConglomerate()).getRow()); } /** ** The standard toString. **/ public String toString() { if (SanityManager.DEBUG) { String string = super.toString(); try { string += "left child page = " + getLeftChildPageno() + ";"; } catch (Throwable t) { string += "error encountered while doing ControlRow.toString()"; } return(string); } else { return(null); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -