⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hfpage.c

📁 mini database hpfile implement
💻 C
字号:
#include <iostream.h>
#include <stdlib.h>
#include <memory.h>

#include "hfpage.h"
#include "heapfile.h"
#include "buf.h"
#include "db.h"


// **********************************************************
// page class constructor

void HFPage::init(PageId pageNo)
{
    curPage   = pageNo;   
    prevPage  = INVALID_PAGE;
    nextPage  = INVALID_PAGE;
    
    slotCnt   = 0;
    usedPtr   = MAX_SPACE - DPFIXED;
    freeSpace = MAX_SPACE - DPFIXED+sizeof(slot_t);

    slot[0].length = EMPTY_SLOT;
}

// **********************************************************
// dump page utlity
void HFPage::dumpPage()
{
    int i;

    cout << "dumpPage, this: " << this << endl;
    cout << "curPage = " << curPage << ", nextPage = " << nextPage << endl;
    cout << "usedPtr = " << usedPtr << ", freeSpace = " << freeSpace
         << ", slotCnt = " << slotCnt << endl;
   
    for (i=0; i < slotCnt; i++) {
        cout << "slot[" << i <<"].offset = " << slot[i].offset
             << ", slot[" << i << "].length = " << slot[i].length << endl;
    }
}

// **********************************************************
PageId HFPage::getPrevPage()
{
    return prevPage;
}

// **********************************************************
void HFPage::setPrevPage(PageId pageNo)
{
    prevPage = pageNo;
}

// **********************************************************
void HFPage::setNextPage(PageId pageNo)
{
    nextPage = pageNo;
}

// **********************************************************
PageId HFPage::getNextPage()
{
    return nextPage;
}

// **********************************************************
// Add a new record to the page. Returns OK if everything went OK
// otherwise, returns DONE if sufficient space does not exist
// RID of the new record is returned via rid parameter.
Status HFPage::insertRecord(char* recPtr, int recLen, RID& rid)
{
    /*if (recPtr == NULL)
    {
        return FAIL;
    }*/
    if(slotCnt==0) slotCnt++;
    if (freeSpace<recLen)
    {
        return DONE;
    }
    for(int i=0;i<slotCnt;i++)
    {
	   if(slot[i].length==EMPTY_SLOT)
	   {
		memcpy(&data[usedPtr-recLen], recPtr, recLen);
		freeSpace = freeSpace-recLen; 
		usedPtr -= recLen;
                slot[i].offset=usedPtr;
		slot[i].length=recLen;
		rid.pageNo = curPage;
    		rid.slotNo = i;
		return OK;
	   }
    }
    if(freeSpace>=recLen+sizeof(slot_t))
    {
		rid.pageNo = curPage;
    		rid.slotNo = slotCnt;
		slot[slotCnt].length = recLen;
		memcpy(&data[usedPtr-recLen], recPtr, recLen);
		usedPtr -= recLen;
		slot[slotCnt].offset = usedPtr;
		freeSpace = freeSpace-sizeof(slot_t)-recLen; 
		slotCnt++;    
    		return OK;
     }
     else return DONE;
}

// **********************************************************
// Delete a record from a page. Returns OK if everything went okay.
// Compacts remaining records but leaves a hole in the slot array.
// Use memmove() rather than memcpy() as space may overlap.
Status HFPage::deleteRecord(const RID& rid)
{
	if((rid.pageNo==curPage)&&(rid.slotNo<slotCnt&&rid.slotNo>=0)&&(slot[rid.slotNo].length!=EMPTY_SLOT))	
	{
	//compact:menmove(void *dst ,void const *src ,size_t len)
	memmove(&data[slot[rid.slotNo].offset+slot[rid.slotNo].length],&data[slot[rid.slotNo].offset],slot[rid.slotNo].length);
	//handle slot
	int i;
	for(i=0;i<slotCnt;i++)
	{
		if(slot[i].offset<slot[rid.slotNo].offset)
		slot[i].offset +=slot[rid.slotNo].length;
	}
	usedPtr += slot[rid.slotNo].length;
	freeSpace += slot[rid.slotNo].length; 
	slot[rid.slotNo].length=EMPTY_SLOT;
    	return OK;
	}	
	else
	return FAIL;
}

// **********************************************************
// returns RID of first record on page
Status HFPage::firstRecord(RID& firstRid)
{
  
	if(usedPtr != MAX_SPACE - DPFIXED)
	{
		int i;	
		for(i=0;i<slotCnt;i++)
		{
			if(slot[i].offset+slot[i].length==MAX_SPACE - DPFIXED)
			{
			firstRid.pageNo=curPage;
			firstRid.slotNo=i;
			return OK;
			}
		}
	}
    	return DONE;
}

// **********************************************************
// returns RID of next record on the page
// returns DONE if no more records exist on the page; otherwise OK
Status HFPage::nextRecord (RID curRid, RID& nextRid)
{
	if((curRid.pageNo==curPage)&&(curRid.slotNo<slotCnt&&curRid.slotNo>=0)&&(slot[curRid.slotNo].length!=EMPTY_SLOT))
	{
		if(slot[curRid.slotNo].offset==usedPtr)
    		{
		return DONE;
    		}
    		else{
			nextRid.pageNo=curPage;
			//find next record's slotNo
			int i;	
			for(i=0;i<slotCnt;i++)
			{
			if(slot[i].length!=EMPTY_SLOT&&((slot[i].offset+slot[i].length)==slot[curRid.slotNo].offset))
			{nextRid.slotNo=i;
			return OK;}
			}
        		return DONE;
    		}
	}else return FAIL;	
}

// **********************************************************
// returns length and copies out record with RID rid
Status HFPage::getRecord(RID rid, char* recPtr, int& recLen)
{
 
	if(rid.pageNo!=curPage) return FAIL;
    	else{
		for(int i =0;i<slot[rid.slotNo].length;i++)	
		{*recPtr=data[slot[rid.slotNo].offset+i];
		recPtr++;}
		recLen=slot[rid.slotNo].length;
    		return OK;
	}
}

// **********************************************************
// returns length and pointer to record with RID rid.  The difference
// between this and getRecord is that getRecord copies out the record
// into recPtr, while this function returns a pointer to the record
// in recPtr.
Status HFPage::returnRecord(RID rid, char*& recPtr, int& recLen)
{
 
	if(rid.pageNo!=curPage) return FAIL;
    		else{
		recPtr=&data[slot[rid.slotNo].offset];
		recLen=slot[rid.slotNo].length;
    		return OK;}
}

// **********************************************************
// Returns the amount of available space on the heap file page
int HFPage::available_space(void)
{
    int num;
	if(slotCnt==0) num=usedPtr;
    else num=usedPtr-sizeof(slot_t)*(slotCnt-1);
    return num;
}

// **********************************************************
// Returns 1 if the HFPage is empty, and 0 otherwise.
// It scans the slot directory looking for a non-empty slot.
bool HFPage::empty(void)
{
	int i;    
	if(slotCnt==0) return true;
	for (i=0; i < slotCnt; i++) {
         if(slot[i].length!=EMPTY_SLOT)
		return false;
    	}
    return true;
}



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -