gStore/test/CBtreeH.h

1640 lines
31 KiB
C
Raw Normal View History

/*
* CBtree.h
*
* Created on: 2012-3-5
* Author: liyouhuan
*/
#ifndef CBTREEH_H_
#define CBTREEH_H_
#include<iostream>
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<time.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<vector>
#include<queue>
#include<stack>
#include<set>
#define BLOCKSIZE (1 << 14)/* 16K */
#define ORDER_V 128 /* 为简单起见把v固定为2实际的B+树v值应该是可配的 */
#define MAXNUM_KEY (ORDER_V * 2) /* 内部结点中最多键个数为2v ( 1~2v )*/
#define MAXNUM_POINTER (ORDER_V * 2 + 1) /* 内部结点中最多指向子树的指针个数为2v ( 1~2v )*/
#define MAXNUM_DATA (ORDER_V * 2 + 1) /* 结点中用作定义为2v ( 1~2v )*/
#define TERM_NUMBER 1
#define FLAG_LEFT 5
#define FLAG_RIGHT 6
#define FLAG_ZERO 7
#define FLAG_NO_ZERO 8
#define nFlush1 2500000
#define nFlush2 2000000
#define nFlush3 1500000
#define nFlush4 1000000
#define level1 6000000
#define level2 4000000
using namespace std;
enum NODE_TYPE
{
NODE_TYPE_INTERNAL = 2, // 内部结点
NODE_TYPE_LEAF = 3, // 叶子结点
};
enum eletype
{
B_CHARARRAY = 1,
B_INTEGER = 4,
};
extern eletype _eletype;
extern int _ii;
extern string filePath_o2sID;
extern string filePath_opID2sID;
extern string filePath_s2sID;
extern string filePath_sID2s;
extern int myStrcmp(char _str1[], int len1, char _str2[], int len2);
extern FILE * _log_btree;
class KeyType
{
public:
int _num_insert;
bool is_AtMem;
char* sKey;
int iKey;
int mLenKey; //关于是否读入\n的试验
KeyType()
{
KeyType_Initial();
}
KeyType(KeyType & a)
{
_num_insert = a._num_insert;
iKey = a.iKey;
mLenKey = a.mLenKey;
is_AtMem = a.is_AtMem;
this ->set_sKey(a.sKey, a.mLenKey);
}
void KeyType_Initial()
{
sKey = NULL;
iKey = -1;
mLenKey = -1;
is_AtMem = false;
_num_insert = -1;
}
~KeyType()
{
clear_skey();
}
void clear_skey()
{
if(sKey != NULL)
{
delete [] sKey;
sKey = NULL;
}
}
void set_sKey(const char * _str, int kLen)
{
if(_str == NULL)
{
sKey = NULL;
mLenKey = 0;
return;
}
if(sKey != NULL)
{
delete [] sKey;
sKey = NULL;
}
mLenKey = kLen;
sKey = new char[mLenKey + 1];
memcpy(sKey, _str, mLenKey);
sKey[mLenKey] = '\0';
}
void set_iKey(int _i)
{
mLenKey = 4;
iKey = _i;
}
void RandInputKey(int _i)
{
if(_eletype == B_CHARARRAY)
{
char _c_key[100] = "a";
int _input_key = rand() % 100000;
_input_key += _i * 3;
char _i_to_s[100] = "";
sprintf(_i_to_s, "%d", _input_key);
strcat(_c_key, _i_to_s);
mLenKey = (int)strlen(_c_key);
sKey = new char[mLenKey + 1];
strcpy(sKey, _c_key);
sKey[mLenKey] = '\0';
}
else
{
iKey = _i;
mLenKey = 4;
}
}
void HandInputKey()
{
if(_eletype == B_CHARARRAY)
{
cout << "input the key_string" << endl;
char _c_key[1000];
gets(_c_key);
gets(_c_key);
mLenKey = (int)strlen(_c_key);
sKey = new char[mLenKey + 1];
strcpy(sKey, _c_key);
sKey[mLenKey] = '\0';
}
else
{
cout << "input the key_integer" << endl;
int _input_key = 0;
scanf("%d", &_input_key);
iKey = _input_key;
mLenKey = 4;
}
}
void ReadKey(FILE * fp);
void WriteKey(FILE * fp);
/*
*
*/
int WriteSize()
{
int size_mLenKey = sizeof(mLenKey);
int size_Key = 4;
if(_eletype == B_CHARARRAY)
{
size_Key = (mLenKey + 1) * sizeof(char);
}
else
if(_eletype == B_INTEGER)
{
size_Key = sizeof(int);
}
else
{
printf("err in writesize of keytype\n");
system("pause"); exit(0);
}
return size_mLenKey + size_Key;
}
void PrintKey()
{
if(_eletype == B_CHARARRAY)
{
printf("[%s,%d]", sKey, this ->mLenKey);
}
else
if(_eletype == B_INTEGER)
{
printf("%d", iKey);
}
else
{
printf("bug in pk\n");
system("pause"); exit(0);
}
}
bool Gt(const KeyType & a)const
{
if(_eletype == B_CHARARRAY)
{
if(myStrcmp(sKey, mLenKey, a.sKey, a.mLenKey) > 0)
return true;
return false;
}
else
if(_eletype == B_INTEGER)
{
if(iKey > a.iKey)
return true;
return false;
}
else
{
printf("err in gt\n");
system("pause"); exit(0);
}
return true;
}
bool Lt(const KeyType & a)const
{
if(_eletype == B_CHARARRAY)
{
if(myStrcmp(sKey, mLenKey, a.sKey, a.mLenKey) < 0)
return true;
return false;
}
else
if(_eletype == B_INTEGER)
{
if(iKey < a.iKey)
return true;
return false;
}
else
{
printf("err in gt\n");
system("pause"); exit(0);
}
return true;
}
bool Eq(const KeyType & a)const
{
if(_eletype == B_CHARARRAY)
{
if(myStrcmp(sKey, mLenKey, a.sKey, a.mLenKey) == 0)
return true;
return false;
}
else
if(_eletype == B_INTEGER)
{
if(iKey == a.iKey)
return true;
return false;
}
else
{
printf("err in gt\n");
system("pause"); exit(0);
}
return true;
}
bool operator >(const KeyType & a)const
{
return Gt(a);
}
bool operator >=(const KeyType & a)const
{
return Gt(a) || Eq(a);
}
bool operator <(const KeyType & a)const
{
return Lt(a);
}
bool operator <=(const KeyType & a)const
{
return Lt(a) || Eq(a);
}
bool operator ==(const KeyType & a)const
{
return Eq(a);
}
KeyType & operator = (const KeyType & a)
{
_num_insert = a._num_insert;
iKey = a.iKey;
mLenKey = a.mLenKey;
is_AtMem = a.is_AtMem;
this ->set_sKey(a.sKey, a.mLenKey);
return * this;
}
};
extern KeyType KeyNULL;
class mBlockLink
{
public:
long long int preBlockAddr;
long long int nextBlockAddr;
void mBlockLink_Initial()
{
preBlockAddr = -1;
nextBlockAddr = -1;
}
mBlockLink & operator=(mBlockLink & a)
{
preBlockAddr = a.preBlockAddr;
nextBlockAddr = a.nextBlockAddr;
return *this;
}
mBlockLink()
{
}
mBlockLink(mBlockLink & a)
{
preBlockAddr = a.preBlockAddr;
nextBlockAddr = a.nextBlockAddr;
}
};
class mValue
{
public:
char * Term[TERM_NUMBER];
int lenTerm[TERM_NUMBER];
~mValue()
{
for(int i = 0; i < TERM_NUMBER; i ++)
{
if(Term[i] != NULL)
{
delete [] Term[i];
Term[i] = NULL;
}
}
}
void mValue_Initial()
{
for(int i = 0; i < TERM_NUMBER; i ++)
{
if(Term[i] != NULL)
{
cout << "term mem lost" << endl;
system("pause");
system("pause"); exit(0);
}
Term[i] = NULL;
lenTerm[i] = 0;
}
}
void getValInteger(vector<int> & nodeSet)
{
{//for one order
/*
int _tag = 0;
int i_size = sizeof(int);
while(_tag + i_size <= lenTerm[0])
{
int _val = *( (int*)(Term[0]+_tag) );
nodeSet.push_back(_val);
_tag += 5;
}
*/
}
{//for the other order
int _tag = lenTerm[0];
int i_size = sizeof(int);
while(_tag - i_size >= 0)
{
int _val = *( (int*)(Term[0]+_tag - i_size) );
nodeSet.push_back(_val);
_tag -= 5;
}
}
return;
}
void iPrintval(int _i)
{
if(_i < 0 || _i > TERM_NUMBER - 1)
{
cout << "bug ipval" << endl;
system("pause"); exit(0);
}
if(Term[_i] == NULL)
{
cout << "bug ipvalt" << endl;
system("pause"); exit(0);
}
cout << Term[_i] << endl;
}
//think
mValue & operator=(const mValue & a)
{
for(int i = 0; i < TERM_NUMBER; i ++)
{
lenTerm[i] = a.lenTerm[i];
if(Term[i] != NULL)
{
delete [] Term[i];
Term[i] = NULL;
}
Term[i] = new char[lenTerm[i] + 1];
memcpy(Term[i], a.Term[i], lenTerm[i] + 1);
}
return *this;
}
mValue()
{
for(int i = 0; i < TERM_NUMBER; i ++)
{
Term[i] = NULL;
lenTerm[i] = 0;
}
}
// think
mValue(mValue & a)
{
for(int i = 0; i < TERM_NUMBER; i ++)
{
lenTerm[i] = a.lenTerm[i];
if(Term[i] != NULL)
{
delete [] Term[i];
Term[i] = NULL;
}
Term[i] = new char[lenTerm[i] + 1];
memcpy(Term[i], a.Term[i], lenTerm[i] + 1);
}
}
void set_iVal(int _i, const char * _str, int _str_len)
{
if(_i < 0 || _i > TERM_NUMBER - 1)
{
cout << "bug setival" << endl;
system("pause"); exit(0);
}
if(Term[_i] != NULL)
{
delete [] Term[_i];
Term[_i] = NULL;
}
Term[_i] = new char[_str_len + 1];
memcpy(Term[_i], _str, _str_len + 1);
lenTerm[_i] = _str_len;
Term[_i][ lenTerm[_i] ] = '\0';
}
bool delete_iVal(int _i, char * del_str, int & flag)
{
if(_i < 0 || _i > TERM_NUMBER - 1)
{
cout << "bug setival" << endl;
system("pause"); exit(0);
}
if(Term[_i] == NULL)
{
cout << "bug addival" << endl;
system("pause"); exit(0);
}
int _tag = 0;
int i_size = sizeof(int);
while(_tag + i_size <= lenTerm[0])
{
if(del_str[0] == Term[0][_tag] && del_str[1] == Term[0][_tag + 1] && del_str[2] == Term[0][_tag + 2]
&& del_str[3] == Term[0][_tag + 3])
break;
_tag += 5;
}
if(_tag + i_size > lenTerm[0])
{
flag = FLAG_NO_ZERO;
return false;
}
if(_tag + i_size == lenTerm[0])
{
Term[0][_tag] = '\0';
lenTerm[0] -= sizeof(int) + sizeof(char);
//只有一个元素时很特殊, 长度是减少4 其余减少5
if(lenTerm[0] <= 0) flag = FLAG_ZERO;
else flag = FLAG_NO_ZERO;
return true;
}
for(int i = _tag; i + i_size < lenTerm[0]; i ++)
{
Term[0][i] = Term[0][i + i_size + 1];
}
lenTerm[0] -= sizeof(int) + sizeof(char);
flag = FLAG_NO_ZERO;
return true;
}
void add_iVal(int _i, const char *add_str)
{
if(_i < 0 || _i > TERM_NUMBER - 1)
{
cout << "bug setival" << endl;
system("pause"); exit(0);
}
if(Term[_i] == NULL)
{
cout << "bug addival" << endl;
system("pause"); exit(0);
}
char * _tmp_term_i = NULL;
int _tag = 0;
int i_size = sizeof(int);
while(_tag + i_size <= lenTerm[0])
{
if(add_str[0] == Term[0][_tag] && add_str[1] == Term[0][_tag + 1] && add_str[2] == Term[0][_tag + 2]
&& add_str[3] == Term[0][_tag + 3])
return;
_tag += 5;
}
int newLen = sizeof(int) + sizeof(char) + lenTerm[_i];
_tmp_term_i = new char[ newLen + 1];
memcpy(_tmp_term_i, add_str, 4 + 1);
_tmp_term_i[4] = ' ';
memcpy(_tmp_term_i + 5, Term[_i], lenTerm[_i] + 1);
lenTerm[0] = newLen;
_tmp_term_i[ lenTerm[_i] ] = '\0';
if(Term[_i] != NULL)
{
delete [] Term[_i];
Term[_i] = NULL;
}
else
{
cout << "bug term" << endl;
system("pause");
exit(0);
}
Term[_i] = _tmp_term_i;
}
void InputVal()
{
char _input_str[1000] = "helloworld";
for(int i = 0; i < TERM_NUMBER; i ++)
{
lenTerm[i] = (int)strlen(_input_str);
Term[i] = new char[lenTerm[i] + 1];
strcpy(Term[i], _input_str);
Term[i][ lenTerm[i] ] = '\0';
}
}
void FputVal(FILE * fp)
{
}
void ReadVal(FILE * fp);
void WriteVal(FILE * fp);
int WriteSize()
{
int _sum_size = 0;
for(int i = 0; i < TERM_NUMBER; i ++)
{
_sum_size += lenTerm[i] + 1;
}
_sum_size += TERM_NUMBER * (sizeof(int));
return _sum_size;
}
void PrintVal()
{
for(int i = 0; i < TERM_NUMBER; i ++)
{
if(Term[i] != NULL)
printf("%s == ", Term[i]);
cout << "len = " << lenTerm[i] << endl;
}
}
};
class mQueue
{
public:
// static const int qLenth = 5243005; /* 5*1024*1024 */
static const int qLenth = 20971520; /* 20*1024*1024 */
int qUsed;
bool qAvailable[mQueue::qLenth];
public:
mQueue()
{
Initial();
}
void Initial()
{
qAvailable[0] = false;
qUsed = 1;
for(int i = 1; i < mQueue::qLenth; i ++)
{
qAvailable[i] = true;
}
}
void Push(long long int _iq)
{
if(_iq % BLOCKSIZE != 0)
{
printf("bug in _iq\n");
system("pause"); exit(0);
}
_iq /= BLOCKSIZE;
if(qAvailable[_iq] || _iq >= mQueue::qLenth)// for check
{
printf("err in queue_insert: qLenth = %d\n", mQueue::qLenth);
_iq %= mQueue::qLenth;
}
// cout << "block back: " << (_iq * BLOCKSIZE) << endl;
qAvailable[_iq] = true;
qUsed --;
}
void MulPush(long long int _iq[], int _qlen)
{
for(int i = 0; i < _qlen; i ++)
{
Push(_iq[i]);
}
}
void MulPush(const vector<long long int>& _back_vec){
vector<long long int>::const_iterator citr;
for(citr = _back_vec.begin(); citr != _back_vec.end(); citr++){
this ->Push(*citr);
}
}
long long int Pop()
{
for(int i = 0; i < mQueue::qLenth; i ++)
{
if(qAvailable[i])
{
long long int lli_tmp = i;
lli_tmp = lli_tmp * BLOCKSIZE;
// cout << "block out: " << (lli_tmp) << endl;
qAvailable[i] = false;
qUsed ++;
return lli_tmp;
}
}
printf("err in queue_pop\n");
system("pause"); exit(0);
}
void ReadQueue(char * _queuefile)
{
FILE * fp;
if((fp = fopen(_queuefile, "rb+")) == NULL)
{
printf("err in open r_queuefile\n");
system("pause"); exit(0);
}
else
{
fread(&qUsed, sizeof(int), 1, fp);
fread(qAvailable, sizeof(bool), mQueue::qLenth, fp);
// printf("qLenth = %d\n", qLenth);
}
fclose(fp);
}
void WriteQueue(char * _queuefile)
{
FILE * fp;
if((fp = fopen(_queuefile, "wb+")) == NULL)
{
printf("err in open w_queuefile\n");
system("pause"); exit(0);
return;
}
else
{
fwrite(&qUsed, sizeof(int), 1, fp);
fwrite(qAvailable, sizeof(bool), mQueue::qLenth, fp);
}
fclose(fp);
}
int BlockUsed()
{
return qUsed;
}
};
class mLeafNode;
class mItnlNode;
class BPlusTree;
class mNode
{
public:
void mNode_Initial()
{
Modify = true; Count = 0;
AddrFB = -1; mFather = NULL;
}
virtual ~mNode() { }
void setModify() { Modify = true; }
bool getModify() { return Modify; }
void unModify() { Modify = false; }
int getCount() { return Count; }
void setCount(int _count) { Count = _count; }
void IncCount() { Count ++; }
void DecCount() { Count --; }
long long int getAddrFB() { return AddrFB; }
void setAddrFB(long long int _addrfb){AddrFB = _addrfb; }
NODE_TYPE getType() { return Type; }
void setType(NODE_TYPE _type) { Type = _type; }
mNode * getFather() { return mFather; }
void setFather(mNode * _mpather) {mFather = _mpather;}
virtual mNode * getPointer(int _i) { return NULL; }
virtual void setPointer(int _i, mNode * _mnode) { }
virtual bool isInMemory(int _i) { return false; }
virtual void setMemory(int _i) { }
virtual int iInsert(KeyType & _keytype) {return 0; }
virtual KeyType & getKey(int _i) { return KeyNULL; }
virtual void setKey(int _i, KeyType &_keytype){ }
virtual void printNode() { return; }
mNode * getBrother(int & flag)
{
mNode * _pFather = this ->getFather();
if(_pFather == NULL) return NULL;
mNode * _pBrother = NULL;
for(int i = 1; i <= _pFather ->getCount(); i ++)
{
//ָ<><D6B8>ƥ<EFBFBD><C6A5>
if(_pFather ->getPointer(i) == this)
{
if(i == (_pFather ->getCount()) + 1)
{
flag = FLAG_LEFT;
_pBrother = _pFather ->getPointer(i - 1);
}
else
{
flag = FLAG_RIGHT;
_pBrother = _pFather ->getPointer(i + 1);
}
break;
}
}
if(_pBrother == NULL)
{
cout << "bug run here" << endl;
}
return _pBrother;
}
mItnlNode * ifordebug;
mLeafNode * lfordebug;
private:
int Count;
long long int AddrFB;
bool Modify;
NODE_TYPE Type;
mNode * mFather;
};
class mitnldata
{
public:
KeyType mKey;
mNode * mPointer;
long long int mAddr_sonFB;
void mitnldata_Initial()
{
mKey.KeyType_Initial();
mPointer = NULL;
mAddr_sonFB = -1;
}
mitnldata & operator=(mitnldata & a)
{
mKey = a.mKey;
mPointer = a.mPointer;
mAddr_sonFB = a.mAddr_sonFB;
return *this;
}
void cleardata()
{
mKey.clear_skey();
}
~mitnldata()
{
}
mitnldata() {}
mitnldata(mitnldata & a)
{
mKey = a.mKey;
mPointer = a.mPointer;
mAddr_sonFB = a.mAddr_sonFB;
}
bool operator >(const mitnldata & a) { return mKey > a.mKey; }
bool operator <(const mitnldata & a) { return mKey < a.mKey; }
void Hand_inputkey() { mKey.HandInputKey(); }
void Rand_inputkey(int _i) { mKey.RandInputKey(_i); }
void Read_mitnldata(FILE * fp);
bool Write_mitnldata( FILE * fp, int & _size_left );
};
class mItnlNode : public mNode
{
public:
mitnldata ItnlData[MAXNUM_DATA];
mItnlNode()
{
mNode_Initial();
ifordebug = this;
lfordebug = NULL;
setType(NODE_TYPE_INTERNAL);
for(int i = 0; i <= MAXNUM_KEY; i ++)
{
ItnlData[i].mitnldata_Initial();
}
}
~mItnlNode()
{
}
KeyType & getKey(int _i)
{
if(_i > 0 && _i <= getCount())
{
return ItnlData[_i].mKey;
}
else
{
printf("err in getkey\n");
system("pause"); exit(0);
}
return KeyNULL;
}
void setKey(int _i, const KeyType &_keytype)
{
if(_i > 0 && _i <= MAXNUM_KEY )
{
ItnlData[_i].mKey = _keytype;
}
else
{
printf("err in setkey\n");
system("pause"); exit(0);
}
return;
}
mitnldata & getElement(int _i)
{
if(_i > 0 && _i <= getCount())
{
return ItnlData[_i];
}
else
{
printf("err in getele\n");
system("pause"); exit(0);
}
return ItnlData[0];
}
void setElement(int _i, mitnldata & _itnldata)
{
if(_i > 0 && _i <= MAXNUM_KEY)
{
ItnlData[_i] = _itnldata;
}
else
{
printf("err in setele\n");
system("pause"); exit(0);
}
}
mNode * getPointer(int _i)
{
if(_i > 0 && _i <= getCount())
{
return ItnlData[_i].mPointer;
}
else
{
printf("err in getpointer\n");
system("pause"); exit(0);
}
return NULL;
}
void setPointer(int _i, mNode * _mpointer)
{
if(_i > 0 && _i <= MAXNUM_POINTER)
{
ItnlData[_i].mPointer = _mpointer;
// setFather !!!!!
_mpointer ->setFather(this);
}
else
{
printf("err in setpointer\n");
system("pause"); exit(0);
}
}
//此函数需仔细考虑~~
int iExist(const KeyType &_keytype)
{
int _ibegin = 1, _iend = getCount();
int _imiddle;
while(_ibegin < _iend)
{
_imiddle = (_ibegin + _iend) / 2;
if(ItnlData[_ibegin].mKey == _keytype)
{
return _ibegin;
}
if(ItnlData[_iend].mKey == _keytype)
{
return _iend;
}
if(_ibegin == _iend - 1) return -1;
// 后加可能有风险
if(ItnlData[_imiddle].mKey > _keytype)
{
_iend = _imiddle;
}
else
{
_ibegin = _imiddle;
}
}
return -1;
}
int iInsert(const KeyType & _keytype)
{
int _ibegin = 1, _iend = getCount();
int _imiddle;
while(_ibegin < _iend)
{
_imiddle = (_ibegin + _iend) / 2;
if(ItnlData[_iend].mKey < _keytype)
{
return _iend + 1;
}
if(ItnlData[_ibegin].mKey < _keytype && ItnlData[_ibegin + 1].mKey > _keytype)
{
return _ibegin + 1;
}
if(ItnlData[_imiddle].mKey > _keytype)
{
_iend = _imiddle;
}
else
{
_ibegin = _imiddle;
}
}
return -1;
}
int iNextFloor(const KeyType & _keytype)
{
int _ibegin, _iend, _imiddle;
_ibegin = 1;
_iend = getCount();
if(ItnlData[_ibegin].mKey > _keytype)
{
// printf("less than _ibegin\n");
return -1;
}
while(_ibegin < _iend)
{
_imiddle = (_ibegin + _iend) / 2;
if(ItnlData[_iend].mKey <= _keytype)
{
return _iend;
}
if(ItnlData[_ibegin].mKey <= _keytype && ItnlData[_ibegin + 1].mKey > _keytype)
{
return _ibegin;
}
if(ItnlData[_imiddle].mKey > _keytype)
{
_iend = _imiddle;
}
else
{
_ibegin = _imiddle;
}
}
return -1;
}
bool isInMemory(int _i)
{
if(_i > 0 && _i <= getCount())
{
if(ItnlData[_i].mKey.is_AtMem)
return true;
else
return false;
}
else
{
printf("err in isinmemeory\n");
system("pause"); exit(0);
}
}
void setMemory(int _i)
{
if(_i > 0 && _i <= getCount())
{
ItnlData[_i].mKey.is_AtMem = true;
}
else
{
printf("err in setmemeory\n");
system("pause"); exit(0);
}
}
long long int getSonAddr(int _i)
{
if(_i > 0 && _i <= getCount())
{
return ItnlData[_i].mAddr_sonFB;
}
else
{
printf("err in getsonaddr\n");
system("pause"); exit(0);
}
}
void setSonAddr(int _i, long long int _addr_son)
{
if(_i > 0 && _i <= MAXNUM_KEY)
{
ItnlData[_i].mAddr_sonFB = _addr_son;
}
else
{
printf("err in getsonaddr\n");
system("pause"); exit(0);
}
}
void printNode()
{
printf(" == ");
for(int i = 1; i <= getCount(); i ++)
{
ItnlData[i].mKey.PrintKey();
printf(" ");
}
printf(" == ");
}
// 插入键
// 最左端递归向上
bool Insert(mNode* _pmnode);
// 删除键
int Delete(const KeyType & _keytype);
// 分裂结点
KeyType & Split(mItnlNode* _mitnlnode);
// 结合结点
bool Combine(mItnlNode * _pmnode);
// 从另一结点移一个元素到本结点
bool MoveOneElement(mNode * _pmnode);
};
class mleafdata
{
public:
KeyType mData;
mValue * pVal;
void mleafdata_Initial()
{
if(mData.sKey != NULL || pVal != NULL)
{
cout << "mem lost" << endl;
system("pause");
system("pause"); exit(0);
}
mData.KeyType_Initial();
pVal = NULL;
}
~mleafdata()
{
cleardata();
}
mleafdata()
{
mData.KeyType_Initial();
pVal = NULL;
}
void cleardata()
{
if(pVal != NULL)
{
delete pVal;
pVal = NULL;
}
mData.clear_skey();
}
void assign_val_ptr(mleafdata & a)
{
this->pVal = a.pVal;
}
// think
mleafdata & operator = (const mleafdata & a)
{
mData = a.mData;
if(pVal != NULL)
{
delete pVal;
pVal = NULL;
}
pVal = new mValue;
pVal ->mValue_Initial();
*pVal = *(a.pVal);
return * this;
}
void SubIDPrint()
{
mData.PrintKey();
cout << " k 2 v " << endl;
vector<int> nSet;
pVal ->getValInteger(nSet);
for(unsigned int i = 0; i < nSet.size(); i ++)
{
cout << nSet[i] << " ";
if(i % 50 == 0) cout << endl;
}
}
void PrintLeafdata()
{
mData.PrintKey();
cout << " k2v ";
pVal ->PrintVal();
}
void fPrintLeafdata(FILE *fp)
{
char * skey = mData.sKey;
char * sterm = pVal ->Term[0];
fprintf(fp, "%s\n\n\n", skey);
fprintf(fp, "%s\n\n\n", sterm);
return;
}
void iPrintdata(int _i)
{
pVal ->iPrintval(_i);
}
void getdataInteger(vector<int> & nodeSet)
{
if(pVal == NULL)
{
cout << "bug pval" << endl;
system("pause"); exit(0);
}
pVal ->getValInteger(nodeSet);
}
void fputLeafdata(FILE * fp)
{
char _str[5][100];
char _latter[500];
int _ikey = 0;
if(pVal != NULL)
{
delete pVal;
pVal = NULL;
}
pVal = new mValue;
pVal ->mValue_Initial();
if(_eletype == B_CHARARRAY)
{
fprintf(fp, "%s %s %s %s %s ", _str[0], _str[1], _str[2], _str[3], _str[4]);
fgets(_latter, 500, fp);
mData.set_sKey(_str[0], (int)strlen(_str[0]));
for(int i = 0; i <= 3; i ++) pVal ->set_iVal(i, _str[i + 1], (int)strlen(_str[i + 1]));
pVal ->set_iVal(4, _latter, (int)strlen(_latter));
}
else
if(_eletype == B_INTEGER)
{
fprintf(fp, "%d %s %s %s %s ", _ikey, _str[1], _str[2], _str[3], _str[4]);
fgets(_latter, 500, fp);
mData.set_iKey(_ikey);
for(int i = 0; i <= 3; i ++) pVal ->set_iVal(i, _str[i + 1], (int)strlen(_str[i + 1]));
pVal ->set_iVal(4, _latter, (int)strlen(_latter));
}
else
{
cout << "bug fput" << endl;
system("pause"); exit(0);
}
}
void set_iKey_sValue(int _ikey, char _sval[])
{
mData.set_iKey(_ikey);
}
void set_sKey_sValue(const char _skey[], int _klen, const char _sval[], int val_len)
{
if(pVal != NULL)
{
delete pVal;
pVal = NULL;
}
pVal = new mValue;
pVal ->mValue_Initial();;
mData.set_sKey(_skey, _klen);
pVal ->set_iVal(0, _sval, val_len);
}
bool deletePartVal(char PartVal[], int & flag)
{
if(pVal == NULL)
{
cout << "null error" << endl;
system("pause");
exit(0);
}
return pVal ->delete_iVal(0, PartVal, flag);
}
void inputLeafdata()
{
if(pVal == NULL)
{
pVal = new mValue;
}
pVal ->InputVal();
}
// think
mleafdata(mleafdata & a)
{
mData = a.mData;
pVal = new mValue;
pVal ->mValue_Initial();
*pVal = *(a.pVal);
}
bool operator > (const mleafdata & a)
{
return mData > a.mData;
}
bool operator < (const mleafdata & a)
{
return mData < a.mData;
}
void Hand_inputkey() { mData.HandInputKey(); }
void Rand_inputkey(int i) { mData.RandInputKey(i); }
bool Read_mleafdata(FILE * fp);
bool Write_mleafdata(FILE * fp, int & _size_left, int & _key_size, int & _val_size);
};
class mLeafNode : public mNode
{
public:
mLeafNode* preNode;
mLeafNode* nextNode;
mBlockLink leafLink;
mleafdata LeafData[MAXNUM_DATA];
mLeafNode()
{
mNode_Initial();
lfordebug = this;
ifordebug = NULL;
preNode = NULL;
nextNode = NULL;
leafLink.mBlockLink_Initial();
setType(NODE_TYPE_LEAF);
for(int i = 0; i <= MAXNUM_KEY; i ++)
{
LeafData[i].mleafdata_Initial();
}
}
~mLeafNode()
{
}
//
// ~mLeafNode()
// {
// cout << "call leaf" << this ->getCount() << endl;
// for(int i = 1; i <= this ->getCount(); i ++)
// {
// LeafData[i].cleardata();
// }
// cout << "here1328" << endl;
// }
KeyType & getKey(int _i)
{
if(_i > 0 && _i <= getCount())
{
return LeafData[_i].mData;
}
else
{
printf("err in leaf getkey\n");
system("pause"); exit(0);
}
return KeyNULL;
}
void setKey(int _i, KeyType & _keytype)
{
if(_i > 0 && _i <= MAXNUM_KEY)
{
LeafData[_i].mData = _keytype;
}
else
{
printf("err in leaf setkey\n");
system("pause"); exit(0);
}
}
mleafdata & getElement(int _i)
{
if(_i > 0 && _i <= getCount())
{
return LeafData[_i];
}
else
{
printf("err in getele\n");
system("pause"); exit(0);
}
}
void setElement(int _i, const mleafdata & _leafdata)
{
if(_i > 0 && _i <= MAXNUM_KEY)
{
LeafData[_i] = _leafdata;
}
else
{
printf("err in setele\n");
system("pause"); exit(0);
}
}
// 此两个函数对叶节点无意义
mNode * getPointer(int _i)
{
return NULL;
}
void setPointer(int _i, mNode * _pmnode)
{
return;
}
int iExist(const KeyType & _keytype)
{
int _ibegin = 1, _iend = getCount();
int _imiddle;
if(_iend <= 0){
// cout << "not found for the bug of getCount : " << _iend << endl;
return -1;
}
if(LeafData[1].mData == _keytype)
return 1;
while(_ibegin < _iend)
{
_imiddle = (_ibegin + _iend) / 2;
if(LeafData[_ibegin].mData == _keytype)
{
return _ibegin;
}
if(LeafData[_iend].mData == _keytype)
{
return _iend;
}
if(_ibegin + 1 == _iend){
return -1;
}
if(LeafData[_imiddle].mData > _keytype)
{
_iend = _imiddle;
}
else
{
_ibegin = _imiddle;
}
}
return -1;
}
// 考虑cout = 0的情况
int iInsert(const KeyType & _keytype)
{
int _ibegin = 1, _iend = getCount();
int _imiddle;
if(_iend <= 0 || LeafData[_ibegin].mData > _keytype)
{
// cout << "iInsert ret 1!!" << endl;
return 1;
}
// count = 0 && count = 1
if(LeafData[_iend].mData < _keytype)
{
return _iend + 1;
}
while(_ibegin < _iend)
{
_imiddle = (_ibegin + _iend) / 2;
if(LeafData[_ibegin].mData < _keytype && LeafData[_ibegin + 1].mData > _keytype)
{
return _ibegin + 1;
}
if(LeafData[_imiddle].mData > _keytype)
{
_iend = _imiddle;
}
else
{
_ibegin = _imiddle;
}
}
return -1;
}
bool isInMemory(int _i)
{
if(_i > 0 && _i <= getCount())
{
if(LeafData[_i].mData.is_AtMem)
return true;
else
return false;
}
else
{
printf("err in setmemeory\n");
system("pause"); exit(0);
}
}
void setMemory(int _i)
{
if(_i > 0 && _i <= getCount())
{
LeafData[_i].mData.is_AtMem = true;
}
else
{
printf("err in setmemeory\n");
system("pause"); exit(0);
}
}
void printNode()
{
printf(" == ");
for(int i = 1; i <= getCount(); i ++)
{
LeafData[i].mData.PrintKey();
printf(" ");
}
printf(" == ");
}
// 插入数据
// 最左端递归向上
bool Insert(const mleafdata & _leafdata);
// 删除数据
int Delete(KeyType & _keytype);
//重载delete partval
int Delete(KeyType & _keytype, char partval[], int & pvFlag);
// 分裂结点
KeyType & Split(mLeafNode* _mpnode);
// 结合结点
bool Combine(mLeafNode* _mpnode);
// 重复插入
bool dupInsert(const mleafdata & _leafdata, int _index_insert);
};
extern mNode* ReadNode(FILE * fp, long long int _addr);
extern void WriteNode(mNode * pNode, FILE * fp, mQueue & _mqueue);
extern void DelDisk(FILE * fp, long long int _addr, mQueue & _mqueue);
extern void FP_Initial(FILE * & _fp);
extern bool DATAINPUT(FILE * ifp, char _row_str[], char _str[][600] );
extern void BuildTree();
extern bool Delete_KeyVal(char keyStr[], int keyLen, BPlusTree * _ptree);
extern bool Delete_Key_PartVal(char keyStr[], int keyLen, char partVal[], BPlusTree * _ptree);
extern bool Delete_sID2sub(int _sID, BPlusTree * _p_sID2sub);
extern bool Delete_s2sID(char _sub_str[], BPlusTree * _p_s2sID);
extern bool Delete_obj2sID(char _obj_str[], int _del_sID, BPlusTree * _p_obj2sID);
extern bool Delete_objpID2sID(char _obj_str[], int _pID, int _del_sID, BPlusTree * _p_objpID2sID);
/* B+树数据结构 */
class BPlusTree
{
public:
// 以下两个变量用于实现双向链表
mLeafNode* pmLeafHead; // 头结点
mLeafNode* pmLeafTail; // 尾结点
mNode * mRoot; // 根结点
mQueue mblockQueue;
FILE * mfp;
char mTreeName[1024];
int mDepth; // 树的深度
int insert_count;
void Initial();
BPlusTree(const char * const_tree_name, const char * _build_or_open);
~BPlusTree();
string getTreeFileName();
void log(const char* _log)const;
void forcheck();
// 获取和设置根结点
mNode * getRoot() { return mRoot; }
void setRoot(mNode * root) { mRoot = root; }
void Flush();
// 为插入而查找叶子结点
mLeafNode * SearchLeafNode(const KeyType & data)const;
//插入键到中间结点
bool InsertItnlNode(mItnlNode * pNode, mNode * pSon);
// 在中间结点中删除键
bool DeleteItnlNode(mItnlNode * pNode, KeyType & key);
// 查找指定的数据
bool Search(KeyType & data, mleafdata & _ret);
// 插入指定的数据
bool Insert(const mleafdata & _mleafdata);
// 删除指定的数据
bool Delete(KeyType & data);
// 重载删除函数
bool Delete(KeyType & data, char PartVal[]);
// 清除树
void ClearTree();
// 打印树
void PrintTree();
//读出根节点
void ReadRoot();
//保存树结构
void StoreTree();
};
#endif /* CBTREE_H_ */