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

📄 relationship.cpp

📁 有计算机图形学、图像处理、dbms、sniffer、中游俄罗斯外挂、othello、遗传算法、舌苔分析等程序。
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			KEY k(any1);
			if(R2->at[AttrNo2].idx)
			{
				CBlock *pblk=NULL;
				CResult res=R2->at[AttrNo2].tree->SearchBTree(k);
				if(R2->at[AttrNo2].unq)
				{
					if(res.success)
					{
						R2->enddb=1;
						pblk=CMemory::ReadDBBlock(res.recptr);
						rcd2=pblk->ReadRecord(OFFSET(res.recptr),R2);//!!!!!!!!
						combine=(*rcd1)+(*rcd2);
						delete rcd2;
						con_success=true;
					}
				}
				else
				{
					if(R2->enddb==1)
					{   //超级冗余
					    CBuffer *buffer=R2->at[AttrNo2].tree->SearchAll(k,&res,TRUE);//允许重复//??
                        R2->SetCurBuffer(buffer);
						R2->Reset();
					}
					rcd2=R2->NextRecord(true);//根据buffer读
					if(rcd2)
					{
						combine=(*rcd1)+(*rcd2);
						delete rcd2;
						con_success=true;
					}
				}
			}
			else//R2响应字段未建索引
			{
				if(R2->enddb==1)
				{
					R2->Reset();
					R2->enddb=0;
				}
				rcd2=R2->NextRecord(false);//不根据buffer读
				if(rcd2)
				{
					ANY any2=rcd2->AttrToValue(AttrNo2);
					switch(cmp)
					{
					case 0:
						{
							if(any1==any2)
							{
							    combine=(*rcd1)+(*rcd2);
								con_success=true;
							}
							break;
						}
					case 1:
						{
							if(any1<any2)
							{
								combine=(*rcd1)+(*rcd2);
								con_success=true;
							}
							break;
						}
					case 2:
						{
							if(any1>any2)
							{
								combine=(*rcd1)+(*rcd2);
								con_success=true;
							}
							break;
						}
					}
					delete rcd2;
				}
			}
		}
		else
		{
			delete R2->buffer;
			R2->buffer=NULL;
		}
	}
	while(rcd1 && !con_success);
	return combine;
}

void Relationship::SetCurBuffer(CBuffer *buffer)
{
	if(this->buffer!=buffer)
	    delete (this->buffer);
	this->buffer=buffer;
}

UINT Relationship::GetRecordLength()
{
	WORD i;
	UINT length=0;

	for(i=1;i<=attr_num;i++)
	{
		
		if(at[i].type==CHAR_TYPE)
			length+=(at[i].length+1);
		else if(at[i].type==VARCHAR_TYPE)
			length+=(at[i].length+2);
		else
			length+=at[i].length;
		
	}
	return length;
}
Record * Relationship::NextUnion(CHashTable &HashTable,Relationship *R2
								 ,BYTE *mask1,BYTE *mask2,
								 BOOL distinct,CBuffer *buf1,CBuffer *buf2)
{
	Record *Ret=NULL;
    Record *Src=NULL;
	do
	{
		delete Ret;
		Ret=NULL;
		if(buf1)
		{
			Src=NextRecord(true);
			if(Src)
		        Ret=Src->Shadow(mask1);//按buffer读
			delete Src;
		}
		else
		{
			Src=NextRecord(false);
			if(Src)
			    Ret=Src->Shadow(mask1);//不按buffer读
			delete Src;
		}
		if(Ret && HashTable.InsertRecord(Ret,!distinct)==TRUE)
			return Ret;
	}
	while(Ret);
    //并R2
	do
	{
		delete Ret;
		Ret=NULL;
		if(buf2)
		{
			Src=R2->NextRecord(true);
			if(Src)
				Ret=Src->Shadow(mask2);//按buffer读
			delete Src;
		}
		else
		{
			Src=R2->NextRecord(false);
			if(Src)
				Ret=Src->Shadow(mask2);//不按buffer读
			delete Src;
		}
		if(Ret && HashTable.InsertRecord(Ret,!distinct)==TRUE)
			return Ret;
	}
	while(Ret);
	
	return NULL;
}
	
//将所有记录插入索引
void Relationship::AutoIndex(WORD AttrNo)
{
	Record *rcd=NULL;
    KEY k;
    CResult res;
    
	BTNODE *CurNode1=CurNode;
	UINT CurNo1=CurNo;
	PDB CurDbPtr1=CurDbPtr;
	BYTE enddb1=enddb;
	Reset();
	enddb=0;
   
	while(enddb==0)
	{
        rcd=NextRecord(false);
		if(rcd)
		{
			k=rcd->AttrToKey(AttrNo);
			res=at[AttrNo].tree->SearchBTree(k);
			at[AttrNo].tree->InsertBTree(k,CurDbPtr,res.pdbNode,res.pos);
		}
	}
	CurNode=CurNode1;
	CurNo=CurNo1;
	CurDbPtr=CurDbPtr1;
	enddb=enddb1;
}

BOOL Relationship::InsertRecord(Record *rcd)
{
    BOOL should=TRUE;

	PDB recptr=DB_NULL;
		
	CResult *res=NULL;
	KEY *k=NULL;
	if(idx_num>0)
	{
		res=new CResult[attr_num+1];
		k=new KEY[attr_num+1];
	}
	
	should=CheckRcdKey(res,k,rcd);
	if(should)
		should=CheckRcdKey(rcd);//慢扫描
	if(should)
	{
		CDatabaseFile *cdbf=CMemory::GetFile(DataFileNo);
		recptr=cdbf->Allocate(rcd,this);

		//记录ID插入B+树
		KEY kid(0,rcd->ID);
		CResult res_id=tree->SearchBTree(kid);
		ASSERT(!(res_id.success));
		tree->InsertBTree(kid,recptr,res_id.pdbNode,res_id.pos);
		//所有已建索引的B+树插入新键
		for(WORD i=1;i<=attr_num;++i)
		{
			if(at[i].idx)
			{
				at[i].tree->InsertBTree(k[i],recptr,res[i].pdbNode,res[i].pos);
			}
		}
	}
	else
	{
		AfxMessageBox("Dup Key");
	}
	
	delete []k;
	delete []res;
	//delete rcd;
}

void Relationship::DeleteRecord(CBuffer *buffer)
{
    //对于重复键,!(res.success)并不代表没有存在的记录
	CString sss;//debug
	
    BTNODE *CurNode1=CurNode;
	UINT CurNo1=CurNo;
	PDB CurDbPtr1=CurDbPtr;
	BYTE enddb1=enddb;
	Reset();
	enddb=0;
	//用于删除键值
	ANY any;
	KEY dk;
	CResult dres;
	Record *deleted=NULL;
	while(!enddb)
	{
		deleted=NextFitDelete(buffer);//不根据范式???
		if(deleted)
		{
			//删除B+树中的记录ID
			dk=KEY(0,deleted->ID);
			dres=tree->SearchBTree(dk);
			ASSERT(dres.success);
			tree->DeletePtr(dk,dres.pdbNode,dres.pos);
			//删除所有已建的键值
			for(WORD j=1;j<=UINT(attr_num);j++)
			{
				if(at[j].idx)
				{
					any=deleted->AttrToValue(j);
					dk=KEY(any);
					dres=at[j].tree->SearchBTree(dk);//应该都能找到
					ASSERT(at[j].unq&&dres.success||!(at[j].unq));
					if(at[j].unq==1)
						at[j].tree->DeletePtr(dk,dres.pdbNode,dres.pos);//删除旧键
					else
						at[j].tree->DeletePtr(dk,dres.pdbNode,dres.recptr
						,CurDbPtr);//删除Dup旧键
				}
			}
		}
		delete deleted;
	}
    
	CurNode=CurNode1;
	CurNo=CurNo1;
	CurDbPtr=CurDbPtr1;
	enddb=enddb1;
}

CBuffer * Relationship::SelectRecord(CNormalForm &form)
{
	CBuffer *res_buf=new CBuffer(300,300);
    Record *rcd=NULL;
	
	BTNODE *CurNode1=CurNode;
	UINT CurNo1=CurNo;
	PDB CurDbPtr1=CurDbPtr;
	BYTE enddb1=enddb;
	Reset();
	enddb=0;/////////////////////////////////////////////////////////

	CNormalForm ApForm;
	Split(form,ApForm);//改变Form和ApForm
	CBuffer *buffer=SelectByIndex(ApForm);
	
    //CViewData view;
	//WORD OrderAttrNo=0;
	//CMergeTree mtree;
	//ANY any;
	//KEY k;
	//Result res;
	UINT ii=0;//////////////////////////调试
	UINT Count=0;
    
	do
	{
		rcd=SelectNext(form,buffer);//此时form全是不能用索引的条件
		if(rcd)
            res_buf->Append(CurDbPtr);
		ii++;
		
		delete rcd;
	}
	while(rcd);
    
	CurNode=CurNode1;
	CurNo=CurNo1;
	CurDbPtr=CurDbPtr1;
	enddb=enddb1;

	return res_buf;
}
//返回的ApForm是建过索引的
void Relationship::Split(CNormalForm &Form,CNormalForm &ApForm)
{
    UINT i;
	CCondition *condition=NULL;
	for(i=0;i<Form.Count;i++)
	{
		condition=new CCondition(Form[i]);
        if(condition->AttrNo2==0 && at[condition->AttrNo1].idx==1)
			//没有第二字段且第一字段建过索引
		{
			if(condition->xkey.type!=CHAR_TYPE || condition->xflag==2)
            {
				Form.DeleteCondition(i);
                ApForm.InsertCondition(condition);
			}
			else
			{
				delete condition;
			}
		}
		else
		{
			delete condition;
		}
	}
}

void Relationship::Display(CBuffer *buffer,CString *shd,WORD OrderAttrNo,bool bDistinct
						   ,CListCtrl &List)
{
    WORD i,j=0;
    UINT Count=0;
	BTNODE *CurNode1=CurNode;
	UINT CurNo1=CurNo;
	PDB CurDbPtr1=CurDbPtr;
	BYTE enddb1=enddb;
	Reset();
	enddb=0;/////////////////////////////////////////////////////////
    SetCurBuffer(buffer);

	while(List.DeleteColumn(0)==TRUE);

	Record *rcd;
	Record *src_rcd;
	BYTE *mask=new BYTE[attr_num+1];
	::memset(mask,0,attr_num+1);
	for(i=1;i<=attr_num;i++)
	{
		if(shd[i]!="")//非空
		{
            List.InsertColumn(j,LPCTSTR(shd[i]),LVCFMT_CENTER,80);
			mask[i]=1;
			j++;
		}
	}

	CMergeTree mtree;
	if(OrderAttrNo!=0)
	{
		//创建的新临时文件覆盖原来文件
		CIndexFile f("D:\\DB\\4.index",CFile::modeCreate
			|CFile::modeReadWrite,4);
		mtree=CMergeTree(1-at[OrderAttrNo].unq,at[OrderAttrNo].type,1,4);
	}
	BOOL NoDup=TRUE;
	CHashTable HashTable;
	if(bDistinct)//要消除重复
	{
		UINT HashID=CMemory::GetHashFileID();
	    UINT RcdLen=GetRecordLength();
	    HashTable=CHashTable(RcdLen,HashID);
	}

	do
	{
		src_rcd=NextRecord(true);//按Buffer读
		if(src_rcd)
		    rcd=src_rcd->Shadow(mask,NULL,NULL);///////////////////////////////////////!!!
		else
			rcd=NULL;
		if(rcd)
		{
			if(bDistinct)
			    NoDup=HashTable.InsertRecord(rcd,false);//不允许重复
			if(NoDup)
			{
				if(OrderAttrNo==0)//不需排序
					rcd->Draw(Count++,List,NULL,NULL,mask);
				else
				{
					KEY key=rcd->AttrToKey(OrderAttrNo);
					CResult res=mtree.SearchBTree(key);
					mtree.InsertBTree(key,CurDbPtr,res.pdbNode,res.pos);
				}
			}
		}
		delete rcd;
	}
	while(rcd);
	if(OrderAttrNo!=0)//需要排序
	{
		Reset();
		enddb=0;
		CurNode=mtree.m_sqt;
		do
		{
			rcd=NextRecord(false);
            if(rcd)
			{
				rcd->Draw(Count++,List,NULL,NULL,mask);
			}
			delete rcd;
		}
		while(rcd);
	}
	CurNode=CurNode1;
	CurNo=CurNo1;
	CurDbPtr=CurDbPtr1;
	enddb=enddb1;
	CMemory::DestroyHashTable();
}

//B树主文件                       
                                
//UINT	ID
//BYTE  DUP
//BYTE	KeyType
//BYTE	KeyNum
//WORD  KeyLength
//WORD 	M 
//PDB	ROOT
//PDB	SQT 
//unsigned int m_uiKeyCount;
//unsigned int m_uiEffectKey;
//UINT  currentFile//当前文件号
//复合索引1,复合索引2,复合索引3........
BOOL Relationship::CreateIndex(CString AttrName)
{
	WORD AttrNo=0;
	if(AttrName!="")
	{
		AttrNo=AttrNameToAttrNo(AttrName);
		if(AttrNo==0)
		{
			AfxMessageBox("wrong attribute");
			return FALSE;
		}
	}
    
	BYTE KeyType,KeyNum=1;//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!KeyNum恒等于1
	WORD KeyLength;
	if(AttrName=="")
	{
		KeyType=UINT_TYPE;
		KeyLength=4;

		BOOL Dup=0;
		UINT IndexMainID=CMemory::AllocateID(FILE_ID);
		UINT IndexID=CMemory::AllocateID(FILE_ID);
		
		IndexMainFile=IndexMainID;
        tree=new CBplusTree(IndexMainID,Dup,KeyType,KeyNum,KeyLength,IndexID);

		CString s;
		s.Format("D:\\DB\\%d.mdx",IndexMainID);
		
		CFile f(LPCTSTR(s),CFile::modeCreate);//主文件
		f.Close();

	    s.Format("D:\\DB\\%d.index",IndexID);
		CIndexFile cidxf(LPCTSTR(s),CFile::modeCreate|CFile::modeNoTruncate|CFile::modeReadWrite
			,IndexID);
	}
	else
	{
		switch(at[AttrNo].type)
		{
		case INT_TYPE:
		case FLOAT_TYPE:
			KeyType=at[AttrNo].type;
			KeyLength=4;
			break;
		case CHAR_TYPE:
		case VARCHAR_TYPE:
			KeyType=CHAR_TYPE;
			KeyLength=KEY_LENGTH;////////////////////////////////////////////////////////////!!!!!!!!!!!!!!!!!!
			break;
		case TIME_TYPE:
			KeyType=TIME_TYPE;
			KeyLength=4;///////////////////////////////////////////////////BYTE [4]
			break;
		case DATE_TYPE:
			KeyType=DATE_TYPE;
			KeyLength=8;//////////////////////////////////////////////////WORD [8]
			break;
		default:
			ASSERT(0);
		}
		if(at[AttrNo].idx!=1)
		{
			idx_num++;
			at[AttrNo].idx=1;
			wtag=1;
			BOOL Dup=BOOL(1-at[AttrNo].unq);
			UINT IndexMainID=CMemory::AllocateID(FILE_ID);
			UINT IndexID=CMemory::AllocateID(FILE_ID);
			
			at[AttrNo].SetIndex(IndexMainID);
			at[AttrNo].tree=new CBplusTree(IndexMainID,Dup,KeyType,KeyNum,KeyLength,IndexID);

			CString s;
			s.Format("D:\\DB\\%d.mdx",IndexMainID);
			
			CFile f(LPCTSTR(s),CFile::modeCreate);//主文件
			f.Close();

			s.Format("D:\\DB\\%d.index",IndexID);
			CIndexFile cidxf(LPCTSTR(s),CFile::modeCreate|CFile::modeReadWrite
				,IndexID);
			/////////////////the bug is killed at 9.14,
			//cidxf析构时会将错误的数值0,覆盖正确的数值
			cidxf.Close();
			this->AutoIndex(AttrNo);
		}
	}
    return TRUE;
}

BOOL Relationship::CreateMulIndex(CString AttrName1, CString AttrName2, BOOL Dup)
{
	WORD AttrNo1=AttrNameToAttrNo(AttrName1);
	WORD AttrNo2=AttrNameToAttrNo(AttrName2);
    if(AttrNo1>0 && AttrNo2>0)
	{
		CMultiIdx multi(Dup,AttrNo1,AttrNo2);
		CreateIndex(AttrNo1);
		CreateIndex(AttrNo2);
		AddMultiIdx(multi);//大错!!!!!!!!!!!!!!!!!!!!!!!
	    return TRUE;
	}
	return FALSE;
}

void Relationship::CreateIndex(WORD AttrNo)
{
    BYTE KeyType,KeyNum=1;//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!KeyNum恒等于1
	WORD KeyLength;
	if(AttrNo==0)
	{
		KeyType=UINT_TYPE;
		KeyLength=4;

		BOOL Dup=0;
		UINT IndexMainID=CMemory::AllocateID(FILE_ID);
		UINT IndexID=CMemory::AllocateID(FILE_ID);
		
		IndexMainFile=IndexMainID;
        tree=new CBplusTree(IndexMainID,Dup,KeyType,KeyNum,KeyLength,IndexID);

		CString s;
		s.Format("D:\\DB\\%d.mdx",IndexMainID);
		
		CFile f(LPCTSTR(s),CFile::modeCreate);//主文件
		f.Close();

	    s.Format("D:\\DB\\%d.index",IndexID);
		CIndexFile cidxf(LPCTSTR(s),CFile::modeCreate|CFile::modeNoTruncate|CFile::modeReadWrite
			,IndexID);
	}
	else
	{
		switch(at[AttrNo].type)
		{
		case INT_TYPE:
		case FLOAT_TYPE:
			KeyType=at[AttrNo].type;
			KeyLength=4;
			break;
		case CHAR_TYPE:
		case VARCHAR_TYPE:
			KeyType=CHAR_TYPE;
			KeyLength=KEY_LENGTH;////////////////////////////////////////////////////////////!!!!!!!!!!!!!!!!!!
			break;
		case TIME_TYPE:
			KeyType=TIME_TYPE;
			KeyLength=4;///////////////////////////////////////////////////BYTE [4]
			break;
		case DATE_TYPE:
			KeyType=DATE_TYPE;
			KeyLength=8;//////////////////////////////////////////////////WORD [8]
			break;
		default:
			ASSERT(0);
		}
		if(at[AttrNo].idx!=1)
		{
			idx_num++;
			at[AttrNo].idx=1;
			wtag=1;
			BOOL Dup=BOOL(1-at[AttrNo].unq);
			UINT IndexMainID=CMemory::AllocateID(FILE_ID);
			UINT IndexID=CMemory::AllocateID(FILE_ID);
			
			at[AttrNo].SetIndex(IndexMainID);
			at[AttrNo].tree=new CBplusTree(IndexMainID,Dup,KeyType,KeyNum,KeyLength,IndexID);

			CString s;
			s.Format("D:\\DB\\%d.mdx",IndexMainID);
			
			CFile f(LPCTSTR(s),CFile::modeCreate);//主文件
			f.Close();

			s.Format("D:\\DB\\%d.index",IndexID);
			CIndexFile cidxf(LPCTSTR(s),CFile::modeCreate|CFile::modeReadWrite
				,IndexID);
			/////////////////the bug is killed at 9.14,
			//cidxf析构时会将错误的数值0,覆盖正确的数值
			cidxf.Close();
			this->AutoIndex(AttrNo);
		}
	}
}

BOOL Relationship::CheckUpdateData(CUpdate &update)
{
	BOOL correct=TRUE;
    for(WORD i=0;i<update.current && correct;i++)
	{
		WORD No=update.up_itms[i].index;//被修改的字段,同CupAttrNo
		CString value=update.up_itms[i].value;
		switch(at[No].type)
		{
        case INT_TYPE:
			{
				int ival=0;
			    correct=CMemory::ATOI(value,ival);
			}
			break;
		case FLOAT_TYPE:
			{
				float fval=0;
                correct=CMemory::ATOF(value,fval);
			}
			break;
		case TIME_TYPE:
			{
                
				Time t;
				correct=CMemory::ATOTime(value,t);
			}
			break;
		case DATE_TYPE:
			{
				Date d;
				correct=CMemory::ATODate(value,d);
			}
			break;
		default:
			break;
		}
	}
	return correct;
}

⌨️ 快捷键说明

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