#ifndef STRUCTURE_H_INCLUDED
#define STRUCTURE_H_INCLUDED
#define FRAMESIZE 4096
#define MAXPAGES 100000
#define DEFBUFSIZE 1024
#include <string>
#include <cstdio>
#include "structure.h"
using namespace std;
struct NewPage
{ int page_id;
int frame_id;
};
struct bFrame
{
char field [FRAMESIZE];
};
struct BCB
{
int page_id;
int frame_id;
int latch;
int count;
int dirty;
BCB * next;
BCB * previous;
};
struct BUFFER
{bFrame bframe[DEFBUFSIZE];
bool used[DEFBUFSIZE];
int freeFrames;
};
class DSMgr
{
public:
DSMgr();
int OpenFile(string filename);
int CloseFile();
bFrame ReadPage(int page_id);
int WritePage(int frame_id, bFrame frm);
int Seek(int offset, int pos);
FILE * GetFile();
void IncNumPages();
int GetNumPages();
void SetUse(int index, int use_bit);
int GetUse(int index);
int WriteBackPage(int page_id, bFrame frm);
int FileSeek(int offset);
private:
FILE *currFile;
int numPages;
int pages[MAXPAGES];
};
DSMgr::DSMgr()
{
int flag=OpenFile("data.dbf");
if(-1==flag)
throw "没有找到数据库文件";
}
int DSMgr::OpenFile(string filename)
{
currFile=fopen(filename.c_str(),"rb+");
if(currFile==NULL)
return -1;
else
return 0;
}
int DSMgr::CloseFile()
{
return fclose(currFile);
}
bFrame DSMgr::ReadPage(int page_id)
{
FileSeek((page_id+1)*FRAMESIZE);
bFrame bframe;
int getByteCount=fread(bframe.field,1,FRAMESIZE,currFile);
if(getByteCount!=FRAMESIZE)
throw "读页面失败";
return bframe;
}
int DSMgr::WritePage(int frame_id, bFrame frm)
{
return 0;
}
int DSMgr::WriteBackPage(int page_id, bFrame frm)
{FileSeek((page_id+1)*FRAMESIZE);
int writeSuccessCount=fwrite(frm.field,1,FRAMESIZE,currFile);
fflush(currFile);
if(writeSuccessCount!=FRAMESIZE)
throw "写回页面失败";
return 0;
}
int DSMgr::Seek(int offset, int pos)
{if(1==pos)
fseek(currFile,offset,SEEK_SET);
if(2==pos)
fseek(currFile,offset,SEEK_CUR);
if(3==pos)
fseek(currFile,offset,SEEK_END);
return 0;
}
int DSMgr::FileSeek(int offset)
{fseek(currFile,offset,SEEK_SET);
return 0;
}
FILE* DSMgr::GetFile()
{
return currFile;
}
void DSMgr::IncNumPages()
{
numPages++;
}
int DSMgr::GetNumPages()
{
return numPages;
}
void DSMgr::SetUse(int index, int use_bit)
{
}
int DSMgr::GetUse(int index)
{
return 0;
}
#endif // STRUCTURE_H_INCLUDED
#include "structure.h"
#include<fstream>
#include<iostream>
#include<cstring>
#include<string>
#include <sstream>
#include <list>
using namespace std;
int count=0;
class BMgr
{
public:
BMgr();
int FixPage(int page_id, int prot);
NewPage FixNewPage();
int UnfixPage(int page_id);
int NumFreeFrames();
int SelectVictim();
int Hash(int page_id);
void RemoveBCB(BCB * ptr, int page_id);
void UpdateLRUEle(int frid);
void SetDirty(int frame_id);
void UnsetDirty(int frame_id);
void WriteDirtys();
void PrintFrame(int frame_id);
void getFrameData(char storage [],int frameID)
{for(int i=0;i<FRAMESIZE;i++)
{storage[i]=buffer.bframe[frameID].field[i];
}
}
BUFFER getBuffer();
int getIdleFrame()
{for(int i=0;i<DEFBUFSIZE;i++)
{if(!buffer.used[i])
return i;
}
return -1;
}
void decreaseLatch(int frameID)
{BCBassemble[frameID]->latch--;
}
DSMgr getDSMgr()
{return dsm;
}
private:
int ftop[DEFBUFSIZE];
BCB* ptof[DEFBUFSIZE];
BCB * BCBassemble[DEFBUFSIZE];
BUFFER buffer;
list<int> lrulist;
DSMgr dsm;
};
BMgr::BMgr()
{
for(int i=0;i<DEFBUFSIZE;i++)
{buffer.used[i]=false;
ptof[i]=0;
}
buffer.freeFrames=DEFBUFSIZE;
}
int BMgr::FixPage(int page_id, int prot)
{
BCB *tempBCBPointer=ptof[page_id%DEFBUFSIZE];
if(0!=tempBCBPointer)
{while(tempBCBPointer->page_id!=page_id)
{cout<<tempBCBPointer<<" ";
tempBCBPointer=tempBCBPointer->next;
if(0==tempBCBPointer)
break;
}
cout<<endl;
if(0!=tempBCBPointer)
{UpdateLRUEle(tempBCBPointer->frame_id);
tempBCBPointer->latch=tempBCBPointer->latch+1;
return tempBCBPointer->frame_id;
}
}
if(0==buffer.freeFrames)
{int victimFrameID=SelectVictim();
BCB *bcbVcitim =BCBassemble[victimFrameID];
if(1==bcbVcitim->dirty)
{
dsm.WriteBackPage(bcbVcitim->page_id,buffer.bframe[bcbVcitim->frame_id]);
count++;
}
if(0!=bcbVcitim->previous)
{bcbVcitim->previous->next=bcbVcitim->next;
if(0!=bcbVcitim->next)
bcbVcitim->next->previous=bcbVcitim->previous;
}
else
{ptof[(bcbVcitim->page_id)%DEFBUFSIZE]=bcbVcitim->next;
if(0!=bcbVcitim->next)
bcbVcitim->next->previous=0;
}
buffer.used[victimFrameID]=false;
buffer.freeFrames++;
bFrame abframe=dsm.ReadPage(page_id);
for(int i=0;i<FRAMESIZE;i++)
{buffer.bframe[victimFrameID].field[i]=abframe.field[i];
}
count++;
buffer.used[victimFrameID]=true;
buffer.freeFrames--;
delete bcbVcitim;
BCB * bcb=new BCB;
bcb->dirty=0;
bcb->frame_id=victimFrameID;
bcb->page_id=page_id;
bcb->next=0;
bcb->previous=0;
BCB * tempBCBPointer=ptof[page_id%DEFBUFSIZE];
if(0==tempBCBPointer)
{ptof[page_id%DEFBUFSIZE]=bcb;
bcb->previous=0;
bcb->next=0;
}
else
{ bcb->next=tempBCBPointer->next;
if(0!=tempBCBPointer->next)
tempBCBPointer->next->previous=bcb;
tempBCBPointer->next=bcb;
bcb->previous=tempBCBPointer;
}
UpdateLRUEle(victimFrameID);
bcb->latch=bcb->latch+1;
BCBassemble[victimFrameID]=bcb;
return victimFrameID;
}
else
{
int idleFrameID=getIdleFrame();
bFrame abframe=dsm.ReadPage(page_id);
for(int i=0;i<FRAMESIZE;i++)
buffer.bframe[idleFrameID].field[i]=abframe.field[i];
count++;
buffer.used[idleFrameID]=true;
buffer.freeFrames--;
BCB * bcb=new BCB;
bcb->dirty=0;
bcb->frame_id=idleFrameID;
bcb->page_id=page_id;
bcb->next=0;
bcb->previous=0;
UpdateLRUEle(idleFrameID);
cout<<"LRU队首"<<lrulist.front()<<endl;
BCBassemble[idleFrameID]=bcb;
BCB * tempBCBPointer=ptof[page_id%DEFBUFSIZE];
if(0==tempBCBPointer)
{ptof[page_id%DEFBUFSIZE]=bcb;
bcb->previous=0;
}
else
{
bcb->next=tempBCBPointer->next;
if(0!=tempBCBPointer->next)
tempBCBPointer->next->previous=bcb;
tempBCBPointer->next=bcb;
bcb->previous=tempBCBPointer;
}
bcb->latch=bcb->latch+1;
return idleFrameID;
}
}
NewPage BMgr::FixNewPage()
{for(int i=0;i<DEFBUFSIZE;i++)
{if(!buffer.used[i])
{NewPage newpage;
newpage.frame_id=i;
newpage.page_id=ftop[i];
return newpage;
}
}
NewPage newpage;
newpage.frame_id=-1;
newpage.page_id=-1;
return newpage;
}
int BMgr::UnfixPage(int page_id)
{
}
int BMgr::NumFreeFrames()
{
return buffer.freeFrames;
}
int BMgr::SelectVictim()
{
for(list<int> ::reverse_iterator riter=lrulist.rbegin();riter!=lrulist.rend();riter++)
if(0==BCBassemble[*riter]->latch)
{return *riter;
}
return -1;
}
int BMgr::Hash(int page_id)
{
return (page_id)%DEFBUFSIZE;
}
void BMgr::RemoveBCB(BCB* ptr, int page_id)
{
}
void BMgr::UpdateLRUEle(int frid)
{ lrulist.remove(frid);
lrulist.push_front(frid);
}
void BMgr::SetDirty(int frame_id)
{
BCBassemble[frame_id]->dirty=1;
}
void BMgr::UnsetDirty(int frame_id)
{
}
void BMgr::WriteDirtys()
{
}
void BMgr::PrintFrame(int frame_id)
{ for(int i=0;i<FRAMESIZE;i++)
{cout<<buffer.bframe[frame_id].field[i];
}
cout<<endl;
}
BUFFER BMgr::getBuffer()
{return buffer;
}
int main()
{int datacount=0;
ifstream infileStream;
string str;
infileStream.open("data.txt",ios::in);
char requestdata[30];
BMgr bMgr;
while(!infileStream.eof())
{datacount++;
cout<<"datacount:*************"<<datacount<<endl;
infileStream.getline(requestdata,20,'\n');
str=string(requestdata);
if(str[str.size()-1]=='\n')
str=str.substr(0,str.size()-1);
int pos=str.find(',',0);
string strRorW=str.substr(0,pos);
string strPage=str.substr(pos+1,str.length());
stringstream ss;
int flagWorR=-1;
int pageAccessID=-1;
ss<<strRorW;
ss>>flagWorR;
ss.clear();
ss<<strPage;
ss>>pageAccessID;
cout<<flagWorR<<","<<pageAccessID<<endl;
int frameID=bMgr.FixPage(pageAccessID,flagWorR);
char contentPage[FRAMESIZE];
bMgr.getFrameData(contentPage,frameID);
cout<<"&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&"<<strlen(contentPage)<<endl;
for(int i=0;i<FRAMESIZE;i++)
{cout<<contentPage[i];
}
cout<<endl;
if(flagWorR==1)
{bMgr.SetDirty(frameID);
}
bMgr.decreaseLatch(frameID);
}
infileStream.close();
bMgr.getDSMgr().CloseFile();
cout<<"buffer和磁盘之间的IO次数是"<<count<<endl;
return 0;
}