📄 ljfiledb.cpp
字号:
int_16 buflen = CacKeyv(buf,whereExpress);
if( buflen != db->IndexTable._idsz1-1 ){
delete []buf;
return db->_err = ER_FIELDISNOTEXIST;
}
db->IndexTable.ResetBlock(buf);
delete []buf;
db->_err = ER_NOERROR;
return 1;
}
void CRecordSet::Serialize(char* buf,TRecord& record){
int p=0;
memset(buf,0,_rdsz1);
vector<char*>::iterator iter = record._values.begin();
for(int i=0;iter!=record._values.end();++iter,++i){
TField field = db->FieldSet[i];
char* val = (char*)*iter;
if( field._ft == 0 ){
strcpy(buf+p,val);
}else{
int* t = (int*)(buf+p);
*t = atoi(val);
}
p+=field._fsz;
}
}
void CRecordSet::Structuralize(char* buf,TRecord& record){
int p = 0;
char* tbuf;
for(int i=0;i<db->FieldSet.Count();++i){
if( db->FieldSet[i]._ft == FT_INT4 ){
int* t = (int*)(buf+p);
char nbuf[20]={0};
itoa(*t,nbuf,10);
tbuf = strdup(nbuf);
}else{
//此处进行了优化,按实际的字符串长度分配空间,而不是按照字段长度分配.
char* sbuf = new char[db->FieldSet[i]._fsz+1];
memset(sbuf,0,db->FieldSet[i]._fsz+1);
memcpy(sbuf,buf+p,db->FieldSet[i]._fsz);
tbuf = strdup(sbuf);
delete []sbuf;
}
record._values.push_back(tbuf);
p += db->FieldSet[i]._fsz;
}
}
int_16 CRecordSet::CacKeyv(char* keyv,TWHEREEXPRESS whereExpress){
int_16 bufoff=0;
for(int i=0;i<db->FieldSet.Count();++i){
if( db->FieldSet[i]._key != FT_KEY )
continue;
TWHEREEXPRESS::iterator iter = whereExpress.begin();
for(;iter!=whereExpress.end();++iter){
TWHERE where = *iter;
if( strcmp(db->FieldSet[i]._fn,where.fn) == 0 ){
if( db->FieldSet[i]._ft == FT_STR ){
strcpy(keyv+bufoff,where.val);
}else if( db->FieldSet[i]._ft == FT_INT4){
int* p = (int*)(keyv+bufoff);
*p = atoi(where.val);
}
bufoff+=db->FieldSet[i]._fsz;
}
}
}
return bufoff;
}
int_16 CRecordSet::Update(TWHEREEXPRESS whereExpress,TWHEREEXPRESS valSet){
Select(whereExpress);
if( Count() == 0 ){
return db->_err;
}
char* okey = new char[db->IndexTable._idsz1-1];
memset(okey,0,db->IndexTable._idsz1-1);
CacKeyv(okey,whereExpress);
char* nkey = new char[db->IndexTable._idsz1-1];
memcpy(nkey,okey,db->IndexTable._idsz1-1);
char* buf = new char[_rdsz1];
Serialize(buf,_records[0]);
int p=0;int idp=0;
for(int i=0;i<db->FieldSet.Count();++i){
TWHEREEXPRESS::iterator iter = valSet.begin();
for(;iter!=valSet.end();++iter){
if( strcmp( db->FieldSet[i]._fn,(*iter).fn) == 0 ){
break;
}
}
if( iter!= valSet.end()){//修改
if( db->FieldSet[i]._ft == FT_STR ){
strcpy(buf+p,(*iter).val);
}else{
int* t = (int*)(buf+p);
*t = atoi((*iter).val);
}
if( db->FieldSet[i]._key == FT_KEY ){//修改索引
if( db->FieldSet[i]._ft == FT_STR ){
strcpy(nkey+idp,(*iter).val);
}else{
int* t = (int*)(nkey+idp);
*t = atoi((*iter).val);
}
}
}
if( db->FieldSet[i]._key == FT_KEY){
idp += db->FieldSet[i]._fsz;
}
p+=db->FieldSet[i]._fsz;
}
// TRACE("write record \n");
fseek(db->file,_bp+_records[0]._no*_rdsz1,SEEK_SET);
fwrite(buf,1,_rdsz1,db->file);
// TRACE("write record ok\n");
//Structuralize(buf,_records[0]);
db->IndexTable.SetBlock(okey,nkey);
delete []okey;
delete []buf;
return db->_err = ER_NOERROR;
}
CIndexTable::CIndexTable(){
_idsz1 = 1; //注意:索引下标从1开始
_bp = 0;
}
void CIndexTable::Free(){
map<INDEX,int_16>::iterator iter = _usedit.begin();
for(;iter!=_usedit.end();++iter){
delete []iter->first._val;
}
_usedit.clear();
_unusedit.clear();
_idsz1 = 1;
}
int CIndexTable::GetFrontAvBlock(){
return _unusedit.front()-1;
}
void CIndexTable::AllocBlock(int i,char* keyv){
_unusedit.erase(&_unusedit.front());
fseek(db->file,_bp+i*_idsz1,SEEK_SET); //写占用位
char buf[1]={1};
fwrite(buf,1,1,db->file);
fwrite(keyv,1,_idsz1-1,db->file); //写索引值
INDEX index;
index._val = keyv;
index._sz = _idsz1-1;
_usedit[index] = i+1;
}
void CIndexTable::ResetBlock(char* keyv){
int_32 p = Find(keyv);
fseek(db->file,_bp+p*_idsz1,SEEK_SET);
char buf[1]={0};
fwrite(buf,1,1,db->file);
_unusedit.push_back(p);
INDEX index;
index._sz = _idsz1-1;
index._val=new char[_idsz1-1];
memset(index._val,0,_idsz1-1);
memcpy(index._val,keyv,_idsz1-1);
_usedit.erase(index);
delete []index._val;
}
void CIndexTable::SetBlock(char* okey,char* nkey){
int_32 idpos = Find(okey);
INDEX index;
index._val = okey;
index._sz = _idsz1-1;
// TRACE("delete index\n");
char* t=NULL;
map<INDEX,int_16>::iterator iter = _usedit.find(index);
if( iter != _usedit.end() ){
INDEX oindex = iter->first;
t = oindex._val;
}
_usedit.erase(index);
if( t )
delete []t;
// TRACE("delete index ok\n");
fseek(db->file,_bp+idpos*_idsz1+1,SEEK_SET);
fwrite(nkey,1,_idsz1-1,db->file);
index._val = nkey;
index._sz = _idsz1-1;
_usedit[index] = idpos+1;
// TRACE("set index ok\n");
}
void CIndexTable::Load(){
char* buf = new char[_idsz1];
fseek(db->file,_bp,SEEK_SET);
INDEX index;
index._sz = _idsz1-1;
for(int i=0;i<MAXRECORDCOUNT;++i){
memset(buf,0,_idsz1);
fread(buf,1,_idsz1,db->file);
if( buf[0] == 1){//占用块
index._val = new char[_idsz1-1];
memcpy(index._val,buf+1,_idsz1-1);
_usedit[index] = i+1;//注意,索引下标从1开始,因为在查map的时候,若没有找到返回的是0,所以不能从0开始
}else{ //空闲块
_unusedit.push_back(i+1);
}
}
delete []buf;
}
int_16 CIndexTable::Find(char* key){
int ret = -1;
INDEX index;
index._sz = _idsz1-1;
index._val=new char[_idsz1-1];
memset(index._val,0,_idsz1-1);
memcpy(index._val,key,_idsz1-1);
map<INDEX,int_16>::iterator iter = _usedit.find(index);
if( iter != _usedit.end() )
ret = (int)(*iter).second - 1;
//if( _usedit[index] != NULL )
// ret = _usedit[index]-1;
delete []index._val;
return ret;
}
CFileDB::CFileDB(){
Head.db = this;
FieldSet.db = this;
RecordSet.db = this;
IndexTable.db = this;
_stat = ST_CLOS;
}
CFileDB::~CFileDB(){
if( _stat != ST_CLOS ){
Clos();
}
}
int_32 CFileDB::Create(char* fn){
if( _stat != ST_CLOS)
return _err = ER_ERROR;
file = fopen(fn,"wb+");
if( file == NULL ){
return _err = ER_FILEOPENER;
}
this->fn = strdup(fn);
Head.write();
FieldSet._bp = 3;
_stat = ST_CREA;
return _err = ER_NOERROR;
}
int_32 CFileDB::Open(char* fn){
if( _stat != ST_CLOS ){
return _err = ER_DBOPENED;
}
file = fopen(fn,"rb+");
if( file == NULL ){
return _err = ER_FILEOPENER;
}
this->fn = strdup(fn);
Head.read();
FieldSet._bp = THEADSIZE;
FieldSet._ct = Head._fc;
FieldSet.Load();
IndexTable._bp = FieldSet._bp+FieldSet.Count()*TFIELDSZ;
IndexTable.Load();
RecordSet._bp = IndexTable._bp+MAXRECORDCOUNT*IndexTable._idsz1;
RecordSet._act = Head._rc;
_stat = ST_OPEN;
return _err = ER_NOERROR;
}
void CFileDB::Clos(){
if( _stat == ST_CLOS )
return;
Head.Free();
FieldSet.Free();
RecordSet.Free();
IndexTable.Free();
fclose(file);
//delete []fn;
free(fn);
_stat = ST_CLOS;
}
int_32 CFileDB::Commit(){
if( _stat != ST_OPEN )
return _err = ER_DBNOTOPEN;
fclose(file);
file = fopen(fn,"rb+");
if( file == NULL )
return _err = ER_FILEOPENER;
return _err = ER_NOERROR;
}
int_32 CFileDB::Open(){
if( _stat != ST_CREA )
return _err = ER_ERROR;
if( FieldSet.Count() == 0 ){
return _err = ER_EMPTYTABLE;
}
//创建索引
IndexTable._bp = FieldSet.Count()*TFIELDSZ+THEADSIZE; //计算索引表的位置
int itsz = MAXRECORDCOUNT*IndexTable._idsz1;
if( fseek(CFileDB::file,IndexTable._bp,SEEK_SET) != 0 ){
return _err = ER_FILESEEKER;
}
char *buf = new char[itsz];
memset(buf,0,itsz);
int r = fwrite(buf,itsz,1,CFileDB::file);
delete []buf;
RecordSet._bp = IndexTable._bp + itsz;
for(int i=0;i<MAXRECORDCOUNT;++i){
IndexTable._unusedit.push_back(i+1);
}
_stat = ST_OPEN;
return _err = ER_NOERROR;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -