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

📄 databasefile.cpp

📁 有计算机图形学、图像处理、dbms、sniffer、中游俄罗斯外挂、othello、遗传算法、舌苔分析等程序。
💻 CPP
字号:
// DatabaseFile.cpp: implementation of the CDatabaseFile class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Database.h"
#include "DatabaseFile.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CDatabaseFile::CDatabaseFile()
{
    
}

CDatabaseFile::CDatabaseFile(LPCTSTR lpszFileName, UINT nOpenFlags,UINT id)
{
	CFile file(lpszFileName,nOpenFlags);
	UINT filelength=file.GetLength();
	if(filelength==0)//是新文件
	{
		const char *magic="DAT";
		file.SetLength(2*MAIN_BLOCK);//初始8192字节
		ID=id;
		end=MAIN_BLOCK;//4096
		start=MAIN_BLOCK;
        wBlockNum=1;
		NextFile=0;
		UINT FirstSpaceOffset=0;
		WORD FirstSpaceLarge=0;
		file.SeekToBegin();
		file.Write(magic,MAGIC);
		file.Write(&ID,sizeof(UINT));
		file.Write(&wBlockNum,sizeof(WORD));
		file.Write(&end,sizeof(UINT));
		file.Write(&start,sizeof(UINT));
		file.Write(&NextFile,sizeof(UINT));
		file.Write(&FirstSpaceOffset,sizeof(UINT));
		file.Write(&FirstSpaceLarge,sizeof(UINT));

		sfirst=slast=NULL;
	}
	else
	{
		sfirst=slast=NULL;
		UINT s_off;
		UINT s_large;
		char *magic[4];
		file.SeekToBegin();
		file.Read(magic,MAGIC);
		//if(strcmp(magic,"DAT"))
			//::AfxThrowFileException(
		file.Read(&ID,sizeof(UINT));
		file.Read(&wBlockNum,sizeof(WORD));
		//Read(&PriorFile,sizeof(UINT));
		file.Read(&end,sizeof(UINT));
		file.Read(&start,sizeof(UINT));
		file.Read(&NextFile,sizeof(UINT));
		
		//读空闲表
		do
		{
			file.Read(&s_off,sizeof(UINT));
			file.Read(&s_large,sizeof(UINT));
			
			if(s_off!=0&&s_large!=0)//断言:这两个条件同成立或...
			{
				Space *s=new Space(s_off,s_large);
				InsertSpace(s);
			    file.Seek(s_off,CFile::begin);
			}
			ASSERT(s_off!=0&&s_large!=0||s_off==0&&s_large==0);
		}
		while(s_off!=0&&s_large!=0);
	}
}

void CDatabaseFile::DeleteSpace(Space *s)
{
	Space *before=NULL;
	Space *ps=sfirst;
	while(ps&&ps!=s)
	{
		before=ps;
		ps=ps->next;
	}
	if(!ps)
		return;
	else//ps==s
	{
		if(ps==sfirst)
			sfirst=ps->next;
		if(ps==slast)
			slast=before;
		if(before)
            before->next=s->next;
		
		delete(s);
	}
}
CDatabaseFile::~CDatabaseFile()
{
    Close();
}
//为记录分配数据库地址
//暂且认为字段长度比块小
PDB CDatabaseFile::Allocate(Record *rcd, Relationship *R)
{
	PDB Ret=0;
	Space *s=sfirst;

	CString filename("");
	filename.Format("D:\\DB\\%d.db",ID);
	CFile file(LPCTSTR(filename),CFile::modeReadWrite);
	UINT FileLength=file.GetLength();
	file.Close();
    
	UINT RcdLength=rcd->m_length;
	Space *s1=NULL;
	
	
    //UINT FitOffset=0;
    //UINT FitLarge=0;
	
	while(s)
	{
		if((s->uLarge-RECORD_HEAD-RcdLength)>=0)
		{
			if( (s->uLarge/2) >= (RECORD_HEAD+RcdLength) )
			{
				s1=new Space(s->uOffset,RECORD_HEAD+RcdLength);
				s->uOffset+=(RECORD_HEAD+RcdLength);
				s->uLarge-=(RECORD_HEAD+RcdLength);
			}
			else
			{
				s1=new Space(s->uOffset,s->uLarge);
				DeleteSpace(s);
			}
			
			
			if(InsertRecord(s1,rcd))
            {
				Ret=(PDB(ID)<<32)+PDB(s1->uOffset);
				return Ret;
			}
		}
        
		else
			s=s->next;
	}
	//此时必然没有s1
	WORD wBlockNum1=wBlockNum;
	Space *space_end=new Space(end,0);
	while( !s1 && ((end+RECORD_HEAD+RcdLength) > FileLength)  )
	{
		if(wBlockNum1 < FILE_MAX/MAIN_BLOCK)
		{
			file.Open(LPCTSTR(filename),CFile::modeReadWrite);
			file.SetLength(FileLength+MAIN_BLOCK);
			FileLength=file.GetLength();
			wBlockNum1++;
			file.Close();
		}
		else
		{
			delete(space_end);
			return DB_NULL;
		}
	}
	wBlockNum=wBlockNum1;
	
	s1=space_end;
	if(InsertRecord(s1,rcd))
    {
		Ret=(PDB(ID)<<32)+PDB(s1->uOffset);
		delete s1;
		return Ret;
	}//要改变end
}

int CDatabaseFile::GetTime()
{
    return 0;
}
BOOL CDatabaseFile::InsertRecord(Space *s, Record *r/*, Relationship *R*/)
//可能要改变文件尾
{
	CBlock *cb;
	
	PDB db_addr=PDB(ID);
	
	BYTE exist=1;
	
	UINT RcdLength=r->m_length;
	UINT RcdID=CMemory::AllocateID(RECORD_ID,r->pattern->ID);
	int time=CMemory::GetTime();
	r->ID=RcdID;
	r->time=time;

	ASSERT(s&&(!s->next));//一个空闲块搞定
	
    //写记录
	db_addr=(db_addr<<32) + PDB(s->uOffset);
	
    cb=CMemory::ReadDBBlock(db_addr);
	
	cb->WriteRecord(r,OFFSET(db_addr));
    
	if(s->uOffset==MAIN_BLOCK&&s->uLarge!=0)//插在文件首,却不是末
	{
		this->start=MAIN_BLOCK;
	}
	if(s->uLarge==0)//这是s为文件尾的标志,而不是s大小真的为0
	{
		this->end+=RcdLength+RECORD_HEAD;
    }

	return TRUE;
}
   
Record *CDatabaseFile::DeleteRecord(PDB db_addr,Relationship *R,bool bRet)//只能由CBlock负责通知CMemory删除记录号
{
	CBlock *cb=CMemory::ReadDBBlock(db_addr);

	BYTE exist=0;

	UINT RcdLength;
	ASSERT(UINT(db_addr>>32)==ID);
	CString filename("");
	filename.Format("D:\\DB\\%d.db",this->ID);
	CFile f(LPCTSTR(filename),CFile::modeReadWrite);
	UINT RecordOff=UINT(db_addr&0xFFFFFFFF);
	f.Seek(RecordOff,CFile::begin);
	f.Read(&RcdLength,sizeof(UINT));

    Space *s=new Space(RecordOff,RECORD_HEAD+RcdLength);
	InsertSpace(s);//可能会改变end或start
	if(!bRet)
		return NULL;
	else
	    return (cb->DeleteRecord(OFFSET(db_addr),R));
}
void CDatabaseFile::InsertSpace(Space *s)
{
	Space *after=sfirst;
	Space *before=NULL;

	if(!sfirst)
		sfirst=slast=s;

	else
	{
		while(after && after->uOffset < (s->uOffset+s->uLarge) )
		{
			before=after;
			after=after->next;
		}
		
	
		if( before&&(before->uOffset+before->uLarge)==s->uOffset )
		{
			before->uLarge=before->uLarge+s->uLarge;
			delete(s);
			s=NULL;//s被前吸收
		}
		else if( after&&(s->uOffset+s->uLarge)==after->uOffset )
		{
			after->uOffset=s->uOffset;
			after->uLarge=after->uLarge+s->uLarge;
			delete(s);
            s=NULL;//s被后吸收
		}
		else
		{
			s->next=after;
			if(sfirst==after)
				sfirst=s;
			if(before)
				before->next=s;
			if(slast==before)
				slast=s;
		}

		if( before&&after&&(before->uOffset+before->uLarge)==after->uOffset)
        {
			ASSERT(!s);
			before->uLarge=before->uLarge+after->uLarge;
			before->next=after->next;
			if(after==slast)
				slast=before;
			delete(after);
		}
	}
		
	if( (slast->uOffset+slast->uLarge)==end)
	{
		end=slast->uOffset;
		DeleteSpace(slast);//???????????????????????????
	}
	if( sfirst&&(sfirst->uOffset==start) )
	{
		start=sfirst->uOffset+sfirst->uLarge;
	}
	if(start>=end)
		start=end=MAIN_BLOCK;
}
	/*		after->uOffset=s->uOffsetafter->uLarge+s->
	}
	while(after->uOffset<(s->uOffset+s->uLarge)) && after->uOffset!=0)
	{
		before=after;
		after=after->next;
	}
	if(s->uOffset==
	if(after->offset==(s->offset+s->large))//完成一部分ResetSpace()的功能
	{
		after->offset=s->offset;
	    after->large=after->large+s->large;
	}
    s->next=after;
	s->prior=after->prior;
	if(after->prior)
	    after->prior->next=s;
	after->prior=s;
	if(after==st)
		st=s;*/

void CDatabaseFile::Close()
{
	CString filename("");
	filename.Format("D:\\DB\\%d.db",ID);
	CFile file(LPCTSTR(filename),CFile::modeReadWrite);
	
	file.Seek(MAGIC,CFile::begin);
	
	//if(strcmp(magic,"IDX"))
		//::AfxThrowFileException(
	file.Write(&ID,sizeof(UINT));
	file.Write(&wBlockNum,sizeof(WORD));
	//Read(&PriorFile,sizeof(UINT));
	file.Write(&end,sizeof(UINT));
	file.Write(&start,sizeof(UINT));
	file.Write(&NextFile,sizeof(UINT));
	
	//写空闲表
	Space *s=sfirst;
	bool stop=0;
	while(!stop)
	{
		if(!s)
		{
			UINT off=0,lar=0;
			file.Write(&off,sizeof(UINT));
			file.Write(&lar,sizeof(UINT));
			stop=1;
		}
		else
		{
		    file.Write(&s->uOffset,sizeof(UINT));
		    file.Write(&s->uLarge,sizeof(UINT));
			file.Seek(s->uOffset,CFile::begin);
			sfirst=sfirst->next;
			if(s==slast)
				slast=NULL;
			delete(s);
			s=sfirst;
		}
	}
}

/*Record CDatabaseFile::UpdateRecord(PDB db_addr, CUpdate up,Relationship *R)
{
    CBlock *cb=CMemory::ReadDBBlock(db_addr);
	ASSERT(UINT(db_addr>>32)==ID);
	return (cb->UpdateRecord(OFFSET(db_addr),up,R));
}*/

⌨️ 快捷键说明

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