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

📄 heapfile.c

📁 linux 下用c++ 开发的一个小型数据库系统
💻 C
字号:
#include "heapfile.h"#include "error.h"// routine to create a heapfileconst Status createHeapFile(const string fileName){    File* 		file;    Status 		status;    FileHdrPage*	hdrPage;    int			hdrPageNo;    int			newPageNo;    Page*		newPage;    int 		i;    db.createFile(fileName) ;    db.openFile( fileName, file) ;    if ((status = bufMgr->allocPage( file, hdrPageNo, newPage)) != OK)       return status ;    hdrPage = (FileHdrPage *)newPage ;    for (i = 0; i < MAXNAMESIZE; i++)      hdrPage->fileName[i] = fileName[i] ;    hdrPage->recCnt = 0 ;    hdrPage->pageCnt = 0 ;    for (i = 0; i < DIRCNT; i++){      hdrPage->pages[i].pageNo = -1 ;      hdrPage->pages[i].freeSpace = -1 ;    }    if ((status = bufMgr->allocPage( file, newPageNo, newPage)) != OK)      return status ;    newPage->init(newPageNo) ;    hdrPage->pages[0].pageNo = newPageNo ;    hdrPage->pages[0].freeSpace = newPage->getFreeSpace() ;    hdrPage->pageCnt = 0 ;        if((status =  bufMgr->unPinPage( file, hdrPageNo, true, true)) != OK)      return status ;    if((status =  bufMgr->unPinPage( file, newPageNo, true, true)) != OK)      return status ;//    if ((status = bufMgr->flushFile(file)) != OK) return status ;    if ((status = db.closeFile(file)) != OK) return status ;      return OK ;}// routine to destroy a heapfileconst Status destroyHeapFile(const string fileName){	return (db.destroyFile (fileName));}// constructor opens the underlying fileHeapFile::HeapFile(const string & fileName, Status& returnStatus){    Status 	status;    Page*	pagePtr;    if((status = db.openFile( fileName, filePtr)) == OK){      if((status = filePtr->getFirstPage(headerPageNo)) == OK){        if ((status = bufMgr->readPage( filePtr, headerPageNo, pagePtr)) == OK){           headerPage = (FileHdrPage *)pagePtr ;           hdrDirtyFlag = false ;           if ((status = bufMgr->readPage( filePtr, headerPage->pages[0].pageNo, curPage)) == OK){             curPageNo = headerPage->pages[0].pageNo ;             curIdx = 0 ;             curDirtyFlag = false ;             curRec = NULLRID ;           }        }     }   }   returnStatus = status ;}// the destructor closes the fileHeapFile::~HeapFile(){    Status status;    //cout << "invoking heapfile destructor on file " << headerPage->fileName << endl;  status = bufMgr->unPinPage( filePtr, headerPageNo, hdrDirtyFlag, true) ;  status = bufMgr->unPinPage( filePtr, curPageNo, curDirtyFlag, true) ;  status = bufMgr->flushFile(filePtr) ;  status = db.closeFile(filePtr) ;   }// Return number of records in heap fileconst int HeapFile::getRecCnt() const{  return headerPage->recCnt;}// retrieve an arbitrary record from a file.// if record is not on the currently pinned page, the current page// is unpinned and the required page is read into the buffer pool// and pinned.  returns a pointer to the record via the rec parameterconst Status HeapFile::getRecord(const RID &  rid, Record & rec){    Status status;    // cout<< "getRecord. record (" << rid.pageNo << "." << rid.slotNo << ")" << endl;    if (rid.pageNo == curPageNo){      if ((status = curPage->getRecord( rid, rec)) != OK) return status ;      curRec = rid ;      return OK ;    }    if ((status = bufMgr->unPinPage( filePtr, curPageNo, curDirtyFlag, true)) != OK) return status ;    if ((status = bufMgr->readPage( filePtr, rid.pageNo, curPage)) != OK){      curPage = NULL ;      curRec = NULLRID ;      curDirtyFlag = false ;      curIdx = -1 ;      return status ;    }      curPageNo = rid.pageNo ;    for (int i = 0; i <= headerPage->pageCnt; i++){      if (headerPage->pages[i].pageNo == rid.pageNo){        curIdx = i ;        break ;      }    }    curDirtyFlag = false ;    curRec = NULLRID ;    if ((status == curPage->getRecord( rid, rec)) != OK) return status ;    curRec = rid ;    return OK ;}HeapFileScan::HeapFileScan(const string & name,			   Status & status) : HeapFile(name, status){    filter = NULL;}const Status HeapFileScan::startScan(const int offset_,				     const int length_,				     const Datatype type_, 				     const char* filter_,				     const Operator op_){    Status status;    // start by making sure the first page of the file is in the buffer pool    // if not, unpin the currently pinned page and then read the     // first page of the file into the buffer pool    // your code to do the above goes here    if ((curPageNo != headerPage->pages[0].pageNo)){      if (curPage != NULL)        if ((status = bufMgr->unPinPage( filePtr, curPageNo, curDirtyFlag, true)) != OK) return status ;      if ((status = bufMgr->readPage( filePtr, headerPage->pages[0].pageNo, curPage)) != OK){        curPage = NULL ;        curPageNo = -1 ;        curIdx = -1 ;        curRec = NULLRID ;        curDirtyFlag = false ;        return status ;      }      curPageNo = headerPage->pages[0].pageNo ;      curIdx = 0 ;      curDirtyFlag = false ;      curRec = NULLRID ;    }    curRec = NULLRID ;    // then check the rest of the paramters    if (!filter_) {                        // no filtering requested        filter = NULL;        return OK;    }       if ((offset_ < 0 || length_ < 1) ||        (type_ != STRING && type_ != INTEGER && type_ != FLOAT) ||        (type_ == INTEGER && length_ != sizeof(int)         || type_ == FLOAT && length_ != sizeof(float)) ||        (op_ != LT && op_ != LTE && op_ != EQ && op_ != GTE && op_ != GT && op_ != NE))    {        return BADSCANPARM;    }    offset = offset_;    length = length_;    type = type_;    filter = filter_;    op = op_;    return OK;}const Status HeapFileScan::endScan(){    // nothing really to do here as we want to leave to leave the last page pinned    return OK;}HeapFileScan::~HeapFileScan(){    Status status;    if (curPage != NULL)    {        status = bufMgr->unPinPage(filePtr, curPageNo, curDirtyFlag, false);        curPage = NULL;        curPageNo = -1;	curDirtyFlag = false;    }}const Status HeapFileScan::markScan(){    // make a snapshot of the state of the scan    markedPageNo = curPageNo;    markedRec = curRec;    markedIdx = curIdx;    return OK;}const Status HeapFileScan::resetScan(){    Status status;    if (markedPageNo == curPageNo){      curPageNo = markedPageNo ;      curRec = markedRec ;      curIdx = markedIdx ;      status = OK ;      return status ;    }    if (curPage != NULL)      if ((status = bufMgr->unPinPage( filePtr, curPageNo, curDirtyFlag, true )) != OK) return status ;    if ((status = bufMgr->readPage( filePtr, markedPageNo, curPage)) != OK){        curPage = NULL ;        curPageNo = 0 ;        curDirtyFlag = false ;        curRec = NULLRID ;        return status ;    }    curPageNo = markedPageNo ;    curRec = markedRec ;    curIdx = markedIdx ;    curDirtyFlag = false ;    return OK ;}const Status HeapFileScan::scanNext(RID& outRid){    Status 	status = OK ;    RID		tmpRid;    Record      rec;    int		i ;     // cout << "in ScanNext(), curPageNo is " << curPageNo << endl;        for (i = curIdx; i <= headerPage->pageCnt; i++){      if ((status = curPage->firstRecord(tmpRid)) == OK){        if (curRec.slotNo == -1){          if ((status = curPage->firstRecord(tmpRid)) != OK) return status ;          if ((status = HeapFile::getRecord(tmpRid,rec)) != OK) return status ;          if (matchRec(rec) == true){            outRid = tmpRid ;            curRec = tmpRid ;            return OK ;          }          curRec = tmpRid ;        }              while((curPage->nextRecord( curRec, tmpRid)) == OK){          if ((status = HeapFile::getRecord(tmpRid,rec)) != OK) return status ;            if (matchRec(rec) == true){	      outRid = tmpRid ;              curRec = tmpRid ;              return OK ;            }        }      }      if ( i + 1 > headerPage->pageCnt) return FILEEOF ;      if (curPage != NULL)        if ((status = bufMgr->unPinPage( filePtr, curPageNo, curDirtyFlag, true)) != OK) return status ;      if ((status = bufMgr->readPage( filePtr, headerPage->pages[i + 1].pageNo, curPage)) != OK){        curPageNo = -1 ;        curPage = NULL ;        curRec = NULLRID ;        curIdx = -1 ;        return status ;      }      curPageNo = headerPage->pages[i + 1].pageNo ;      curIdx = i + 1 ;      curDirtyFlag = false ;      curRec = NULLRID ;    }  }// returns pointer to the current record.  page is left pinned// and the scan logic is required to unpin the page const Status HeapFileScan::getRecord(Record & rec){    return curPage->getRecord(curRec, rec);}// delete record from file. const Status HeapFileScan::deleteRecord(){    Status status;        if (curRec.pageNo != curPageNo) return BADPAGENO ;         if ((status = curPage->deleteRecord(curRec)) != OK) return status ;        headerPage->recCnt -= 1 ;    headerPage->pages[curIdx].freeSpace = curPage->getFreeSpace() ;    hdrDirtyFlag = true ;    curDirtyFlag = true ;    return OK ;  }// update record from file.const Status HeapFileScan::updateRecord(const Record &rec){   Status status ;      if (curRec.pageNo != curPageNo) return BADPAGENO ;      if ((status = curPage->updateRecord( rec, curRec)) != OK) return status ;     hdrDirtyFlag = true ;   curDirtyFlag = true ;   return OK ;}// mark current page of scan dirtyconst Status HeapFileScan::markDirty(){    curDirtyFlag = true;    return OK;}const bool HeapFileScan::matchRec(const Record & rec) const{    // no filtering requested    if (!filter) return true;    // see if offset + length is beyond end of record    // maybe this should be an error???    if ((offset + length -1 ) >= rec.length)	return false;    float diff = 0;                       // < 0 if attr < fltr    switch(type) {    case INTEGER:        int iattr, ifltr;                 // word-alignment problem possible        memcpy(&iattr,               (char *)rec.data + offset,               length);        memcpy(&ifltr,               filter,               length);        diff = iattr - ifltr;        break;    case FLOAT:        float fattr, ffltr;               // word-alignment problem possible        memcpy(&fattr,               (char *)rec.data + offset,               length);        memcpy(&ffltr,               filter,               length);        diff = fattr - ffltr;        break;    case STRING:        diff = strncmp((char *)rec.data + offset,                       filter,                       length);        break;    }    switch(op) {    case LT:  if (diff < 0.0) return true; break;    case LTE: if (diff <= 0.0) return true; break;    case EQ:  if (diff == 0.0) return true; break;    case GTE: if (diff >= 0.0) return true; break;    case GT:  if (diff > 0.0) return true; break;    case NE:  if (diff != 0.0) return true; break;    }    return false;}InsertFileScan::InsertFileScan(const string & name,                               Status & status) : HeapFile(name, status){    //cout << "doing insertfile scan constuctor " << endl;    // the heapfile constructor will make sure that the header page     // and the first page of the file are in the buffer pool    curRec = NULLRID;}InsertFileScan::~InsertFileScan(){    Status status;    // unpin last page of the scan    if (curPage != NULL)    {        status = bufMgr->unPinPage(filePtr, curPageNo, curDirtyFlag, false);        curPage = NULL;	curRec = NULLRID;        curPageNo = -1;        if (status != OK) cerr << "error in unpin of data page\n";    }}// Insert a record into the fileconst Status InsertFileScan::insertRecord(const Record & rec, RID& outRid){    Status	status ;    RID		rid ;        if ((status = curPage->insertRecord(rec,rid)) == OK){      outRid = rid ;      curRec = rid ;      headerPage->pages[curIdx].freeSpace = curPage->getFreeSpace() ;      headerPage->recCnt += 1 ;      hdrDirtyFlag = true ;      curDirtyFlag = true ;      return OK ;    }      for (int i = 0; i <= headerPage->pageCnt; i++){       if ((status = bufMgr->unPinPage( filePtr, curPageNo, curDirtyFlag, false)) != OK) return status ;       if ((status = bufMgr->readPage( filePtr, headerPage->pages[i].pageNo, curPage)) != OK){         curPage = NULL ;         curRec = NULLRID ;         curIdx = -1 ;         curPageNo = -1 ;         return status ;       }       curPageNo = headerPage->pages[i].pageNo ;       curRec = NULLRID ;       curIdx = i ;       curDirtyFlag = false ;       if ((status = curPage->insertRecord(rec,rid)) == OK){         outRid = rid ;         curRec = rid ;         headerPage->pages[curIdx].freeSpace = curPage->getFreeSpace() ;         headerPage->recCnt += 1 ;         hdrDirtyFlag = true ;         curDirtyFlag = true ;         return OK ;       }    }    if (headerPage->pageCnt ==  DIRCNT - 1) return FILEHDRFULL ;                if ((status = bufMgr->unPinPage( filePtr, curPageNo, curDirtyFlag, false)) != OK) return status ;    curRec = NULLRID ;    curPage = NULL ;    curPageNo = -1 ;    curIdx = -1 ;    curDirtyFlag = false ;    if((status = bufMgr->allocPage( filePtr, curPageNo, curPage)) != OK) return status ;    curPage->init(curPageNo) ;    curRec = NULLRID ;    curDirtyFlag = false ;    headerPage->pageCnt++ ;    hdrDirtyFlag = true ;    headerPage->pages[headerPage->pageCnt].pageNo = curPageNo ;    headerPage->pages[headerPage->pageCnt].freeSpace = curPage->getFreeSpace() ;    curIdx = headerPage->pageCnt ;    if ((status = curPage->insertRecord(rec,rid)) == OK){         outRid = rid ;         curRec = rid ;         headerPage->recCnt += 1 ;         headerPage->pages[curIdx].freeSpace = curPage->getFreeSpace() ;         hdrDirtyFlag = true ;         curDirtyFlag = true ;         return OK ;    }    return NOSPACE ;}

⌨️ 快捷键说明

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