gStore/test/CBtreeH.h

1640 lines
31 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* 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_ */