1640 lines
31 KiB
C
1640 lines
31 KiB
C
|
/*
|
|||
|
* 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_ */
|
|||
|
|