📄 controlrow.java
字号:
if (this.btree == null) { // use format id to create empty instance of Conglomerate class this.btree = (BTree) Monitor.newInstanceFromIdentifier(format_id); scratch_row[CR_CONGLOM_COLID] = this.btree; fetchDesc.setValidColumns(CR_CONGLOM_BITSET); this.page.fetchFromSlot( (RecordHandle) null, CR_SLOT, scratch_row, fetchDesc, false); } return this.btree; } /** * Set the conglomerate field in the btree. * <p> * Sets the btree field of the control row. Updates just the disk copy. * * @exception StandardException Standard exception policy. **/ private void setConglom(BTree btree) throws StandardException { // Store the field. Delay faulting value into object until getConlgom() // call, which in general only happens during recovery. // Write the field through to the underlying row. this.page.updateFieldAtSlot(CR_SLOT, CR_CONGLOM_COLID, btree, null); } /* ** Methods for getting control rows from pages. */ /** Get the control row from the given page in the b-tree. The returned control row will be of the correct type for the page (i.e., either a LeafControlRow or a BranchControlRow). @exception StandardException Standard exception policy. **/ public static ControlRow Get(OpenBTree open_btree, long pageNumber) throws StandardException { return(ControlRow.Get(open_btree.container, pageNumber)); } public static ControlRow Get(ContainerHandle container, long pageNumber) throws StandardException { if (SanityManager.DEBUG) { SanityManager.ASSERT(container != null, "ControlRow.Get() is being called on a closed container."); } // Get the page, waiting if necessary. The page is returned latched. Page page = container.getPage(pageNumber); if (SanityManager.DEBUG) { if (page == null) SanityManager.THROWASSERT( "No page at pagenumber: " + pageNumber + "; ContainerHandle = " + container); } // Return the corresponding control row. return GetControlRowForPage(container, page); } /** Get the control row for the given page if the latch on the page can be obtained without waiting, else return null. @exception StandardException Standard exception policy. **/ public static ControlRow GetNoWait( OpenBTree open_btree, long pageNumber) throws StandardException { // Try to get the page without waiting. If we would have // to wait, return null. Page page = open_btree.container.getUserPageNoWait(pageNumber); if (page == null) return null; // Got the page without waiting. Return the corresponding // control row. return GetControlRowForPage(open_btree.container, page); } protected static ControlRow GetControlRowForPage( ContainerHandle container, Page page) throws StandardException { ControlRow cr = null; // See if the control row is still cached with the page // If so, just use the cached control row. AuxObject auxobject = page.getAuxObject(); if (auxobject != null) return (ControlRow) auxobject; if (SanityManager.DEBUG) SanityManager.ASSERT(page.recordCount() >= 1); // No cached control row, so create a new one. // Use the version field to determine the type of the row to // create. This routine depends on the version field being the same // number column in all control rows. StorableFormatId version = new StorableFormatId(); DataValueDescriptor[] version_ret = new DataValueDescriptor[1]; version_ret[0] = version; // TODO (mikem) - get rid of this new. page.fetchFromSlot( (RecordHandle) null, CR_SLOT, version_ret, new FetchDescriptor(1, CR_VERSION_BITSET, (Qualifier[][]) null), false); // use format id to create empty instance of right Conglomerate class cr = (ControlRow) Monitor.newInstanceFromIdentifier(version.getValue()); cr.page = page; // call page specific initialization. cr.ControlRowInit(); // cache this Control row with the page in the cache. page.setAuxObject(cr); return(cr); } /** Release this control row's resources. **/ public void release() { if (SanityManager.DEBUG) SanityManager.ASSERT(page != null); if (page != null) page.unlatch(); // It might be nice to set the page object to null, but // since there might be multiple control rows on this // page, we'd have to maintain a use count. Rather than // doing that we'll let the garbage collector earn its // keep. We are also expecting that the raw store will // throw errors if we attempt to use an unlatched page. } /** Search this index page. <P> This method is very performance sensitive. It is the intention that no object allocations occur during the execution of this method. <P> This method performs a binary search on the page and finds the entry i on the page such that entry[i] <= key < entry[i+1]. The result of the search is filled into the passed in params structure. @param params the parameters of the search @exception StandardException could be thrown by underlying raw store operations. @see SearchParameters **/ protected void searchForEntry(SearchParameters params) throws StandardException { if (SanityManager.DEBUG) { // System.out.println("searchForEntry() enter: params:" + params); // System.out.println("searchForEntry() enter: this:" + this); // System.out.println("searchForEntry() enter: this page:" + debugPage(params.btree)); } // leftrange and rightrange indicates the range of slots to search. // The range starts as all the slots on the page not including slot // 0 which is the control row. int leftrange = 1; int rightrange = page.recordCount() - 1; // leftslot and rightslot if non-zero, mean that the key has been // compared to the row at that slot. If non-zero the key must be // greater than the key at leftslot and the key must be lest than // the key at rightslot. int leftslot = 0; int rightslot = rightrange + 1; int midslot; int compare_ret; // search until you either exactly find the key, or you have // compared 2 adjacent rows and found the value must exist between // the 2. if (this.use_last_search_result_hint) { // make sure to set midslot to point to somwhere in the legal range. midslot = ((this.last_search_result == 0) ? 1 : this.last_search_result); if (midslot > rightrange) midslot = rightrange; } else { // if we don't think we have a good hint where to start the search // just go to the middle. midslot = (leftrange + rightrange) / 2; } if (SanityManager.DEBUG) { if ((leftslot != (rightslot - 1)) && !(midslot >= leftrange && midslot <= rightrange)) { SanityManager.THROWASSERT( "midslot = " + midslot + ";leftrange = " + leftrange + ";rightrange = " + rightrange); } } while (leftslot != (rightslot - 1)) { // Compare the index row to the key. compare_ret = CompareIndexRowFromPageToKey( this, midslot, params.template, params.searchKey, params.btree.getConglomerate().nUniqueColumns, params.partial_key_match_op, params.btree.getConglomerate().ascDescInfo); if (compare_ret == 0) { // Found exact match params.resultSlot = midslot; params.resultExact = true; // update the hints based on result of the search. use_last_search_result_hint = (midslot == this.last_search_result) ? true : false; this.last_search_result = midslot; return; } else if (compare_ret > 0) { // key falls to the left of midslot rightslot = midslot; rightrange = midslot - 1; } else { // key falls to the right of midslot leftslot = midslot; leftrange = midslot + 1; } midslot = (leftrange + rightrange) / 2; //midslot = (leftrange + rightrange) >> 1; } // update the hints based on result of the search. this.use_last_search_result_hint = (leftslot == this.last_search_result); this.last_search_result = leftslot; // no exact match found, leftslot will point at the slot on the // page just before where the row should be inserted. In the case // where the key is before rows on the page then leftslot will be // 0 (an empty page is a special case of this). if (SanityManager.DEBUG) { if (leftslot != rightslot - 1) SanityManager.THROWASSERT( "leftslot = " + leftslot + "; rightslot = " + rightslot); } params.resultSlot = leftslot; params.resultExact = false; if (SanityManager.DEBUG) { // System.out.println("searchForEntry() exit: params:" + params); } return; } protected void searchForEntryBackward(SearchParameters params) throws StandardException { if (SanityManager.DEBUG) { // System.out.println("searchForEntry() enter: params:" + params); // System.out.println("searchForEntry() enter: this:" + this); // System.out.println("searchForEntry() enter: this page:" + debugPage(params.btree)); } // leftrange and rightrange indicates the range of slots to search. // The range starts as all the slots on the page not including slot // 0 which is the control row. int leftrange = 1; int rightrange = page.recordCount() - 1; // leftslot and rightslot if non-zero, mean that the key has been // compared to the row at that slot. If non-zero the key must be // greater than the key at leftslot and the key must be lest than // the key at rightslot. int leftslot = 0; int rightslot = rightrange + 1; int midslot; int compare_ret; // search until you either exactly find the key, or you have // compared 2 adjacent rows and found the value must exist between // the 2. if (this.use_last_search_result_hint) { // make sure to set midslot to point to somwhere in the legal range. midslot = ((this.last_search_result == 0) ? 1 : this.last_search_result); if (midslot > rightrange) midslot = rightrange; } else { // if we don't think we have a good hint where to start the search // just go to the middle. midslot = (leftrange + rightrange) / 2; } if (SanityManager.DEBUG) { if ((leftslot != (rightslot - 1)) && !(midslot >= leftrange && midslot <= rightrange)) { SanityManager.THROWASSERT( "midslot = " + midslot + ";leftrange = " + leftrange + ";rightrange = " + rightrange); } } while (leftslot != (rightslot - 1)) { // Compare the index row to the key. compare_ret = CompareIndexRowFromPageToKey( this, midslot, params.template, params.searchKey, params.btree.getConglomerate().nUniqueColumns, params.partial_key_match_op, params.btree.getConglomerate().ascDescInfo); if (compare_ret == 0) { // Found exact match params.resultSlot = midslot; params.resultExact = true; // update the hints based on result of the search.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -