diff --git a/src/jrd/btn.cpp b/src/jrd/btn.cpp index cbd475eaa4..ec9f3f6ab4 100644 --- a/src/jrd/btn.cpp +++ b/src/jrd/btn.cpp @@ -90,7 +90,7 @@ SLONG findPageInDuplicates(const btree_page* page, UCHAR* pointer, // correct node is found. // If this is an end bucket marker then return // the previous passed page number. - if (BTreeNode::isEndBucket(&node, leafPage)) { + if (node.isEndBucket) { return previousNumber; } if (findRecordNumber < node.recordNumber) { @@ -111,7 +111,7 @@ SLONG findPageInDuplicates(const btree_page* page, UCHAR* pointer, pointer = BTreeNode::readNode(&node, pointer, flags, leafPage); // We're done if end level marker is reached or this // isn't a equal node anymore. - if (BTreeNode::isEndLevel(&node, leafPage) || + if ((node.isEndLevel) || (node.length != 0) || (node.prefix != (previousNode.length + previousNode.prefix))) { @@ -139,17 +139,26 @@ USHORT getJumpNodeSize(const IndexJumpNode* jumpNode, SCHAR flags) if (flags & btr_large_keys) { // Size needed for prefix USHORT number = jumpNode->prefix; - result++; - number >>= 7; - if (number > 0) { - result++; + if (number & 0xC000) { + result += 3; } + else if (number & 0xFF80) { + result += 2; + } + else { + result += 1; + } + // Size needed for length number = jumpNode->length; - result++; - number >>= 7; - if (number > 0) { - result++; + if (number & 0xC000) { + result += 3; + } + else if (number & 0xFF80) { + result += 2; + } + else { + result += 1; } } else { @@ -257,36 +266,26 @@ USHORT getNodeSize(const IndexNode* indexNode, SCHAR flags, bool leafNode) if (internalFlags != 3) { // Size needed for prefix number = indexNode->prefix; - UCHAR tmp = (number & 0x7F); - number >>= 7; - if (number > 0) { - tmp |= 0x80; + if (number & 0xFFFFC000) { + result += 3; } - result++; // 7 - if (tmp & 0x80) { - tmp = (number & 0x7F); - number >>= 7; - if (number > 0) { - tmp |= 0x80; - } - result++; // 14 + else if (number & 0xFFFFFF80) { + result += 2; + } + else { + result += 1; } // Size needed for length number = indexNode->length; - tmp = (number & 0x7F); - number >>= 7; - if (number > 0) { - tmp |= 0x80; + if (number & 0xFFFFC000) { + result += 3; } - result++; // 7 - if (tmp & 0x80) { - tmp = (number & 0x7F); - number >>= 7; - if (number > 0) { - tmp |= 0x80; - } - result++; // 14 + else if (number & 0xFFFFFF80) { + result += 2; + } + else { + result += 1; } } @@ -308,7 +307,6 @@ USHORT getNodeSize(const IndexNode* indexNode, SCHAR flags, bool leafNode) } } - return result; } @@ -346,50 +344,6 @@ UCHAR* getPointerFirstNode(btree_page* page, IndexJumpInfo* jumpInfo) } -bool isEndBucket(const IndexNode* indexNode, bool leafNode) -{ -/************************************** - * - * i s E n d B u c k e t - * - ************************************** - * - * Functional description - * Check if this is a END_BUCKET - * marker node. - * - **************************************/ - if (leafNode) { - return (indexNode->recordNumber == END_BUCKET); - } - else { - return (indexNode->pageNumber == END_BUCKET); - } -} - - -bool isEndLevel(const IndexNode* indexNode, bool leafNode) -{ -/************************************** - * - * i s E n d L e v e l - * - ************************************** - * - * Functional description - * Check if this is a END_LEVEL - * marker node. - * - **************************************/ - if (leafNode) { - return (indexNode->recordNumber == END_LEVEL); - } - else { - return (indexNode->pageNumber == END_LEVEL); - } -} - - bool keyEquality(USHORT length, const UCHAR* data, const IndexNode* indexNode) { /************************************** @@ -452,8 +406,8 @@ UCHAR* lastNode(btree_page* page, jrd_exp* expanded_page, BTX* expanded_node) IndexNode node; while (true) { pointer = previousNode(&node, pointer, flags, &enode); - if (!isEndBucket(&node, false) && - !isEndLevel(&node, false)) + if (!node.isEndBucket && + !node.isEndLevel) { if (expanded_node) { *expanded_node = enode; @@ -796,6 +750,9 @@ UCHAR* readNode(IndexNode* indexNode, UCHAR* pagePointer, SCHAR flags, bool leaf // Get pointer where data starts indexNode->data = pagePointer; pagePointer += indexNode->length; + + indexNode->isEndBucket = (internalFlags == BTN_END_BUCKET_FLAG); + indexNode->isEndLevel = (internalFlags == BTN_END_LEVEL_FLAG); } else { indexNode->prefix = (*pagePointer); @@ -804,9 +761,13 @@ UCHAR* readNode(IndexNode* indexNode, UCHAR* pagePointer, SCHAR flags, bool leaf pagePointer++; if (leafNode) { indexNode->recordNumber = get_long(pagePointer); + indexNode->isEndBucket = (indexNode->recordNumber == END_BUCKET); + indexNode->isEndLevel = (indexNode->recordNumber == END_LEVEL); } else { indexNode->pageNumber = get_long(pagePointer); + indexNode->isEndBucket = (indexNode->pageNumber == END_BUCKET); + indexNode->isEndLevel = (indexNode->pageNumber == END_LEVEL); } pagePointer += 4; @@ -1236,6 +1197,8 @@ void setEndBucket(IndexNode* indexNode, bool leafNode) * Functional description * **************************************/ + indexNode->isEndBucket = true; + indexNode->isEndLevel = false; if (leafNode) { indexNode->recordNumber = END_BUCKET; } @@ -1256,6 +1219,8 @@ void setEndLevel(IndexNode* indexNode, bool leafNode) * Functional description * **************************************/ + indexNode->isEndBucket = false; + indexNode->isEndLevel = true; indexNode->prefix = 0; indexNode->length = 0; if (leafNode) { diff --git a/src/jrd/btn.h b/src/jrd/btn.h index 1b2669bd6d..06064d40bb 100644 --- a/src/jrd/btn.h +++ b/src/jrd/btn.h @@ -79,9 +79,6 @@ namespace BTreeNode { USHORT getNodeSize(const IndexNode* indexNode, SCHAR flags, bool leafNode = true); UCHAR* getPointerFirstNode(btree_page* page, IndexJumpInfo* jumpInfo = NULL); - bool isEndBucket(const IndexNode* indexNode, bool leafNode = true); - bool isEndLevel(const IndexNode* indexNode, bool leafNode = true); - bool keyEquality(USHORT length, const UCHAR* data, const IndexNode* indexNode); #ifdef SCROLLABLE_CURSORS diff --git a/src/jrd/btr.cpp b/src/jrd/btr.cpp index f28ee44674..bb84d1cab5 100644 --- a/src/jrd/btr.cpp +++ b/src/jrd/btr.cpp @@ -459,11 +459,11 @@ void BTR_evaluate(TDBB tdbb, IRB retrieval, SBM * bitmap) pointer = BTreeNode::readNode(&node, pointer, flags, true); while (true) { - if (BTreeNode::isEndLevel(&node, true)) { + if (node.isEndLevel) { break; } - if (!BTreeNode::isEndBucket(&node, true)) { + if (!node.isEndBucket) { SBM_set(tdbb, bitmap, node.recordNumber); pointer = BTreeNode::readNode(&node, pointer, flags, true); continue; @@ -997,8 +997,7 @@ UCHAR *BTR_last_node(btree_page* page, jrd_exp* expanded_page, BTX * expanded_no IndexNode node; while (true) { pointer = BTR_previousNode(&node, pointer, flags, &enode); - if (node.recordNumber != END_BUCKET && - node.recordNumber != END_LEVEL) { + if (!node.isEndBucket && !node.isEndLevel) { if (expanded_node) { *expanded_node = enode; } @@ -1347,9 +1346,7 @@ void BTR_remove(TDBB tdbb, WIN * root_window, IIB * insertion) const SLONG number = pageNode.pageNumber; pointer = BTreeNode::readNode(&pageNode, pointer, flags, false); - if (!(BTreeNode::isEndBucket(&pageNode, false) || - BTreeNode::isEndLevel(&pageNode, false))) - { + if (!(pageNode.isEndBucket || pageNode.isEndLevel)) { CCH_RELEASE(tdbb, &window); CCH_RELEASE(tdbb, root_window); return; @@ -1558,9 +1555,7 @@ void BTR_selectivity(TDBB tdbb, jrd_rel* relation, USHORT id, SelectivityList& s while (page) { pointer = BTreeNode::readNode(&node, pointer, flags, true); while (true) { - if (BTreeNode::isEndBucket(&node, true) || - BTreeNode::isEndLevel(&node, true) ) - { + if (node.isEndBucket || node.isEndLevel) { break; } ++nodes; @@ -1654,7 +1649,7 @@ void BTR_selectivity(TDBB tdbb, jrd_rel* relation, USHORT id, SelectivityList& s pointer = BTreeNode::readNode(&node, pointer, flags, true); } - if (node.recordNumber == END_LEVEL || !(page = bucket->btr_sibling)) + if (node.isEndLevel || !(page = bucket->btr_sibling)) { break; } @@ -2387,17 +2382,13 @@ static CONTENTS delete_node(TDBB tdbb, WIN *window, UCHAR *pointer) //bool leafPage = (page->btr_level == 0); //SCHAR flags = page->btr_header.pag_flags; pointer = BTreeNode::readNode(&node, pointer, flags, leafPage); - if (BTreeNode::isEndBucket(&node, leafPage) || - BTreeNode::isEndLevel(&node, leafPage)) - { + if (node.isEndBucket || node.isEndLevel) { return contents_empty; } // check to see if there is just one node pointer = BTreeNode::readNode(&node, pointer, flags, leafPage); - if (BTreeNode::isEndBucket(&node, leafPage) || - BTreeNode::isEndLevel(&node, leafPage)) - { + if (node.isEndBucket || node.isEndLevel) { return contents_single; } @@ -3410,7 +3401,7 @@ static UCHAR *find_node_start_point(btree_page* bucket, KEY * key, UCHAR * value // prefix of the current node is less than the running prefix, the // node must have a value greater than the key, so it is the insertion // point. - if (BTreeNode::isEndLevel(&node, leafPage) || node.prefix < prefix) { + if (node.isEndLevel || node.prefix < prefix) { if (return_value) { *return_value = prefix; } @@ -3453,7 +3444,7 @@ static UCHAR *find_node_start_point(btree_page* bucket, KEY * key, UCHAR * value prefix = (USHORT)(p - key->key_data); } - if (BTreeNode::isEndBucket(&node, leafPage)) { + if (node.isEndBucket) { if (pointer_by_marker) { goto done1; } @@ -3675,8 +3666,8 @@ static UCHAR* find_area_start_point(btree_page* bucket, const KEY* key, UCHAR * if (node.length != 0 || node.prefix != prevJumpNode.prefix + prevJumpNode.length || jumpNode.prefix != prevJumpNode.prefix + prevJumpNode.length || - BTreeNode::isEndBucket(&node, leafPage) || - BTreeNode::isEndLevel(&node, leafPage)) + node.isEndBucket || + node.isEndLevel) { break; } @@ -3734,8 +3725,8 @@ static UCHAR* find_area_start_point(btree_page* bucket, const KEY* key, UCHAR * if (node.length != 0 || node.prefix != prevJumpNode.prefix + prevJumpNode.length || jumpNode.prefix != prevJumpNode.prefix + prevJumpNode.length || - BTreeNode::isEndBucket(&node, leafPage) || - BTreeNode::isEndLevel(&node, leafPage)) + node.isEndBucket || + node.isEndLevel) { break; } @@ -3830,14 +3821,12 @@ static SLONG find_page(btree_page* bucket, const KEY* key, UCHAR idx_flags, SLON IndexNode node; pointer = BTreeNode::readNode(&node, pointer, flags, leafPage); - if (BTreeNode::isEndBucket(&node, leafPage) || - BTreeNode::isEndLevel(&node, leafPage)) - { + if (node.isEndBucket || node.isEndLevel) { pointer = BTreeNode::getPointerFirstNode(bucket); pointer = BTreeNode::readNode(&node, pointer, flags, leafPage); } - if (BTreeNode::isEndLevel(&node, leafPage)) { + if (node.isEndLevel) { BUGCHECK(206); // msg 206 exceeded index level } @@ -3862,7 +3851,7 @@ static SLONG find_page(btree_page* bucket, const KEY* key, UCHAR idx_flags, SLON // prefix of the current node is less than the running prefix, its // node must have a value greater than the key, which is the fb_insertion // point. - if (BTreeNode::isEndLevel(&node, leafPage) || node.prefix < prefix) { + if (node.isEndLevel || node.prefix < prefix) { return previousNumber; } @@ -3926,7 +3915,7 @@ static SLONG find_page(btree_page* bucket, const KEY* key, UCHAR idx_flags, SLON // If this is the end of bucket, return node. Somebody else can // deal with this - if (BTreeNode::isEndBucket(&node, leafPage)) { + if (node.isEndBucket) { return node.pageNumber; } @@ -4214,7 +4203,7 @@ static CONTENTS garbage_collect(TDBB tdbb, WIN * window, SLONG parent_number) IndexNode parentNode; while (true) { parentPointer = BTreeNode::readNode(&parentNode, parentPointer, flags, false); - if (BTreeNode::isEndBucket(&parentNode, false)) { + if (parentNode.isEndBucket) { parent_page = (btree_page*) CCH_HANDOFF(tdbb, &parent_window, parent_page->btr_sibling, LCK_write, pag_index); parentPointer = BTreeNode::getPointerFirstNode(parent_page); @@ -4222,7 +4211,7 @@ static CONTENTS garbage_collect(TDBB tdbb, WIN * window, SLONG parent_number) } if (parentNode.pageNumber == window->win_page || - BTreeNode::isEndLevel(&parentNode, false)) + parentNode.isEndLevel) { break; } @@ -4230,7 +4219,7 @@ static CONTENTS garbage_collect(TDBB tdbb, WIN * window, SLONG parent_number) } // we should always find the node, but just in case we don't, bow out gracefully - if (BTreeNode::isEndLevel(&parentNode, false)) { + if (parentNode.isEndLevel) { CCH_RELEASE(tdbb, &left_window); if (right_page) { CCH_RELEASE(tdbb, &right_window); @@ -4296,9 +4285,7 @@ static CONTENTS garbage_collect(TDBB tdbb, WIN * window, SLONG parent_number) BTreeNode::readNode(&leftNode, (UCHAR*)left_page + jumpNode.offset, flags, leafPage); - if (!(BTreeNode::isEndBucket(&leftNode, leafPage) || - BTreeNode::isEndLevel(&leftNode, leafPage))) - { + if (!(leftNode.isEndBucket || leftNode.isEndLevel)) { if (jumpNode.length) { memcpy(lastKey.key_data + jumpNode.prefix, jumpNode.data, jumpNode.length); @@ -4315,9 +4302,7 @@ static CONTENTS garbage_collect(TDBB tdbb, WIN * window, SLONG parent_number) while (true) { leftPointer = BTreeNode::readNode(&leftNode, leftPointer, flags, leafPage); // If it isn't a recordnumber were done - if (BTreeNode::isEndBucket(&leftNode, leafPage) || - BTreeNode::isEndLevel(&leftNode, leafPage)) - { + if (leftNode.isEndBucket || leftNode.isEndLevel) { break; } // Save data @@ -4614,17 +4599,13 @@ static CONTENTS garbage_collect(TDBB tdbb, WIN * window, SLONG parent_number) parentPointer = BTreeNode::getPointerFirstNode(parent_page); IndexNode parentNode; parentPointer = BTreeNode::readNode(&parentNode, parentPointer, flags, false); - if (BTreeNode::isEndBucket(&parentNode, false) || - BTreeNode::isEndLevel(&parentNode, false)) - { + if (parentNode.isEndBucket || parentNode.isEndLevel) { return contents_empty; } // check whether there is just one node parentPointer = BTreeNode::readNode(&parentNode, parentPointer, flags, false); - if (BTreeNode::isEndBucket(&parentNode, false) || - BTreeNode::isEndLevel(&parentNode, false)) - { + if (parentNode.isEndBucket || parentNode.isEndLevel) { return contents_single; } @@ -4693,9 +4674,7 @@ static void generate_jump_nodes(TDBB tdbb, btree_page* page, jumpNodeList* jumpN IndexNode node; while (pointer < endpoint) { pointer = BTreeNode::readNode(&node, pointer, flags, leafPage); - if (BTreeNode::isEndBucket(&node, leafPage) || - BTreeNode::isEndLevel(&node, leafPage)) - { + if (node.isEndBucket || node.isEndLevel) { break; } if (node.length) { @@ -4883,7 +4862,7 @@ static SLONG insert_node(TDBB tdbb, } else { // We have a equal node, so find the correct insertion point. - if (BTreeNode::isEndBucket(&beforeInsertNode, leafPage)) { + if (beforeInsertNode.isEndBucket) { if (allRecordNumber) { break; } @@ -4891,7 +4870,7 @@ static SLONG insert_node(TDBB tdbb, return NO_VALUE; } } - if (BTreeNode::isEndLevel(&beforeInsertNode, leafPage)) { + if (beforeInsertNode.isEndLevel) { break; } if (leafPage && unique) { @@ -4983,8 +4962,7 @@ static SLONG insert_node(TDBB tdbb, newBucket->btr_length += delta; // figure out whether this node was inserted at the end of the page - bool endOfPage = BTreeNode::isEndBucket(&beforeInsertNode, leafPage) || - BTreeNode::isEndLevel(&beforeInsertNode, leafPage); + bool endOfPage = (beforeInsertNode.isEndBucket || beforeInsertNode.isEndLevel); // Initialize variables needed for generating jump information bool useJumpInfo = (flags & btr_jump_info); @@ -5623,7 +5601,7 @@ static CONTENTS remove_leaf_node(TDBB tdbb, IIB * insertion, WIN * window) break; } - if (BTreeNode::isEndLevel(&node, true)) { + if (node.isEndLevel) { #ifdef DEBUG_BTR CCH_RELEASE(tdbb, window); CORRUPT(204); // msg 204 index inconsistent @@ -5632,7 +5610,7 @@ static CONTENTS remove_leaf_node(TDBB tdbb, IIB * insertion, WIN * window) } // go to the next node and check that it is a duplicate - if (!BTreeNode::isEndBucket(&node, true)) { + if (!node.isEndBucket) { pointer = BTreeNode::readNode(&node, pointer, flags, true); if (node.length != 0 || node.prefix != key->key_length) { @@ -5749,7 +5727,7 @@ static bool scan(TDBB tdbb, UCHAR *pointer, SBM *bitmap, USHORT to_segment, pointer = BTreeNode::readNode(&node, pointer, page_flags, true); while (true) { - if (BTreeNode::isEndLevel(&node, true)) { + if (node.isEndLevel) { return false; } @@ -5811,7 +5789,7 @@ static bool scan(TDBB tdbb, UCHAR *pointer, SBM *bitmap, USHORT to_segment, } } - if (BTreeNode::isEndBucket(&node, true)) { + if (node.isEndBucket) { // Our caller will fetch the next page return true; } diff --git a/src/jrd/nav.cpp b/src/jrd/nav.cpp index 63c69e074a..1f96a59056 100644 --- a/src/jrd/nav.cpp +++ b/src/jrd/nav.cpp @@ -623,11 +623,11 @@ bool NAV_get_record(TDBB tdbb, // it, do a simple handoff to the right sibling page. #endif { - if (number == END_LEVEL) { + if (node.isEndLevel) { impure->irsb_flags |= irsb_eof; break; } - if (number == END_BUCKET) { + if (node.isEndBucket) { page = (btree_page*) window.win_buffer; page = (btree_page*) CCH_HANDOFF(tdbb, &window, page->btr_sibling, LCK_read, pag_index); @@ -1409,11 +1409,11 @@ static bool find_saved_node(Rsb* rsb, IRSB_NAV impure, pointer = BTreeNode::readNode(&node, pointer, flags, true); - if (node.recordNumber == END_LEVEL) { + if (node.isEndLevel) { *return_pointer = node.nodePointer; return false; } - if (node.recordNumber == END_BUCKET) { + if (node.isEndBucket) { page = (btree_page*) CCH_HANDOFF(tdbb, window, page->btr_sibling, LCK_read, pag_index); break; diff --git a/src/jrd/ods.h b/src/jrd/ods.h index 591167d525..e73688ae71 100644 --- a/src/jrd/ods.h +++ b/src/jrd/ods.h @@ -216,6 +216,8 @@ struct IndexNode SLONG pageNumber; // page number UCHAR* data; // Data can be read from here SLONG recordNumber; // record number + bool isEndBucket; + bool isEndLevel; }; struct IndexJumpNode diff --git a/src/jrd/val.cpp b/src/jrd/val.cpp index eb4564a8a8..ca987a8d6c 100644 --- a/src/jrd/val.cpp +++ b/src/jrd/val.cpp @@ -1495,7 +1495,7 @@ static RTN walk_index(TDBB tdbb, } if (useAllRecordNumbers && (node.recordNumber >= 0) && - !firstNode && !BTreeNode::isEndLevel(&node, leafPage)) + !firstNode && !node.isEndLevel) { // If this node is equal to the previous one and it's // not a MARKER, record number should be same or higher. @@ -1522,9 +1522,7 @@ static RTN walk_index(TDBB tdbb, } key.key_length = p - key.key_data; - if (BTreeNode::isEndBucket(&node, leafPage) || - BTreeNode::isEndLevel(&node, leafPage)) - { + if (node.isEndBucket || node.isEndLevel) { break; } @@ -1569,8 +1567,7 @@ static RTN walk_index(TDBB tdbb, // Only check record-number if this isn't the first page in // the level and it isn't a MARKER. if (useAllRecordNumbers && down_page->btr_left_sibling && - !(BTreeNode::isEndBucket(&downNode, downLeafPage) || - BTreeNode::isEndLevel(&downNode, downLeafPage))) + !(downNode.isEndBucket || downNode.isEndLevel)) { // Check record number if key is equal with node on // pointer page. In that case record number on page @@ -1592,17 +1589,14 @@ static RTN walk_index(TDBB tdbb, BTreeNode::readNode(&downNode, pointer, flags, leafPage); next_number = downNode.pageNumber; - if (!(BTreeNode::isEndBucket(&downNode, leafPage) || - BTreeNode::isEndLevel(&downNode, leafPage)) && + if (!(downNode.isEndBucket || downNode.isEndLevel) && (next_number != down_page->btr_sibling)) { corrupt(tdbb, control, VAL_INDEX_PAGE_CORRUPT, relation, id + 1, next); } - if (BTreeNode::isEndLevel(&downNode, leafPage) && - down_page->btr_sibling) - { + if (downNode.isEndLevel && down_page->btr_sibling) { corrupt(tdbb, control, VAL_INDEX_ORPHAN_CHILD, relation, id + 1, next); } diff --git a/src/utilities/gstat/dba.epp b/src/utilities/gstat/dba.epp index ca1eb97781..5bd281cbee 100644 --- a/src/utilities/gstat/dba.epp +++ b/src/utilities/gstat/dba.epp @@ -1180,9 +1180,7 @@ static void analyze_index( dba_rel* relation, dba_idx* index) pointer = BTreeNode::readNode(&node, pointer, bucket->btr_header.pag_flags, true); - if (BTreeNode::isEndBucket(&node, true) || - BTreeNode::isEndLevel(&node, true)) - { + if (node.isEndBucket || node.isEndLevel) { break; } @@ -1235,7 +1233,7 @@ static void analyze_index( dba_rel* relation, dba_idx* index) } ++index->idx_fill_distribution[n]; - if (BTreeNode::isEndLevel(&node, true)) { + if (node.isEndLevel) { break; } number = page;