Esempio n. 1
0
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);
}
Esempio n. 4
0
 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;
 }
Esempio n. 5
0
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);
	}
	
}