📄 db.cpp
字号:
#include <string>
using namespace std;
#include <iostream>
#include <fstream>
#include <stdio.h>
#include "DBT.h"
#include "DB.h"
DB::DB()
{
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//// DB(string& db_name)
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
DB::DB(string& db_name)
{ //initialte parameters indexname,dbname,pagesize,metapage;
index_name=db_name;
index_name+="_index";
dbname=db_name;
pagesize=100;//数据库块大小,8KB// pagesize here may have a change;
metapage=0;//数据库首页号
if(fopen(dbname.data(),"rw")==NULL)//judge the file exist or not
{
//if
///////////If the file exist,create data file and indexfile and initiate related parameter
cout<<"the fiel doesn't exist ,we are builtint it ^^^^^"<<endl;
//initial parameters and write them to indexfile
pageno=1;
for(int i=0;i<10;i++) //total pageno may have a change
pagecondition[i]=pagesize;
pagecondition[7]=pageno;//store pageno;
pagecondition[8]=0;//store my_key block;
pagecondition[9]=0;//store my_key offset;
// pagecondition[10]=pagesize store space of index
string temp="";
my_key=temp;
my_data=temp;
mykeyoffset=0;
mykeyblock=0;
////////////////////////////////////////write data to buff/////////////////////////////////////////////////
memcpy(buff,pagecondition,40);
memcpy(&buff[40],(char*)my_key,my_key.totalsize());
memcpy(&buff[40+my_key.totalsize()],(char*)my_data,my_data.totalsize());
//////////////////////////////////////////////////////////////////////////////////////////////////
//create datafile
ofstream inout(dbname.data(),ios::binary|ios::out);
if(!inout)
cout<<"sorry,not created datafile "<<endl;
else
cout<<"created datafile success! "<<db_name<<endl;
//close datafile
inout.close();
//create indexfile and write data
ofstream indexout(index_name.data(),ios::binary|ios::out);
if(!indexout)
cout<<"sorry,not created index file"<<endl;
else
{
cout<<"created success "<<index_name<<" index file !! "<<endl<<endl;
indexout.write(buff,pagesize);
}
// close indexfile
indexout.close();
}
else
{
//else////////////////////////////////
cout<<"the data file exists !"<<endl;
//open index_file and read the initial data to buff ,file is closed
fstream inout(index_name.data(),ios::binary|ios::in|ios::out);
inout.seekg(0,ios::beg);
inout.read(buff,pagesize);
inout.read(indexbuff,pagesize);
inout.close();
//buff of char type convert to the type you want;
/////////////////////////covert buff to data structure/////////////////////////////////////
memcpy(&pagecondition[0],&buff[0],40);// read pagecondition
//read my_key
int mysize;
memcpy(&mysize,&buff[40],4);
string youwant,temp="";
for(int i=0;i<mysize;i++)
{
temp=buff[44+i];
youwant+=temp;
}
my_key=youwant;
//read my_data
youwant="";
memcpy(&mysize,&buff[44+i],4);
int pos=44+i+4;// keep i
for( i=0;i<mysize;i++)
{
temp=buff[pos+i];
youwant+=temp;
}
my_data=youwant;
youwant="";
pageno=pagecondition[7];
mykeyblock=pagecondition[8];
mykeyoffset=pagecondition[9];
}
///////////////////////////////////////////////////////////////////////////////////////////////
//check code check code check code
// for(int i=0;i<=9;i++)
// {
// cout<<pagecondition[i]<<" ";
// }
// cout<<my_key<<" "<<my_data<<endl<<pageno<<mykeyblock<<mykeyoffset<<endl<<endl<<endl;
//close the database
db_close();
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// db_fetch(DBT& key)
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
DBT DB::db_fetch(DBT& key)
{
//define the tempotary varible which we will use later
int mykeysize;
int mydatasize;
string youwant,temp="";
// open the file
fstream inout(dbname.data(),ios::binary|ios::in|ios::out);
//find the key
for(int i=0;i<pageno;i++)// search key from different block
{
inout.seekg(i*pagesize,ios::beg);
inout.read(buff,pagesize);
for(int j=0;j<pagesize-pagecondition[i];j++)//search key from one block
{
youwant="";
memcpy(&mykeysize,&buff[j],4);
memcpy(&mydatasize,&buff[j+4+mykeysize],4);
for(int k=0;k<mykeysize;k++)// get one key from the buff
{
temp=buff[j+4+k];
youwant+=temp;
}
if (youwant==key.getstring())//compare the key you get to key
{ j+=key.totalsize();
youwant="";
for(int k=0;k<mydatasize;k++)// get the data about the key
{
temp=buff[j+4+k];
youwant+=temp;
}
//////////// change the attribute of DB
my_key=key;
my_data=youwant;
pagecondition[8]=mykeyblock=i;
pagecondition[9]=mykeyoffset=j-key.totalsize();
////////////
cout<<"fetch "<<key<<" success!"<<endl;
cout<<key<<" "<<my_data<<endl<<endl;
inout.close();
db_close();
//check node check
// for(int i=0;i<=10;i++)
//{
// cout<<pagecondition[i]<<" ";
// }
//for(i=0;i<=pagesize;i++)
//cout<<buff[i];
cout<<endl<<endl;
//////////check node
return my_data;
}
else
j+=8+mykeysize+mydatasize-1;// the next key pos substract 1
}
}
inout.close();
cout<<"don't find "<<key<<endl<<endl;
return key;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////
/// db_store(DBT& key,DBT& data,int flag)
//////////////////////////////////////////////////////////////////////////////////////////////////////////
int DB::db_store(DBT& key,DBT& data,int flag)
{ //find the key first
//define the tempotary varible which we will use later
int mykeysize;
int mydatasize;
string youwant,temp="";
// open the file
fstream inout(dbname.data(),ios::binary|ios::in|ios::out);
//find the key
for(int i=0;i<pageno;i++)// search key from different block
{
inout.seekg(i*pagesize,ios::beg);
inout.read(buff,pagesize);
for(int j=0;j<pagesize-pagecondition[i];j++)//search key from one block
{
youwant="";
memcpy(&mykeysize,&buff[j],4);
memcpy(&mydatasize,&buff[j+4+mykeysize],4);
for(int k=0;k<mykeysize;k++)//get one key from the buff
{
temp=buff[j+4+k];
youwant+=temp;
}
if (youwant==key.getstring())//comparee two keys,if equal ,take related action
{
j+=key.totalsize();
youwant="";
for(int k=0;k<mydatasize;k++)//get the data of the key
{
temp=buff[j+4+k];
youwant+=temp;
}
//////////// change the attribute of DB
my_key=key;
my_data=youwant;
pagecondition[8]=mykeyblock=i;
pagecondition[9]=mykeyoffset=j-key.totalsize();
////////////out put to screen
cout<<"we find the same key "<<key<<" !"<<endl;
cout<<key<<" "<<my_data<<endl;
////////////////flag==1,can't replace!
if(flag==1)
{ inout.close();
db_close();
cout<<"but you cant't replace it!"<<endl<<endl<<endl;
return 0;
}
// recover
for(k=j-key.totalsize();k<(pagesize-pagecondition[i]);k++)// delete the key,move data ahead
buff[k]=buff[k+key.totalsize()+youwant.size()+4];
inout.seekp(i*pagesize,ios::beg);
inout.write(buff,pagesize);// write data to disk
pagecondition[i]+=key.totalsize()+youwant.size()+4;//change pagecondition
cout<<"we replace the same key!"<<endl;
break;
}//if end
else
j+=8+mykeysize+mydatasize-1;
}//end for j
}// end for i
inout.close();
// change attribute of the class
my_key=key;
my_data=data;
//find the block you want to store
int j=0;//j is the block you want to store
while((key.totalsize()+data.totalsize())>pagecondition[j]&&j<pageno) j++;
if(j==pageno)
pageno++;//change attribute of the class
mykeyblock=j; //change attribute of the class
mykeyoffset=pagesize-pagecondition[j];//change attribute of the class
// write key and data to the block;
fstream in(dbname.data(),ios::binary|ios::in|ios::out);
in.seekp((j)*pagesize+pagesize-pagecondition[j],ios::beg);
in.write((char*)key,key.totalsize());
in.write((char*)data,data.totalsize());
in.close();
cout<<key<<" has been stored successfully!"<<endl;
pagecondition[j]-=(key.totalsize()+data.totalsize());//store data ,so change the pagecondition
pagecondition[7]=pageno;//store pageno;
pagecondition[8]=mykeyblock;//store my_key block;
pagecondition[9]=mykeyoffset;//store my_key offset;
//check node check
// for( i=0;i<=9;i++)
// {
// cout<<pagecondition[i]<<" ";
// }
cout<<endl<<endl;
// db_createindex(key,j);
//close the database
db_close();
return mykeyblock;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/// db_delete(DBT& key)
/////////////////////////////////////////////////////////////////////////////////////////////////////////
int DB::db_delete(DBT& key)
{
//define the tempotary varible which we will use later
int mykeysize;
int mydatasize;
string youwant,temp="";
// open the file
fstream inout(dbname.data(),ios::binary|ios::in|ios::out);
//find the key
for(int i=0;i<pageno;i++)// search key from different block
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -