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

📄 hfpage-bing.cpp

📁 mini database hpfile implement
💻 CPP
字号:
#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)
{
    // fill in the body
    curPage   = pageNo;
    
    prevPage  = INVALID_PAGE;
    nextPage  = INVALID_PAGE;
    
    slotCnt   = 0;
    usedPtr   = EMPTY_SLOT;
    freeSpace = MAX_SPACE - DPFIXED;
    
    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()
{
    // fill in the body
    return prevPage;
}

// **********************************************************
void HFPage::setPrevPage(PageId pageNo)
{
    // fill in the body
    prevPage = pageNo < INVALID_PAGE ? INVALID_PAGE : pageNo;
}

// **********************************************************
void HFPage::setNextPage(PageId pageNo)
{
    // fill in the body
    nextPage = pageNo < INVALID_PAGE ? INVALID_PAGE : pageNo;
}

// **********************************************************
PageId HFPage::getNextPage()
{
    // fill in the body
    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)
{
    // fill in the body
    if (recPtr == NULL)
    {
        return FAIL;
    }
    
    if (available_space() < recLen)
    {
        return DONE;
    }
    
    rid.pageNo = curPage;
    rid.slotNo = slotCnt;
    
    usedPtr -= recLen;
    slot[slotCnt].offset = usedPtr;
    slot[slotCnt].length = recLen;
    
    freeSpace = usedPtr - sizeof(slot_t) * slotCnt;    
    memcpy(&data[slot[slotCnt].offset], recPtr, recLen);
    
    slotCnt++;
    
    return OK;
}

// **********************************************************
// 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)
{
	// compact: memmove(void *dst, void const *src, size_t len)
	// memmove(slot[rid.slotNo].offset + slot[rid.slotNo].length, slot[rid.slotNo].offset, slot[rid.slotNo].offset - usedPtr);
	// 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;
        }
	}
	
	slot[rid.slotNo].length = EMPTY_SLOT;
    return OK;
    */
    if (rid.pageNo != curPage || 
        rid.slotNo >= slotCnt || 
        rid.slotNo < 0)
    {
        return FAIL;
    }

    if (slot[rid.slotNo].offset != usedPtr)
    {
        int copyLen = slot[rid.slotNo].offset - usedPtr;
        memmove(&data[slot[rid.slotNo].length + usedPtr],
                &data[usedPtr],
                copyLen);

        for (int 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;
}

// **********************************************************
// returns RID of first record on page
Status HFPage::firstRecord(RID& firstRid)
{
    int i;	
	for (i = 0; i < slotCnt; i++)
	{
		if (slot[i].offset + slot[i].length + DPFIXED == MAX_SPACE)
		{
            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)
    {
        return FAIL;
    }
    
    if (slot[curRid.slotNo].offset == usedPtr ||
        slot[curRid.slotNo].length == EMPTY_SLOT) 
    {
        return DONE;
    } 
    else 
    {
        nextRid.pageNo = curPage;
        // find next record's slotNo
        int i;	
        for (i = 0; i < slotCnt; i++)
        {
            if (slot[i].offset + slot[i].length == slot[curRid.slotNo].offset)
            {
                nextRid.slotNo = i;
                break;
            }
        }
        return OK;
    }
}

// **********************************************************
// returns length and copies out record with RID rid
Status HFPage::getRecord(RID rid, char* recPtr, int& recLen)
{
    if (rid.pageNo != curPage || // not current page
        rid.slotNo >= slotCnt || // upperbound
        rid.slotNo < 0 ||        // lowerbound
        recPtr == NULL ||        // null pointer
		slot[rid.slotNo].length == EMPTY_SLOT) // slot is empty
    {
        return FAIL;
    } 
    else 
    {
        // recPtr = &data[slot[rid.slotNo].offset];
        recLen = slot[rid.slotNo].length;
        memcpy(recPtr, &data[slot[rid.slotNo].offset], recLen);
        
        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 || 
        rid.slotNo >= slotCnt || 
        rid.slotNo < 0 ||
		slot[rid.slotNo].length == EMPTY_SLOT)
    {
        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;
    // num = usedPtr - DPFIXED + sizeof(slot_t) * slotCnt;
    num = usedPtr - sizeof(slot_t) * slotCnt;
    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;    
	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 + -