📄 tdataappend.c
字号:
/* ======================================================================== DEVise Data Visualization Software (c) Copyright 1992-1996 By the DEVise Development Group Madison, Wisconsin All Rights Reserved. ======================================================================== Under no circumstances is this software to be copied, distributed, or altered in any way without prior permission from the DEVise Development Group.*//* $Id: TDataAppend.c,v 1.4 1996/06/21 19:33:20 jussi Exp $ $Log: TDataAppend.c,v $ Revision 1.4 1996/06/21 19:33:20 jussi Replaced MinMax calls with MIN() and MAX(). Revision 1.3 1996/01/12 15:24:21 jussi Replaced libc.h with stdlib.h. Revision 1.2 1995/09/05 22:15:47 jussi Added CVS header.*//* Append-only Textual Data */#include <stdio.h>#include <stdlib.h>#include "Exit.h"#include "TDataAppend.h"#include "BufMgr.h"#include "PageFile.h"/********************************************************************Constructors********************************************************************/TDataAppend::TDataAppend(char *name, BufMgr *mgr, int recSize){ Initialize(name, mgr, recSize);}TDataAppend::TDataAppend(char *name, int recSize){ Initialize(name, NULL, recSize);}/**************************************************************Initialization for constructors***************************************************************/void TDataAppend::Initialize(char *name, BufMgr *mgr, int recSize){ _name = name; /* Get memory for returning records */ _createdMgr = false; if ((_mgr=mgr) == NULL){ _createdMgr = true; _mgr = new BufMgr(); } _pfile = new PageFile(name, _mgr); if (_pfile->NumPages() == 0){ /* a newly created file */ _header.numRecs = 0; _header.recSize = recSize; } else { /* Read header from file */ _pfile->ReadHeader(&_header, sizeof(_header)); if (_header.recSize != recSize){ fprintf(stderr,"TDataAppend::TDataAppend(%s,,%d):recSize shoudl be %d\n", name, recSize, _header.recSize); Exit::DoExit(1); } } _lastGetPageNum = -1; _returnRecs = new (void *[RecordsPerPage()]);}/**********************************************************************Destructor***********************************************************************/TDataAppend::~TDataAppend(){/*printf("TDataAppend: destructor\n");*/ /* Write header back */ _pfile->WriteHeader(&_header, sizeof(_header)); /* delete the page file */ delete _pfile; if (_createdMgr) /* delete the buffer manager */ delete _mgr; delete _returnRecs;}/******************************************************************Return # of pages******************************************************************/int TDataAppend::NumPages(){ return _header.numRecs / RecordsPerPage() + ( (_header.numRecs % RecordsPerPage()) == 0? 0 : 1);}/*****************************************************************Return page number of 1st page *******************************************************************/int TDataAppend::FirstPage(){ return 1;}/******************************************************************Return page number of last page*******************************************************************/int TDataAppend::LastPage() { return NumPages(); };/***********************************************************************Get page numbers of pages currently in memory ***********************************************************************/void TDataAppend::PagesInMem(int &numPages, int *&pageNums){ /* Report all pages except page 0 */ _pfile->PagesInMem(numPages, pageNums);}/*********************************************************************Fetch page in mem and return all records**********************************************************************/void TDataAppend::GetPage(int pageNum, int &numRecs, RecId &startRid, void **&recs, Boolean isPrefetch){ if (pageNum < 1 || pageNum > NumPages()){ fprintf(stderr, "TDataAppend::GetPage: invalid page number %d\n", pageNum); Exit::DoExit(1); } BufPage *bpage = _pfile->GetPage(pageNum, isPrefetch); RecId firstRid = MakeRecId(pageNum, 0); numRecs = MIN(RecordsPerPage(), (int)(_header.numRecs - firstRid)); RecId lastRid = firstRid+numRecs-1; /* set return params */ startRid = firstRid; int i; char *ptr = (char *)bpage->PageData(); for (i=0; i < numRecs; i++){ _returnRecs[i] = ptr; ptr += _header.recSize; } recs = _returnRecs; _lastGetPageNum = pageNum; _lastGetPageBuf = bpage;}/*********************************************************************Return true if page in mem**********************************************************************/Boolean TDataAppend::PageInMem(int pageNum){ return _pfile->PageInMem(pageNum);}/*********************************************************************Fetch the page containing the specified record id.Returns: pageNum: page number of the page rec: pointer to record data.FreePage() must be called to free the page ************************************************************************/void TDataAppend::GetRecPage(RecId recId, int &pageNum, void *&rec, Boolean isPrefetch){ CheckRecId(recId); pageNum = PageNum(recId); BufPage *bpage = _pfile->GetPage(pageNum, isPrefetch); _lastGetPageNum = pageNum; _lastGetPageBuf = bpage; rec = RecordAddress(recId, bpage->PageData());}/*******************************************************************Free page, called when page is no longer needed.*********************************************************************/void TDataAppend::FreePage(int pageNum, BufHint hint){ if (pageNum == _lastGetPageNum){ /* free last page we got */ _pfile->UnfixPage(_lastGetPageBuf, hint); _lastGetPageNum = -1; /* page no longer cached */ } else { /* get the page back. Free it twice: once for when we got it last time. Once for now.*/ BufPage *bpage = _pfile->GetPage(pageNum); _pfile->UnfixPage(bpage, hint); _pfile->UnfixPage(bpage, hint); }}/**********************************************************************Record Oriented Interface**********************************************************************//****************************************************************Return # of records*****************************************************************/int TDataAppend::NumRecords(){ return _header.numRecs;}/*****************************************************************Return record size********************************************************************/int TDataAppend::RecSize(){ return _header.recSize;}/*********************************************************************Insert a new record **********************************************************************/void TDataAppend::InsertRec(void *data){ /* update record Id */ int recId = _header.numRecs++; /* Read page from page file */ int page = PageNum(recId); BufPage *bpage; int temp; if (page > _pfile->NumPages()) /* Create a new page */ bpage = _pfile->CreatePage(temp); else /* read an existing page */ bpage = _pfile->GetPage(page); /* Write the new record onto disk */ char *recAddr = RecordAddress(recId, bpage->PageData()); bcopy((char *)data, recAddr, _header.recSize); /* mark page dirty and no longer needed */ _pfile->DirtyPage(bpage); _pfile->UnfixPage(bpage, Stay); /* Report insertion of new record */ TData::ReportNewRec(recId);}/**********************************************************************Check record id***********************************************************************/void TDataAppend::CheckRecId(RecId id){ if (id < 0 ||id >= _header.numRecs){ fprintf(stderr,"TDataAppend::invalid recId %d, only %d recs\n", id, _header.numRecs); Exit::DoExit(1); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -