void *FindInTree( Node t, void *key ) { if ( t == (Node)0 ) return NULL; switch( KeyCmp( key, ItemKey(t->item) ) ) { case -1 : return FindInTree( t->left, key ); case 0: return t->item; case +1 : return FindInTree( t->right, key ); } }
t_rc INXM_IndexHandle::InsertIntoLeaf(STORM_PageHandle leafPageHandle, void *key, const REM_RecordID &rid) { t_rc rc; /* Find correct point for the new key. */ INXM_InitPageHeader initPageHeader; LoadInitHeaders(leafPageHandle, initPageHeader); INXM_Node node; int insertPoint = 0; rc = ReadNode(leafPageHandle, insertPoint, node); if (rc != OK) { return rc; } while (insertPoint < initPageHeader.nItems && KeyCmp(node.key, key) < 0) { insertPoint++; rc = ReadNode(leafPageHandle, insertPoint, node); if (rc != OK) { return rc; } } /* Open needed space at correct point. */ int point = INXM_INITPAGEHEADER_SIZE + INXM_NODEPAGEHEADER_SIZE + insertPoint*(INXM_NODE_SIZE+this->inxmFileHeader.attrLength); char *leafData; rc = leafPageHandle.GetDataPtr(&leafData); if (rc != OK) { return rc; } memcpy(&leafData[point + INXM_NODE_SIZE+this->inxmFileHeader.attrLength], &leafData[point], (initPageHeader.nItems-insertPoint)*(INXM_NODE_SIZE+this->inxmFileHeader.attrLength)); /* Write new data. */ int slot; STORM_PageHandle lastDataPageHandle; rc = this->sfh.GetPage(this->inxmFileHeader.lastDataPage, lastDataPageHandle); if (rc != OK) { return rc; } rc = WriteData(lastDataPageHandle, rid, slot); if (rc != OK) { return rc; } /* Write new node. */ rc = WriteNode(leafPageHandle, insertPoint, key, this->inxmFileHeader.lastDataPage, slot); if (rc != OK) { return rc; } return(OK); }
t_rc INXM_IndexHandle::FindLeaf(int rootPageID, void *key, STORM_PageHandle &leafPageHandle) { t_rc rc; int nodeRunner = rootPageID; INXM_Node node; INXM_InitPageHeader initPageHeader; INXM_NodePageHeader nodePageHeader; LoadNodeHeaders(nodeRunner, initPageHeader, nodePageHeader); while (!nodePageHeader.isLeaf) { int keyRunner = 0; while (keyRunner < initPageHeader.nItems) { rc = ReadNode(nodeRunner, keyRunner, node); if (rc != OK) { return rc; } if (KeyCmp(key,node.key) > 0) { keyRunner++; } else { break; } } nodeRunner = node.left; if (keyRunner == initPageHeader.nItems) { nodeRunner = nodePageHeader.next; } rc = LoadNodeHeaders(nodeRunner, initPageHeader, nodePageHeader); if (rc != OK) { return rc; } } rc = this->sfh.GetPage(nodeRunner, leafPageHandle); if (rc != OK) { return rc; } return(OK); }
const_iterator findKey(const KEY& key) const { // binary search for key const_iterator it(std::lower_bound(m_contents.begin(), m_contents.end(), key, KeyCmp())); if (it != m_contents.end() && CMP()(key, it->first)) // it > it-1, check == it = m_contents.end(); return it; }
RHTable::ELEMENT* RHTable::Find(unsigned char* key, unsigned int size, unsigned int hashValue, bool bInsert ) { BUCKET *pSaveBucket = NULL; ELEMENT *pFrontE = NULL; ELEMENT *pFindE = NULL; unsigned char hashKey[256]; unsigned int hashSize; if ( !m_bRemote ) HashFunction( hashKey, hashSize, key, size ); unsigned int idx = 0; HASH_TABLE *pHashTable = m_pHashTable; do { idx = hashValue&pHashTable->sizemask; if (NULL == pSaveBucket) pSaveBucket = &pHashTable->buckets[idx]; pFindE = pHashTable->buckets[idx].head; while ( NULL != pFindE ) { if ( pFindE->isDel || hashValue != pFindE->hashValue || !KeyCmp( pFindE->key, pFindE->keySize, key, size ) ) { pFrontE = pFindE; pFindE = pFindE->next; continue; } break; } if ( NULL != pFindE ) break;//找到对象 pHashTable = pHashTable->next;//旧表中查询 } while (NULL != pHashTable); if ( NULL == pFindE ) //没有找到 { if ( !bInsert ) return NULL; ELEMENT *pNew = pSaveBucket->head; while ( NULL != pNew ) { if ( pNew->isDel ) break; pNew = pNew->next; } bool bNew = false; if ( NULL == pNew ) { pNew = new ELEMENT; if ( NULL == pNew ) return NULL; pNew->next = pSaveBucket->head; bNew = true; } pNew->value = NULL; pNew->key = new unsigned char[size]; if ( NULL == pNew->key ) { delete pNew; return NULL; } pNew->hashValue = hashValue; memcpy( pNew->key, key, size ); pNew->keySize = size; pNew->isDel = false; if ( bNew ) pSaveBucket->head = pNew; return pNew; } if ( pSaveBucket == &pHashTable->buckets[idx] ) return pFindE; //数据迁移 if ( pHashTable->buckets[idx].head == pFindE ) pHashTable->buckets[idx].head = pFindE->next; else pFrontE->next = pFindE->next; pFindE->next = pSaveBucket->head; pSaveBucket->head = pFindE; pHashTable->count--; m_pHashTable->count++; if ( 0 == pHashTable->count ) ReleaseOldHashTable(); return pFindE; }
t_rc INXM_IndexHandle::InsertIntoLeafAfterSplitting(int rootID, STORM_PageHandle leafPageHandle, void *key, const REM_RecordID &rid) { t_rc rc; STORM_PageHandle newLeafPageHandle; int newLeafPageID; rc = CreateNodePage(newLeafPageHandle, newLeafPageID, 0, 0, 0, true); if (rc != OK) { return rc; } /* Read leaf page headers. */ INXM_InitPageHeader leafPageHeader; rc = LoadInitHeaders(leafPageHandle, leafPageHeader); if (rc != OK) { return rc; } int insertPoint = 0; INXM_Node node; ReadNode(leafPageHandle, insertPoint, node); while (insertPoint < leafPageHeader.nItems && KeyCmp(node.key, key) < 0) { ReadNode(leafPageHandle, insertPoint, node); insertPoint++; } INXM_Node **temp_nodes = (INXM_Node **)malloc(INXM_NODE_SIZE*leafPageHeader.nItems); int i,j; for (i=0, j=0; i < leafPageHeader.nItems; i++, j++) { if (j == insertPoint) j++; ReadNode(leafPageHandle, i, *(temp_nodes[j])); } /* Write new data to last page. */ int newDataSlot; STORM_PageHandle lastDataPageHandle; rc = this->sfh.GetPage(this->inxmFileHeader.lastDataPage, lastDataPageHandle); if (rc != OK) { return rc; } rc = WriteData(lastDataPageHandle, rid, newDataSlot); if (rc != OK) { return rc; } /* Place new node to temp array. */ INXM_Node *newNode = new INXM_Node(); newNode->key = key; newNode->left = this->inxmFileHeader.lastDataPage; newNode->slot = newDataSlot; temp_nodes[insertPoint] = newNode; /* Reset leaf's nItems */ char *tmpData; leafPageHandle.GetDataPtr(&tmpData); leafPageHeader.nItems = 0; memcpy(tmpData, &leafPageHeader, INXM_INITPAGEHEADER_SIZE); int maxNodeRoom = (PAGE_DATA_SIZE-INXM_INITPAGEHEADER_SIZE-INXM_NODEPAGEHEADER_SIZE)/(INXM_NODE_SIZE+this->inxmFileHeader.attrLength); int split = Cut(maxNodeRoom); /* Write new data. */ for (i = 0; i < split; i++) { WriteNode(leafPageHandle, i, temp_nodes[i]->key, temp_nodes[i]->left, temp_nodes[i]->slot); } for (i = split, j = 0; i < maxNodeRoom; i++, j++) { WriteNode(newLeafPageHandle, j, temp_nodes[i]->key, temp_nodes[i]->left, temp_nodes[i]->slot); } free(temp_nodes); // This is not enough! INXM_NodePageHeader leafNodePageHeader; LoadNodeHeaders(leafPageHandle, leafPageHeader, leafNodePageHeader); INXM_NodePageHeader newLeafNodePageHeader; INXM_InitPageHeader newLeafPageHeader; rc = LoadNodeHeaders(newLeafPageHandle, newLeafPageHeader, newLeafNodePageHeader); if (rc != OK) { return rc; } int leafPageID; rc = leafPageHandle.GetPageID(leafPageID); if (rc != OK) { return rc; } newLeafNodePageHeader.next = leafNodePageHeader.next; newLeafNodePageHeader.previous = leafPageID; leafNodePageHeader.next = newLeafPageID; if (newLeafNodePageHeader.next != 0) { STORM_PageHandle nextLeafPageHandle; rc = this->sfh.GetPage(newLeafNodePageHeader.next, nextLeafPageHandle); if (rc != OK) { return rc; } INXM_InitPageHeader nextInitPageHeader; INXM_NodePageHeader nextNodePageHeader; LoadNodeHeaders(nextLeafPageHandle, nextInitPageHeader, nextNodePageHeader); nextNodePageHeader.previous = newLeafPageID; UpdateNodeHeaders(nextLeafPageHandle, nextInitPageHeader, nextNodePageHeader); } rc = UpdateNodeHeaders(leafPageHandle, leafPageHeader, leafNodePageHeader); if (rc != OK) { return rc; } rc = UpdateNodeHeaders(newLeafPageHandle, newLeafPageHeader, newLeafNodePageHeader); if (rc != OK) { return rc; } INXM_Node keyNode; rc = ReadNode(newLeafPageHandle, 0, keyNode); if (rc != OK) { return rc; } rc = InsertIntoParent(this->inxmFileHeader.treeRoot, leafPageHandle, keyNode, newLeafPageHandle); if (rc != OK) { return rc; } return(OK); }
t_rc INXM_IndexHandle::FindAndAppend(int rootPageID, void *key, const REM_RecordID &rid) { t_rc rc; STORM_PageHandle leafPageHandle; rc = FindLeaf(rootPageID, key, leafPageHandle); if (rc != OK) { return rc; } INXM_InitPageHeader initPageHeader; rc = LoadInitHeaders(leafPageHandle, initPageHeader); if (rc != OK) { return rc; } INXM_Node node; int i; for (i=0; i < initPageHeader.nItems; i++) { rc = ReadNode(leafPageHandle, i, node); if (rc != OK) { return rc; } if (KeyCmp(key, node.key) == 0) { break; } } if (i == initPageHeader.nItems) { return(INXM_KEY_NOT_FOUND); } else { int slotOfNewData; STORM_PageHandle lastDataPageHandle; rc = this->sfh.GetPage(this->inxmFileHeader.lastDataPage, lastDataPageHandle); if (rc != OK) { return rc; } /* Check if last data page has room. */ INXM_InitPageHeader initPageHeader; rc = LoadInitHeaders(lastDataPageHandle, initPageHeader); if (rc != OK) { return rc; } int room = PAGE_DATA_SIZE-(INXM_INITPAGEHEADER_SIZE+(initPageHeader.nItems+1)*INXM_DATA_SIZE); /* If no room. Reserve new last data page. */ if (room < 0 ) { CreateLastDataPage(lastDataPageHandle); /* Write last data. */ WriteData(lastDataPageHandle, rid, slotOfNewData); } else if (room == 0) { /* Write last data. */ WriteData(lastDataPageHandle, rid, slotOfNewData); CreateLastDataPage(lastDataPageHandle); } else { /* Write last data. */ WriteData(lastDataPageHandle, rid, slotOfNewData); } /* Update last-1 link data. */ STORM_PageHandle listDataPageHandle; this->sfh.GetPage(node.left, listDataPageHandle); INXM_Data data; ReadData(listDataPageHandle, node.slot, data); int fromWhere = node.slot; while (data.nextPageID != 0) { this->sfh.GetPage(data.nextPageID, listDataPageHandle); fromWhere = data.nextSlot; ReadData(listDataPageHandle, data.nextSlot, data); } data.nextPageID=this->inxmFileHeader.lastDataPage; data.nextSlot=slotOfNewData; /* Write updated last-1 data of list. */ EditData(listDataPageHandle, fromWhere, data); return(OK); } }