📄 hfpage-bing.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 + -