📄 memory.cpp
字号:
// Memory.cpp: implementation of the CMemory class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Database.h"
#include "Memory.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
UINT CMemory::MaxHashFileID=0;
DB_table CMemory::dbtb=NULL;
PData_Block CMemory::lpdOld=NULL;
unsigned short CMemory::db_count=0;
IDX_table CMemory::ibtb=NULL;
PIndex_Block CMemory::lpiOld=NULL;
unsigned short CMemory::ib_count=0;
HB_table CMemory::htb=NULL;
PHash_Block CMemory::lphOld=NULL;
unsigned short CMemory::h_count=0;
File_table CMemory::ftb=NULL;
unsigned short CMemory::f_count=0;
CMemory::CMemory()
{
}
CMemory::~CMemory()
{
}
CDatabaseFile * CMemory::GetFile(UINT ID)
{
WORD i;
CDatabaseFile *cdbf;
if(ID==0)
return NULL;
PFile_Item pf=ftb;
for(i=0;i<f_count && pf->cdbf->ID!=ID;++i,pf=pf->next);
if(i<f_count && (pf->cdbf->ID==ID) )
{
return pf->cdbf;
}
else
{
CString filename;
filename.Format("D:\\DB\\%d.db",ID);
cdbf=new CDatabaseFile(filename,CFile::modeCreate
|CFile::modeNoTruncate|CFile::modeReadWrite,ID);
PFile_Item newfn=new File_Item(cdbf);
if(!ftb)
{
ftb=newfn;
ftb->next=ftb;
}
else
{
newfn->next=pf->next;//应该是dbtb
pf->next=newfn;
}
++f_count;
return cdbf;
}
}
CBlock * CMemory::ReadDBBlock(PDB db_addr,bool view)
{
int i;
CBlock *newcb;
if(db_addr==DB_NULL)
return NULL;
PData_Block pblk=dbtb;
db_addr=(db_addr&0xFFFFFFFF00000000) + BLOCK(db_addr)*MAIN_BLOCK;//!!!!
for(i=0;i<db_count&&pblk->db_addr!=db_addr;++i,pblk=pblk->next);
if(i<db_count&&(pblk->db_addr==db_addr))//命中
{
pblk->mem_addr->rtag=0x1;//读标志
return pblk->mem_addr;
}
if(i>=db_count)
{
CString filename;
filename.Format("D:\\DB\\%d",FILE(db_addr));
if(!view)
filename+=".db";
else
filename+=".view";
CFile f(LPCTSTR(filename),CFile::modeRead);
BYTE *buf=new BYTE[MAIN_BLOCK];
f.Seek(MAIN_BLOCK*(BLOCK(db_addr)),CFile::begin);//?????????????????????????
UINT BytesRead=f.Read(buf,MAIN_BLOCK);
f.Close();
newcb=new CBlock(buf,BytesRead,db_addr,view,0);
if(db_count<DB_BLOCK_COUNT)//还未达到内存块数上限100
{
PData_Block newbn=new Data_Block(db_addr,newcb);
if(!dbtb)
{
dbtb=newbn;
dbtb->next=dbtb;
lpdOld=newbn;
}
else
{
newbn->next=pblk->next;//应该是dbtb
pblk->next=newbn;
}
++db_count;
}
else//需进行时钟块替换
{
CBlock *replaced;
while(lpdOld->mem_addr->rtag)//最老的块被房问过
{
lpdOld->mem_addr->rtag=0x0;
lpdOld=lpdOld->next;//时钟移动
}
replaced=lpdOld->mem_addr;
lpdOld->mem_addr=newcb;
lpdOld->db_addr=newcb->ID;
if(1)//replaced->wtag)//块被修改,则需要写回
replaced->WriteBack();//???????????????????????????????????8/18
lpdOld=lpdOld->next;
}
return newcb;
}
}
BTNODE * CMemory::ReadIDXBlock(PDB db_addr,unsigned short m,BYTE KeyType,WORD KeyLength,BTNODE *source)
{
int i;
BTNODE *newcb;
if(db_addr==DB_NULL)
return NULL;
int j=0;////////////////////////////////////////////////DEBUG
PIndex_Block pblk=ibtb;
for(i=0;i<ib_count&&pblk->db_addr!=db_addr;++i,pblk=pblk->next)
++j;
if(i<ib_count&&pblk->db_addr==db_addr)//命中
{
if(pblk->mem_addr->rtag!=0x2)
pblk->mem_addr->rtag=0x1;//读标志
return pblk->mem_addr;
}
if(i>=ib_count)
{
CString filename;
filename.Format("D:\\DB\\%d",FILE(db_addr));
filename+=".index";
CFile f(LPCTSTR(filename),CFile::modeRead);
BYTE *buf=new BYTE[MAIN_BLOCK];
f.Seek(MAIN_BLOCK*(BLOCK(db_addr)),CFile::begin);//??????????????????????????????
UINT BytesRead=f.Read(buf,MAIN_BLOCK);
f.Close();
newcb=new BTNODE(db_addr,buf,m,KeyType,KeyLength);
if(ib_count<IDX_BLOCK_COUNT)//还未达到内存块数上限1000
{
PIndex_Block newbn=new Index_Block(db_addr,newcb);
if(!ibtb)
{
ibtb=newbn;
ibtb->next=ibtb;
lpiOld=newbn;
}
else
{
newbn->next=pblk->next;//应该是ibtb
pblk->next=newbn;
}
++ib_count;
ASSERT(ib_count<=IDX_BLOCK_COUNT);
}
else//需进行时钟块替换
{
BTNODE *replaced=NULL;
while(lpiOld->mem_addr->rtag>0)//最老的块被房问过
{
if(lpiOld->mem_addr->rtag==0x1)//0x2表示根结点或m_sqt
{
//不能互有关系,才可替换
if(lpiOld->mem_addr!=source)
lpiOld->mem_addr->rtag=0x0;
}
lpiOld=lpiOld->next;//时钟移动
}
replaced=lpiOld->mem_addr;
lpiOld->mem_addr=newcb;
lpiOld->db_addr=newcb->DB_THIS;
if(1)//replaced->wtag)//块被修改,则需要写回
{
replaced->WriteDisk();
delete replaced;
replaced=NULL;
}
lpiOld=lpiOld->next;
}
return newcb;
}
}
/*=====================================================================================
|文件尾(UINT) 当前偏移(UINT)|当前MaxFileNo+1(UINT)|多余分配号1(UINT) 下一个偏移(UINT)|
|多余分配号2(UINT) 下一个偏移(UINT)|多余分配号3(UINT) 下一个偏移(UINT)|.....*/
UINT CMemory::AllocateID(BOOL mode,UINT RelationNo)
{
CString s("");
LPCTSTR filename;
if(mode==FILE_ID)
filename="D:\\DB\\FileAllocate.alct";
else if(mode==SCHEMA_ID)
filename="D:\\DB\\SchemaAllocate.alct";
else
{
ASSERT(RelationNo>=6);
s.Format("D:\\DB\\%d.alct",RelationNo);
filename=LPCTSTR(s);
}
CFile f(filename,CFile::modeCreate|CFile::modeNoTruncate|CFile::modeReadWrite);
UINT offset=8;
UINT FileEnd=3*sizeof(UINT);
UINT Ret=0;
if(f.GetLength()==0)
{
UINT current_no=6;//从6号开始分配
f.SeekToBegin();
f.Write(&FileEnd,sizeof(UINT));
f.Write(&offset,sizeof(UINT));
f.Write(¤t_no,sizeof(UINT));
}
f.SeekToBegin();
f.Read(&FileEnd,sizeof(UINT));
f.Read(&offset,sizeof(UINT));
f.Read(&Ret,sizeof(UINT));
if(offset==8)//没有多余分配号
{
UINT NewNo=Ret+1;
LONG off=-int(sizeof(UINT));
f.Seek(off,CFile::current);
f.Write(&NewNo,sizeof(UINT));
}
else
{
UINT NewOffset;
f.Seek(offset,CFile::begin);
f.Read(&Ret,sizeof(UINT));
f.Read(&NewOffset,sizeof(UINT));
//写入新的文件尾和新的偏移
FileEnd=FileEnd-2*sizeof(UINT);
f.SeekToBegin();
f.Write(&FileEnd,sizeof(UINT));
f.Write(&NewOffset,sizeof(UINT));
}
return Ret;
}
PDB CMemory::AllocatePDB(UINT FN,void *mem,BOOL mode)//同时将新块加入链表
{
PDB Ret;
UINT FileNo=FN;
CString s;
switch(mode)
{
case INDEX_FILE:
{
s.Format("D:\\DB\\%d",FileNo);
s+=".index";
CIndexFile cidxf(s,CFile::modeReadWrite);
while(!(Ret=cidxf.AllocateNewBlock()))
{
if(cidxf.NextFile==0)
{
FileNo=CMemory::AllocateID(FILE_ID);
s.Format("D:\\DB\\%d",FileNo);
s+=".index";
cidxf.SetNextFile(FileNo);
cidxf.Close();
cidxf.Open(s,CFile::modeCreate|CFile::modeReadWrite
,FileNo);
}
else
{
s.Format("D:\\DB\\%d",cidxf.NextFile);
s+=".index";
cidxf.Close();
cidxf.Open(s,CFile::modeReadWrite);
}
}
Index_Block *pblk=ibtb;
for(WORD i=0;i<ib_count;i++,pblk=pblk->next);
PIndex_Block newbn=new Index_Block(Ret,(BTNODE *)mem);
if(!ibtb)
{
ibtb=newbn;
ibtb->next=ibtb;
lpiOld=newbn;
}
else
{
newbn->next=pblk->next;//应该是ibtb
pblk->next=newbn;
}
++ib_count;
}
break;
}
return Ret;
}
void CMemory::DeleteID(UINT ID,BOOL mode,UINT RelationNo,BOOL FileMode)
{
CString s("");
LPCTSTR filename;
if(mode==FILE_ID)
filename="D:\\DB\\FileAllocate.alct";
else if(mode==SCHEMA_ID)
filename="D:\\DB\\SchemaAllocate.alct";
else
{
s.Format("D:\\DB\\%d.alct",RelationNo);
filename=LPCTSTR(s);
}
CFile f(filename,CFile::modeReadWrite);
UINT offset=0;
UINT FileEnd=0;
f.SeekToBegin();
f.Read(&FileEnd,sizeof(UINT));
UINT FileLength=f.GetLength();
if(FileLength-FileEnd<=10*sizeof(UINT))
f.SetLength(FileLength+MAIN_BLOCK);//文件增长4096字节
f.SeekToBegin();
f.Read(&FileEnd,sizeof(UINT));
f.Read(&offset,sizeof(UINT));
f.Seek(FileEnd,CFile::begin);
f.Write(&ID,sizeof(UINT));
f.Write(&offset,sizeof(UINT));
//更新offset和FileEnd
offset=FileEnd;
FileEnd=FileEnd+2*sizeof(UINT);
f.SeekToBegin();
f.Write(&FileEnd,sizeof(UINT));
f.Write(&offset,sizeof(UINT));
if(mode==FILE_ID)
{
CString s("");
s.Format("D:\\DB\\%d",ID);
switch(FileMode)
{
case DATA_FILE:
s+=".db";
break;
case INDEX_FILE:
s+=".index";
break;
default:break;
}
CFile::Remove(LPCTSTR(s));//删除文件
}
}
int CMemory::GetTime()
{
return 0;
}
void CMemory::WriteBackAll()
{
Data_Block *pdb=dbtb;
Data_Block *db_next=NULL;
Index_Block *pib=ibtb;
Index_Block *ib_next=NULL;
File_Item *pf=ftb;
File_Item *f_next=NULL;
if(pdb&&pdb->next!=pdb)
{
do
{
pdb->next->mem_addr->WriteBack();
db_next=pdb->next;
pdb->next=pdb->next->next;
delete db_next->mem_addr;
delete db_next;
}
while(pdb->next!=pdb);
}
ASSERT(!pdb || (pdb->next==pdb ));
if(pdb)
{
pdb->mem_addr->WriteBack();
delete pdb->mem_addr;
delete pdb;
}
if(pib&&pib->next!=pib)
{
do
{
pib->next->mem_addr->WriteDisk();
ib_next=pib->next;
pib->next=pib->next->next;
delete ib_next->mem_addr;//!!!!!!!!!
delete ib_next;
}
while(pib->next!=pib);
}
ASSERT(!pib || (pib->next==pib));
if(pib)
{
pib->mem_addr->WriteDisk();
delete pib->mem_addr;
delete pib;
}
if(pf&&pf->next!=pf)
{
do
{
pf->next->cdbf->Close();
f_next=pf->next;
pf->next=pf->next->next;
delete f_next->cdbf;
delete f_next;
}
while(pf->next!=pf);
}
ASSERT(!pf || (pf->next==pf));
if(pf)
{
pf->cdbf->Close();
delete pf->cdbf;
delete pf;
}
}
/*for(i=0;i<db_count;++i)
{
pdb->mem_addr->WriteBack();
pdb=pdb->next;
}
for(i=0;i<ib_count;i++)
{
pib->mem_addr->WriteDisk();
pib=pib->next;
}
for(i=0;i<f_count;i++)
{
pf->cdbf->Close();
pf=pf->next;
}*/
CHashBlock * CMemory::ReadHashBlock(PDB db_addr, UINT RcdLen,BOOL clean)
{
int i;
CHashBlock *newhb=NULL;
ASSERT(db_addr!=DB_NULL);//?????????????????
if(db_addr==DB_NULL)
return NULL;
PHash_Block pblk=htb;
for(i=0;i<h_count&&pblk->db_addr!=db_addr;++i,pblk=pblk->next);
if(i<h_count&&(pblk->db_addr==db_addr))//命中
{
pblk->mem_addr->rtag=0x1;//读标志
return pblk->mem_addr;
}
if(i>=h_count)
{
CString filename;
filename.Format("D:\\DB\\%d.hash",FILE(db_addr));
CFile f(LPCTSTR(filename),CFile::modeRead);
BYTE *buf=new BYTE[MAIN_BLOCK];
f.Seek(MAIN_BLOCK*(BLOCK(db_addr)),CFile::begin);//?????????????????????????
UINT BytesRead=f.Read(buf,MAIN_BLOCK);
f.Close();
newhb=new CHashBlock(buf,BytesRead,db_addr,RcdLen,clean);
if(h_count<DB_BLOCK_COUNT)//还未达到内存块数上限100
{
PHash_Block newbn=new Hash_Block(db_addr,newhb);
if(!htb)
{
htb=newbn;
htb->next=htb;
lphOld=newbn;
}
else
{
newbn->next=pblk->next;//应该是htb
pblk->next=newbn;
}
++h_count;
}
else//需进行时钟块替换
{
CHashBlock *replaced=NULL;
while(lphOld->mem_addr->rtag)//最老的块被房问过
{
lphOld->mem_addr->rtag=0x0;
lphOld=lphOld->next;//时钟移动
}
replaced=lphOld->mem_addr;
lphOld->mem_addr=newhb;
lphOld->db_addr=newhb->ID;
if(1)//replaced->wtag)//块被修改,则需要写回
{
replaced->WriteBack();//???????????????????????????????????8/18
delete replaced;
replaced=NULL;
}
lphOld=lphOld->next;
}
return newhb;
}
}
UINT CMemory::GetHashFileID()
{
MaxHashFileID++;
return MaxHashFileID;
}
void CMemory::DestroyHashTable()
{
PHash_Block phb=htb;
PHash_Block hb_next=NULL;
if(phb&&phb->next!=phb)
{
do
{
hb_next=phb->next;
phb->next=phb->next->next;
delete hb_next->mem_addr;
delete hb_next;
}
while(phb->next!=phb);
}
ASSERT(!phb || (phb->next==phb ));
if(phb)
{
delete phb->mem_addr;
delete phb;
}
htb=NULL;
lphOld=NULL;
h_count=0;
MaxHashFileID=0;
}
BOOL CMemory::ATOI(CString value,int &ival)
{
CString s;
ival=atoi(LPCTSTR(value));
s.Format("%d",ival);
if(s!=value)
return FALSE;
return TRUE;
}
BOOL CMemory::ATOF(CString value, float &fval)
{
CString s;
fval=float(atof(LPCTSTR(value)));
s.Format("%f",fval);
if(s!=value)
return FALSE;
return TRUE;
}
BOOL CMemory::ATOTime(CString value, Time &time)
{
if(value.GetLength()==8&&value[2]==':'&&value[5]==':')
{
time=Time(value);
return TRUE;
}
return FALSE;
}
BOOL CMemory::ATODate(CString value, Date &date)
{
if(value.GetLength()==10&&value[4]=='-'&&value[7]=='-')
{
date=Date(value);
return TRUE;
}
return FALSE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -