B+树(插入,非惰性删除)

来源:互联网 发布:flushcopy是什么软件 编辑:程序博客网 时间:2024/04/29 03:47

设计思路:

 

  使用C++中的模板类编程,B+树的存储支持所有数据类型,包括用户自定义类型。

  使用纯虚基类,使得B+树中的叶结点与内部结点继承自同一类,便于维护与管理,避免为保证统一而扩充结点导致的空间浪费,利用多态性在运行时确定结点类型。

      叉数和类型都作为参数传入。

      BPlusTree类维护了结点类型、叉数等信息以及插入、删除、查找等方法。

  接口函数通过调用组织B+树类提供的函数,封装后供其它模块调用。



向外提供的接口:

 


 

执行创建操作:

 

        根据传入的表名和类型名、类型大小,计算叉数,创建B+树文件,存入叉数和类型名;

 

执行查询操作:

 

  查询等于,直接调用等值查找;

  查询不等于,不通过B+;

  查询大于,找到第一个等于的值,然后沿底部的链表向右把后面的偏移量都存入缓冲区;

  查询大于等于,找到第一个等于的值,然后沿底部的链表向右把第一个的偏移量和后面的偏移量都存入缓冲区;

  查询大于,找到第一个等于的值,然后沿底部的链表向左把前面的偏移量都存入缓冲区;

  查询大于等于,找到第一个等于的值,然后沿底部的链表向左把第一个的偏移量和前面的偏移量都存入缓冲区;

 

执行插入操作:

 

  根据表名打开对应B+树文件,直接调用插入方法;

 

执行删除操作:

 

  首先执行查询操作,将符合条件的删除值对应偏移量传出,然后再调用删除方法更新B+;

 

执行创建索引操作:

 

  根据索引名新建文件,将该表已有的属性及其偏移量,从底层通过调用insert方法建立B+树,并存入文件,其余使用和基于主键的B+树类似;

 

删除索引/表:

 

  直接删除对应的B+树文件;

 

判断是否违反约束:

 

      主要判断主码是否唯一;

  类似于等值查找,在非叶结点和叶结点上,一旦读到相同的值,立即返回false

 

5.4.5 B+树主要方法:

 

树的基本操作:

void insert(T x,Index y);

void delete(T x);

bool isKey(T x);

int find(T x);

 

持久化存储:

void load();

void save();

 

 

实现算法:

 

  删除插入算法参考了mysqlinnodb引擎中的B+树。

 

 




       




         

载入B+树:

 

按照格式化顺序,把读到的文件划分为一个个字符串,并对每个字符串进行相应的映射以及格式转换。第一个读到的结点被作为根结点。


#ifndef _BPLUSTREE_H#define _BPLUSTREE_H#include<iostream>#include <fstream>  #include<string>template<typename T>class BPlusTree{private:std::string TYPE;int RANK;int MINSIZE;std::string tableName;typedef enum { nonleaf, leaf}type;typedef enum { ins, del }op;typedef int Index;class treeNode {public:Index id;Index parent;int size;virtual type getType()const = 0; //得到类型:叶结点、内部结点virtual T getKey(int i)const = 0; //得到下标为i的keyvirtual void setKey(T x, int i) = 0; //设置下标为i的key值virtual void setChild(Index t, int i) { }virtual void setBlock(int num, int i) { }virtual void setNext(Index t) { }virtual void setLast(Index t) { }virtual Index getChild(int i)const { return -1; }virtual Index getNext()const { return -1; }virtual Index getLast()const { return -1; }virtual int getBlock(int i)const { return 0; }};class internalNode :public treeNode {public:T* key;Index* child;virtual type getType()const { return nonleaf; }virtual T getKey(int i)const { return key[i]; }virtual void setKey(T x, int i) { key[i] = x; }virtual void setChild(Index t, int i) { child[i] = t; }virtual Index getChild(int i)const { return child[i]; }internalNode(int RANK, int size = 1) {key = new T[RANK];child = new Index[RANK + 1];this->size = size;for (int i = 0; i < RANK + 1; i++)child[i] = -1;}virtual ~internalNode() { };};class leafNode :public treeNode {public:T* key;Index next;Index last;int* blockNum;virtual type getType()const { return leaf; }virtual T getKey(int i)const { return key[i]; }virtual void setKey(T x, int i) { key[i] = x; }virtual void setBlock(int num, int i) { blockNum[i] = num; }virtual int getBlock(int i)const { return blockNum[i]; }virtual void setNext(Index t) { next = t; }virtual void setLast(Index t) { last = t; }virtual Index getNext()const { return next; }virtual Index getLast()const { return last; }leafNode(int RANK,int size = 1) { key = new T[RANK]; blockNum = new int[RANK]; this->size = size; next = -1; }virtual ~leafNode() { };};treeNode* root;leafNode* childNode;void insertIntoLeaf(leafNode* p, int i, T x, int y) {while (i >= 1 && x <= p->getKey(i - 1)) {p->setKey(p->getKey(i - 1), i);p->setBlock(p->getBlock(i - 1), i);i--;}//找到插入的位置  p->setKey(x, i);p->setBlock(y, i);p->size++;return;}T findKey(treeNode* t) {while (t->getType() == nonleaf) {t = node[t->getChild(0)];}return t->getKey(0);}T findNextKey(Index t) {while (t->getType() == nonleaf) {t = t->getChild(0);}return t->getKey(1);}void updateIndex(treeNode* p, T x) {if (!p)return;if (p->parent == -1)return;internalNode* t = static_cast<internalNode*>(node[p->parent]);while (t) {if (x < t->getKey(0)) {if (t->parent != -1)t = static_cast<internalNode*>(node[t->parent]);else break;}else {bool flag = false;for (int i = 0; i < t->size; i++) {if (x == t->key[i]) {t->key[i] = findKey(node[t->child[i + 1]]);flag = true;break;}}if (flag)break;else if (t->parent != -1)t = static_cast<internalNode*>(node[t->parent]);else break;}}return;}void updateIndex(treeNode* p, T x, T y) {if (!p) {return;}Index index = p->parent;if (p->parent == -1) {return;}internalNode* t = static_cast<internalNode*>(node[p->parent]);while (t) {if (y < t->getKey(0)) {index = t->parent;if(index!=-1)t = static_cast<internalNode*>(node[index]);else break;}else {bool flag = false;for (int i = 0; i < t->size; i++) {if (y == t->key[i]) {t->key[i] = x;flag = true;break;}}if (flag)break;index = t->parent;if (index != -1)t = static_cast<internalNode*>(node[index]);else break;}}return;}void updateChild(internalNode* t, T z){//更新父结点的孩子结点if (z < t->key[0]) {for (int i = 0; i < t->size; i++) {t->key[i] = t->key[i + 1];t->child[i] = t->child[i + 1];}t->child[t->size] = t->child[t->size + 1];}else {for (int i = 0; i < t->size + 1; i++) {if (z == t->key[i]) {//t是第i + 1个孩子for (int j = i; j < t->size; j++) {t->key[j] = t->key[j + 1];}for (int j = i + 1; j < t->size + 1; j++) {t->child[j] = t->child[j + 1];}return;}}}}leafNode* findLeafNode(T x) {int count = 0;treeNode *p = root;Index j = 1;if (!p)return nullptr;while (p->getType() == nonleaf) {//在已知p为内部结点时,向下造型为内部结点internalNode* t = dynamic_cast<internalNode*>(p);if (x < t->getKey(0)) {j = t->getChild(0);p = node[j];}else {for (int i = 0; i < t->size - 1; i++) {if (x >= t->getKey(i) && x < t->getKey(i + 1)) {j = t->child[i + 1];p = node[j];break;}}if (x >= t->getKey(t->size - 1)) {j = t->child[t->size];p = node[j];}}}return static_cast<leafNode*>(p);}Index findLeafNode(T x, op type) {  //找到x所在的叶结点treeNode *p = root;Index j = 1;if (!p)return -1;while (p->getType() == nonleaf) {//在已知p为内部结点时,向下造型为内部结点internalNode* t = dynamic_cast<internalNode*>(p);if (x < t->getKey(0)) {j = t->getChild(0);p = node[j];}else {for (int i = 0; i < t->size - 1; i++) {if (x > t->getKey(i) && x < t->getKey(i + 1)) {j = t->child[i + 1];p = node[j];break;}else if (x == t->getKey(i)) {if (type == ins)return -1;else if (type == del) {j = t->child[i + 1];p = node[j];break;}}}if (x > t->getKey(t->size - 1)) {j = t->child[t->size];p = node[j];}else if (x == t->getKey(t->size - 1)) {if (type == ins)return -1;else if (type == del) {j = t->child[t->size];p = node[j];}}}}return j;}treeNode* queue[10000];int front, rear;void enqueue(treeNode* t){front = (front + 1) % 10000;queue[front] = t;}treeNode* dequeue(){rear = (rear + 1) % 10000;return queue[rear];}treeNode* node[30000];int cnt;public:BPlusTree(int r,std::string name,std::string type) {cnt = 0;RANK = r;tableName = name;MINSIZE = ((RANK + 1) >> 1);root = nullptr; front = rear = 0;childNode = new leafNode(1);node[cnt] = childNode;TYPE = type;childNode->id = cnt;cnt++;}~BPlusTree() {}bool isKey(T x) {if (!this)return false;if (!root) {return false;}//找到叶结点  Index index = findLeafNode(x, ins);if (index == -1)return true;leafNode* p = static_cast<leafNode*>(node[index]);if (!p)return true;for (int j = 0; j < p->size; j++) {if (x == p->getKey(j)) {return true;}}return false;}void insert(T x, int y) {if (!root) {root = new leafNode(1);root->id = cnt;node[cnt] = root;childNode->next = cnt;childNode->last = -1;root->setKey(x, 0);root->setBlock(y, 0);root->setNext(-1);root->setLast(0);root->parent = -1;cnt++;return;}//找到叶结点  Index index = findLeafNode(x, ins);if (index == -1)return;leafNode* p = static_cast<leafNode*>(node[index]);if (!p)return;for (int j = 0; j < p->size; j++) {if (x == p->getKey(j)) {return;}}//叶结点非满,直接插入  if (p->size != RANK) {insertIntoLeaf(p, p->size, x, y);}//叶结点满  else {//旋转叶结点if (p->last != 0 && p->last != -1 && node[p->last]->size < RANK) {//printf("向左借结点\n");T w = p->key[0];int count = 1;node[p->last]->setKey(p->key[0], node[p->last]->size);node[p->last]->setBlock(p->blockNum[0], node[p->last]->size);node[p->last]->size++;bool flag = false;for (int i = 0; i < RANK; i++) {if (!flag && i == RANK - 1) {p->key[i] = x;p->blockNum[i] = y;}else if (x > p->key[count] || flag) {p->key[i] = p->key[count];p->blockNum[i] = p->blockNum[count++];}else {p->key[i] = x;p->blockNum[i] = y;flag = true;}}T x = p->key[0];updateIndex(p, x, w);return;}else if (p->next!=-1 &&node[p->next]->size < RANK) {//printf("向右借结点\n");T *num = new T[RANK + 1];int* Block = new int[RANK + 1];bool flag = false;int count = 0;T w = node[p->next]->getKey(0);for (int i = 0; i < RANK + 1; i++) {if (!flag&&i == RANK) {num[i] = x;Block[i] = y;}else if (x > p->key[count] || flag) {num[i] = p->key[count];Block[i] = p->blockNum[count++];}else {num[i] = x;Block[i] = y;flag = true;}}for (int i = 0; i < RANK; i++) {p->key[i] = num[i];p->blockNum[i] = Block[i];}for (int i = node[p->next]->size; i > 0; i--) {node[p->next]->setKey(node[p->next]->getKey(i-1),i);// [i]genode[p->next]->setBlock(node[p->next]->getBlock(i - 1), i);}node[p->next]->size++;node[p->next]->setKey(num[RANK],0);node[p->next]->setBlock(Block[RANK], 0);T u = node[p->next]->getKey(0);updateIndex(node[p->next], u, w);delete[] Block;delete[] num;return;}//分裂叶结点//分裂叶结点//将p分裂//printf("分裂叶结点\n");leafNode* newNode = new leafNode(RANK);node[cnt] = newNode;newNode->id = cnt;cnt++;struct childnode {T k;int num;}*a = new childnode[RANK + 1];//将所有数据预存在结构数组a中for (int i = 0; i < RANK; i++) {if (p->getKey(i) == x) {return;}a[i].k = p->getKey(i);a[i].num = p->getBlock(i);}int j = RANK - 1;//将新的数据插入数组afor (; x < a[j].k && j >= 0; j--) {a[j + 1] = a[j];}a[j + 1].k = x;a[j + 1].num = y;//将数组a的数据复制到node1和node2中for (int i = 0; i < MINSIZE; i++) {p->setKey(a[i].k, i);p->setBlock(a[i].num, i);}p->size = MINSIZE;int count = 0;for (int i = MINSIZE; i < RANK + 1; i++) {newNode->setKey(a[i].k, count);newNode->setBlock(a[i].num, count++);}newNode->size = RANK - MINSIZE + 1;//维护双向链表newNode->next = p->next;newNode->last = p->id;if (p->next!=-1) {static_cast<leafNode*>(node[p->next])->last = newNode->id;}p->next = newNode->id;internalNode* parent = nullptr;internalNode* newNode2 = nullptr;treeNode** Node = new treeNode*[RANK + 2];treeNode* t = p;while (t != nullptr) {if(t->parent!=-1)parent = static_cast<internalNode*>(node[t->parent]);else parent = nullptr;if (!newNode2) {if (parent) {leafNode* tmp = static_cast<leafNode*>(node[parent->getChild(0)]);for (int i = 0; i<parent->size + 2; i++) {Node[i] = tmp;if(tmp->next!=-1)tmp = static_cast<leafNode*>(node[tmp->next]);}}else {Node[0] = t;Node[1] = newNode;}}else {if (parent) {int count = 0;//2bool flag = false;internalNode* tmp = nullptr;for (int i = 0; i <parent->size + 2; i++) {if (count<parent->size + 1)tmp = static_cast<internalNode*>(node[parent->child[count]]);if (tmp!=nullptr&&!flag && (newNode2->key[0] < tmp->key[0] || i == parent->size + 1)) {Node[i] = newNode2;flag = true;}else {Node[i] = node[parent->child[count++]];}}}else {Node[0] = t;Node[1] = newNode2;}}//case 1: 当前结点是根节点,根节点长高  if (!parent) {internalNode* r = new internalNode(1);node[cnt] = r;r->id = cnt;cnt++;for (int i = 0; i < 2; i++) {r->child[i] = Node[i]->id;node[r->child[i]]->parent = r->id;}r->key[0] = findKey(node[r->child[1]]);root = r;root->parent = -1;break;}//case 2 :当前结点的父节点不满  else if (parent->size < RANK) {//printf("case 2 :当前结点的父节点不满 \n");for (int i = 0; i < parent->size + 2; i++) {parent->child[i] = Node[i]->id;node[parent->child[i]]->parent = parent->id;}for (int i = 0; i < parent->size + 1; i++) {parent->key[i] = findKey(node[parent->child[i + 1]]);}parent->size++;//printf("quit\n");break;}//case 3 :当前父节点已满,分裂父节点  else if (parent->size == RANK) {//printf("case 3 :当前父节点已满,分裂父节点\n");newNode2 = new internalNode(RANK - MINSIZE);node[cnt] = newNode2;newNode2->id = cnt;cnt++;for (int i = 0; i < MINSIZE + 1; i++) {parent->child[i] = Node[i]->id;node[parent->child[i]]->parent = parent->id;}for (int i = 0; i < MINSIZE; i++) {parent->key[i] = findKey(node[parent->child[i + 1]]);}parent->size = MINSIZE;int count = 0;for (int i = MINSIZE + 1; i < RANK + 2; i++) {newNode2->child[count] = Node[i]->id;node[newNode2->child[count++]]->parent = newNode2->id;}count = 0;for (int i = MINSIZE + 1; i < RANK + 1; i++) {newNode2->key[count] = findKey(node[newNode2->child[count + 1]]);count++;}t = parent;}}}return;}void Delete(T x){//找到叶结点  Index index = findLeafNode(x, del);if (index == -1)return;leafNode* p = static_cast<leafNode*>(node[index]);//("index = %d\n", index);if (!p)return;T past;//原来的索引值past = p->key[0];//找到所在下标int j = -1;for (int i = 0; i < p->size; i++) {if (x == p->getKey(i)) {j = i;break;}}//用后面的值填补删除值的位置if (j == -1) { return; }for (int i = j + 1; i < p->size; i++) {p->setKey(p->getKey(i), i - 1);p->setBlock(p->getBlock(i), i - 1);}p->size--;//删除后大小仍然大于最小值if (p->size >= MINSIZE) {//printf("here\n");if(p->parent!=-1)updateIndex(p, x);//更新值为x的索引return;//可能影响了父节点的索引}else if (p == root) {if (p->size == 0)root = nullptr;return;}//向左借元素if (p->last != 0 && node[p->last]->size >MINSIZE) {//printf("1向左借元素\n");if(p->parent!=-1)updateIndex(p, x);//更新值为x的索引for (int i = MINSIZE - 1; i > 0; i--) {p->key[i] = p->key[i - 1];p->blockNum[i] = p->blockNum[i - 1];}//挪出一个位置p->key[0] = node[p->last]->getKey(node[p->last]->size - 1);p->blockNum[0] = node[p->last]->getBlock(node[p->last]->size-1);//将左节点的值放到挪出的位置T z = p->key[0];//新的索引值T y = p->key[1];//原来的索引值node[p->last]->size--;//左节点的大小减一p->size++;//该结点的大小加一updateIndex(p, z, y);//将原来的索引值更新为新的索引值return;}//向右借元素else if (p->next!=-1 &&node[p->next]->size>MINSIZE) {//printf("1向右借元素\n");updateIndex(p, x);//更新值为x的索引T y = node[p->next]->getKey(0);//原来的索引值T z = node[p->next]->getKey(1);//新的索引值p->key[MINSIZE - 1] = node[p->next]->getKey(0);//将右结点的元素放到后面p->blockNum[MINSIZE - 1] = node[p->next]->getBlock(0);p->size++;//该结点元素数加一for (int i = 0; i < node[p->next]->size - 1; i++) {node[p->next]->setKey(node[p->next]->getKey(i + 1),i);node[p->next]->setBlock(node[p->next]->getBlock(i + 1),i);}//右结点的元素向左挪动node[p->next]->size--;//下一个结点数减一updateIndex(node[p->next], z, y);//将原来的索引值更新为新的索引值return;}else {internalNode* t = nullptr;//当前结点  //向左合并int count = 0;if (p->last != 0 && node[p->last]->size + p->size <= RANK) {//printf("1向左合并\n");t = static_cast<internalNode*>(node[p->parent]);for (int i = node[p->last]->size; i < node[p->last]->size + p->size; i++) {node[p->last]->setKey(p->key[count],i);node[p->last]->setBlock(p->blockNum[count++],i);}//将当前结点的值转移到左节点中node[p->last]->size = node[p->last]->size + p->size;//更新左节点的大小//维护双向链表node[p->last]->setNext(p->next);if (p->next!=-1) node[p->next]->setLast(p->last);//更新p的指针,防止空指针p->parent = -1;p->next = -1;p->last = -1;delete p;}//向右合并else if (p->next!=-1 && node[p->next]->size + p->size <= RANK) {//printf("1向右合并\n");count = 0;past = node[p->next]->getKey(0); //合并前,记录原来的索引值t = static_cast<internalNode*>(node[node[p->next]->parent]);for (int i = p->size; i < node[p->next]->size + p->size; i++) {p->setKey(node[p->next]->getKey(count),i);p->setBlock(node[p->next]->getBlock(count++),i);} //将右结点的值转移到当前结点p->size = node[p->next]->size + p->size;//更新当前结点的大小//维护双向链表if (node[p->next]->getNext() != -1)node[node[p->next]->getNext()]->setLast(p->id);leafNode* tmp = static_cast<leafNode*>(node[p->next]);p->next = node[p->next]->getNext();//更新p->next的指针tmp->parent = -1;tmp->next = -1;tmp->last = -1;delete tmp;}t->size--;//更新updateChild(t, past);updateIndex(t, past);int index = -1;while (t != nullptr) {internalNode* parent;if(t->parent!=-1)parent = static_cast<internalNode*>(node[t->parent]);//计算得到父母  //case 1:当前结点为根节点else parent = nullptr;if (!parent) {if (t->size == 0) {root = node[t->child[0]];root->parent = -1;}break;}//case 2:当前结点大于最小结点数else if (t->size >= MINSIZE - 1) {if (index != -1) {for (int i = index; i < t->size + 1; i++) {t->child[i] = t->child[i + 1];}}break;}//case 3:当前结点小于最小结点数else if (t->size < MINSIZE - 1) {//updateChild(t, z);internalNode* sibling;//如果邻居的大小大于等于MINSIZEint last = -1, next = 1, now = 0;if (t->key[0] >= parent->key[0]) {for (int i = 0; i < parent->size; i++) {if (t->key[0] < parent->key[i]) {last = i - 1;now = i;next = i + 1;break;}else if (i == parent->size - 1) {last = parent->size - 1;now = parent->size;next = parent->size + 1;}}}if (last >= 0) {sibling = static_cast<internalNode*>(node[parent->child[last]]);//向左借节点if (sibling->size >= MINSIZE) {//printf("向左借元素\n");for (int i = t->size + 1; i >= 1; i--) {t->child[i] = t->child[i - 1];}for (int i = t->size; i >= 1; i--) {t->key[i] = t->key[i - 1];}t->child[0] = node[sibling->child[sibling->size]]->id;node[t->child[0]]->parent = t->id;t->key[0] = findKey(node[t->child[1]]);//更新父节点node[t->parent]->setKey(findKey(node[node[t->parent]->getChild(now)]), last);sibling->child[sibling->size] = -1;sibling->size--;t->size++;break;}//与左节点合并else if (t->size + sibling->size + 1 <= RANK) {//printf("与左节点合并\n");int count = 0;for (int i = sibling->size + 1; i < t->size + sibling->size + 2; i++) {sibling->child[i] = t->child[count++];node[sibling->child[i]]->parent = sibling->id;}for (int i = sibling->size; i < t->size + sibling->size + 1; i++) {sibling->key[i] = findKey(node[sibling->child[i + 1]]);}sibling->size = t->size + sibling->size + 1;t->parent = -1;delete t;for (int i = now; i < parent->size; i++) {parent->child[i] = parent->child[i + 1];}for (int i = last; i < parent->size - 1; i++) {parent->key[i] = findKey(node[parent->child[i + 1]]);}parent->size--;t = parent;}}else if (next <= RANK + 1) {sibling = static_cast<internalNode*>(node[parent->child[next]]);//向右借结点if (sibling->size >= MINSIZE) {//printf("向右借结点\n");t->child[t->size + 1] = sibling->child[0];node[t->child[t->size + 1]]->parent = t->id;t->key[t->size] = findKey(node[t->child[t->size + 1]]);for (int i = 0; i < sibling->size; i++) {sibling->child[i] = sibling->child[i + 1];}for (int i = 0; i < sibling->size - 1; i++) {sibling->key[i] = findKey(node[sibling->child[i + 1]]);}node[t->parent]->setKey(findKey(node[node[t->parent]->getChild(next)]), now);sibling->child[sibling->size] = -1;sibling->size--;t->size++;break;}//与右结点合并else if (t->size + sibling->size + 1 <= RANK) {//printf("与右节点合并\n");int count = 0;for (int i = t->size + 1; i < t->size + sibling->size + 2; i++) {t->child[i] = sibling->child[count++];node[t->child[i]]->parent = t->id;}//count = 0;for (int i = t->size; i < t->size + sibling->size + 1; i++) {t->key[i] = findKey(node[t->child[i + 1]]);}t->size = t->size + sibling->size + 1;sibling->parent = -1;delete sibling;for (int i = next; i < parent->size; i++) {parent->child[i] = parent->child[i + 1];}for (int i = now; i < parent->size - 1; i++) {parent->key[i] = findKey(node[parent->getChild(i + 1)]);}parent->size--;t = parent;}}}}}}void at(int index) {leafNode* tmp = childNode;for (int i = 0; i < index + 1; i++) {tmp = tmp->next;}for (int i = 0; i < tmp->size; i++) {std::cout << tmp->getKey(i) << " ";}std::cout << std::endl;}std::string getName()       //打印出模板参数的类型名{return typeid(T).name();}void print() {//printf("sizeof int = %d\n", sizeof(int));//printf("size = %d\n",sizeof(leafNode));if (!root)return;bool flag = false;treeNode* tmp;std::cout << RANK << " ";std::cout << typeid(T).name();front = (front + 1) % 10000;queue[front] = root;int cur = 1;int curnum = 1;int nextnum = 0;while (front != rear) {rear = (rear + 1) % 10000;tmp = queue[rear];if (tmp->getType() == nonleaf) {std::cout << "[";internalNode* t = static_cast<internalNode*>(tmp);curnum--;std::cout << tmp->getType() << " ";if (tmp->parent != -1) {std::cout << node[tmp->parent]->id << " ";}else std::cout << "-1 ";std::cout << t->id << " ";std::cout << tmp->size << " ";for (int i = 0; i < tmp->size - 1; i++) {std::cout << tmp->getKey(i) << " ";}std::cout << tmp->getKey(tmp->size - 1) << " ";;for (int i = 0; i < tmp->size + 1; i++) {if (i == tmp->size) {if (t->child[i] != -1) {std::cout << node[t->child[i]]->id << "]";front = (front + 1) % 10000;queue[front] = node[t->child[i]];nextnum++;}else std::cout << "-1]";}else {if (t->child[i] != -1) {std::cout << node[t->child[i]]->id << " ";front = (front + 1) % 10000;queue[front] = node[t->child[i]];nextnum++;}else std::cout << "-1 ";}}if (curnum == 0) {cur++;curnum = nextnum;nextnum = 0;}}else {std::cout << "[";std::cout << tmp->getType() << " ";if (tmp->parent != -1) {std::cout << node[tmp->parent]->id << " ";}else std::cout << "-1 ";std::cout << tmp->id << " ";std::cout << tmp->size << " ";std::cout << tmp->getLast() << " " << tmp->getNext() << " ";for (int i = 0; i < tmp->size - 1; i++) {std::cout << tmp->getBlock(i) << " ";}std::cout << tmp->getBlock(tmp->size - 1) << " ";for (int i = 0; i < tmp->size - 1; i++) {std::cout << tmp->getKey(i) << " ";}std::cout << tmp->getKey(tmp->size - 1) << "]";}}}void save() {bool flag = false;treeNode* tmp;std::ofstream out(tableName+".txt", std::ios_base::out);out << RANK << " ";out << TYPE ;if (!root)return;front = (front + 1) % 10000;queue[front] = root;int cur = 1;int curnum = 1;int nextnum = 0;while (front != rear) {rear = (rear + 1) % 10000;tmp = queue[rear];if (tmp->getType() == nonleaf) {out << "[";internalNode* t = static_cast<internalNode*>(tmp);curnum--;out << tmp->getType()<<" ";if (tmp->parent!=-1) {out << node[tmp->parent]->id<<" ";}else out << "-1 ";out << t->id << " ";out << tmp->size << " ";for (int i = 0; i < tmp->size - 1; i++) {        out << tmp->getKey(i)<<" ";}out<<tmp->getKey(tmp->size - 1) << " ";;for (int i = 0; i < tmp->size + 1; i++) {if (i == tmp->size) {if (t->child[i] != -1) {out << node[t->child[i]]->id << "]";front = (front + 1) % 10000;queue[front] = node[t->child[i]];nextnum++;}else out << "-1]";}else {if (t->child[i] != -1) {out << node[t->child[i]]->id << " ";front = (front + 1) % 10000;queue[front] = node[t->child[i]];nextnum++;}else out << "-1 ";}}if (curnum == 0) {cur++;curnum = nextnum;nextnum = 0;}}else {out << "[";out << tmp->getType() << " ";if (tmp->parent!=-1) {out << node[tmp->parent]->id << " ";}else out << "-1 ";out << tmp->id << " ";out << tmp->size << " ";out << tmp->getLast() << " " << tmp->getNext() << " ";for (int i = 0; i < tmp->size - 1; i++) {out << tmp->getBlock(i) << " ";}out << tmp->getBlock(tmp->size - 1) << " ";for (int i = 0; i < tmp->size - 1; i++) {out << tmp->getKey(i) << " ";}out << tmp->getKey(tmp->size - 1) << "]";}}out.close();}void loadFloat(std::string s) {treeNode* p = nullptr;int j = 0;std::string str = "";int count = 0;if (s[0] == '0') {p = new internalNode(RANK);for (int i = 2; i <= s.length(); i++) {if (s[i] != ' '&&s[i] != ']'&&s[i] != '['&&i != s.length()) {str = str + s[i];}else {if (count == 0) {p->parent = std::atoi(str.c_str());str = "";count++;}else if (count == 1) {p->id = std::atoi(str.c_str());node[p->id] = p;str = "";count++;}else if (count == 2) {p->size = std::atoi(str.c_str());str = "";count++;}else if (count == 3) {if (getName() == "float") {p->setKey(std::atof(str.c_str()), j);str = "";j++;}if (j == p->size) {j = 0;count++;}}else if (count == 4) {p->setChild(std::atoi(str.c_str()), j);str = "";j++;if (j == p->size + 1) {j = 0;count = 0;break;}}}}}else if (s[0] == '1') {p = new leafNode(RANK);for (int i = 2; i <= s.length(); i++) {if (s[i] != ' '&&s[i] != ']'&&s[i] != '['&&i != s.length()) {str = str + s[i];}else {if (count == 0) {p->parent = std::atoi(str.c_str());str = "";count++;}else if (count == 1) {p->id = std::atoi(str.c_str());node[p->id] = p;str = "";count++;}else if (count == 2) {p->size = std::atoi(str.c_str());str = "";count++;}else if (count == 3) {p->setLast(std::atoi(str.c_str()));str = "";count++;}else if (count == 4) {p->setNext(std::atoi(str.c_str()));count++;str = "";}else if (count == 5) {p->setBlock(std::atoi(str.c_str()), j);j++;str = "";if (j == p->size) {j = 0;count++;}}else if (count == 6) {if (getName() == "float") {p->setKey(std::atof(str.c_str()), j);str = "";j++;}str = "";if (j == p->size) {j = 0;count = 0;break;}}}}}if (!root) {printf("here\n");if (p->getType() == nonleaf) {root = new internalNode(RANK);root = p;}else {root = new leafNode(RANK);root = p;}}}void loadString(std::string s) {treeNode* p = nullptr;int j = 0;std::string str = "";int count = 0;if (s[0] == '0') {p = new internalNode(RANK);for (int i = 2; i <= s.length(); i++) {if (s[i] != ' '&&s[i] != ']'&&s[i] != '['&&i != s.length()) {str = str + s[i];}else {if (count == 0) {p->parent = std::atoi(str.c_str());str = "";count++;}else if (count == 1) {p->id = std::atoi(str.c_str());node[p->id] = p;str = "";count++;}else if (count == 2) {p->size = std::atoi(str.c_str());str = "";count++;}else if (count == 3) {if (getName() == "string") {p->setKey(str, j);str = "";j++;}if (j == p->size) {j = 0;count++;}}else if (count == 4) {p->setChild(std::atoi(str.c_str()), j);str = "";j++;if (j == p->size + 1) {j = 0;count = 0;break;}}}}}else if (s[0] == '1') {p = new leafNode(RANK);for (int i = 2; i <= s.length(); i++) {if (s[i] != ' '&&s[i] != ']'&&s[i] != '['&&i != s.length()) {str = str + s[i];}else {if (count == 0) {p->parent = std::atoi(str.c_str());str = "";count++;}else if (count == 1) {p->id = std::atoi(str.c_str());node[p->id] = p;str = "";count++;}else if (count == 2) {p->size = std::atoi(str.c_str());str = "";count++;}else if (count == 3) {p->setLast(std::atoi(str.c_str()));str = "";count++;}else if (count == 4) {p->setNext(std::atoi(str.c_str()));count++;str = "";}else if (count == 5) {p->setBlock(std::atoi(str.c_str()), j);j++;str = "";if (j == p->size) {j = 0;count++;}}else if (count == 6) {if (getName() == "string") {p->setKey(str, j);str = "";j++;}str = "";if (j == p->size) {j = 0;count = 0;break;}}}}}if (!root) {if (p->getType() == nonleaf) {root = new internalNode(RANK);root = p;}else {root = new leafNode(RANK);root = p;}}}void loadInt(std::string s) {treeNode* p = nullptr;int j = 0;std::string str = "";int count = 0;if (s[0] == '0') {p = new internalNode(RANK);for (int i = 2; i <= s.length(); i++) {if (s[i] != ' '&&s[i]!=']'&&s[i]!='['&&i!=s.length()) {str = str + s[i];}else{if (count == 0) {p->parent = std::atoi(str.c_str());str = "";count++;}else if (count == 1) {p->id = std::atoi(str.c_str());node[p->id] = p;str = "";count++;}else if (count == 2) {p->size = std::atoi(str.c_str());str = "";count++;}else if (count == 3) {if (getName() == "int") {T x = std::atoi(str.c_str());p->setKey(x, j);str = "";j++;}if (j == p->size) {j = 0;count++;}}else if (count == 4) {p->setChild(std::atoi(str.c_str()),j);str = "";j++;if (j == p->size+1) {j = 0;count = 0;break;}}}}}else if (s[0] == '1') {p = new leafNode(RANK);for (int i = 2; i <= s.length(); i++) {if (s[i] != ' '&&s[i] != ']'&&s[i] != '['&&i != s.length()) {str = str + s[i];}else {if (count == 0) {p->parent = std::atoi(str.c_str());str = "";count++;}else if (count == 1) {p->id = std::atoi(str.c_str());node[p->id] = p;str = "";count++;}else if (count == 2) {p->size = std::atoi(str.c_str());str = "";count++;}else if (count == 3) {p->setLast(std::atoi(str.c_str()));str = "";count++;}else if (count == 4) {p->setNext(std::atoi(str.c_str()));count++;str = "";}else if (count == 5) {p->setBlock(std::atoi(str.c_str()), j);j++;str = "";if (j == p->size) {j = 0;count++;}}else if (count == 6) {if (getName() == "int") {p->setKey(std::atoi(str.c_str()), j);str = "";j++;}if (j == p->size) {j = 0;count = 0;break;}}}}}if (!root) {if (p->getType() == nonleaf) {root = new internalNode(RANK);root = p;}else {root = new leafNode(RANK);root = p;}}}int equal(T x) {  //找到x所在的叶结点treeNode *p = root;Index j = 1;if (!p)return -1;while (p->getType() == nonleaf) {//在已知p为内部结点时,向下造型为内部结点internalNode* t = dynamic_cast<internalNode*>(p);if (x < t->getKey(0)) {j = t->getChild(0);p = node[j];}else {for (int i = 0; i < t->size - 1; i++) {if (x >= t->getKey(i) && x < t->getKey(i + 1)) {j = t->child[i + 1];p = node[j];break;}}if (x >= t->getKey(t->size - 1)) {j = t->child[t->size];p = node[j];}}}for (int i= 0; i < p->size; i++) {if (p->getKey(i) == x) {return p->getBlock(i);}}return -1;}void larger(int* buffer,T x) {int count = 0;leafNode *p = findLeafNode(x);while (1) {for (int i = 0; i < p->size; i++) {if (p->getKey(i)>x) {buffer[++count] = p->getBlock(i);}}if(p->next!=-1)p = static_cast<leafNode*>(node[p->next]);else break;}buffer[0] = count;}void smaller(int* buffer, T x) {int count = 0;leafNode *p = findLeafNode(x);while (1) {for (int i = 0; i < p->size; i++) {if (p->getKey(i)<x) {buffer[++count] = p->getBlock(i);}}if (p->last != 0)p = static_cast<leafNode*>(node[p->last]);else break;}buffer[0] = count;}void largerAndEqual(int* buffer, T x) {int count = 0;leafNode *p = findLeafNode(x);while (1) {for (int i = 0; i < p->size; i++) {if (p->getKey(i)>=x) {buffer[++count] = p->getBlock(i);}}if (p->next != -1)p = static_cast<leafNode*>(node[p->next]);else break;}buffer[0] = count;}void smallerAndEqual(int* buffer, T x) {int count = 0;leafNode *p = findLeafNode(x);while (1) {for (int i = 0; i < p->size; i++) {if (p->getKey(i)<=x) {buffer[++count] = p->getBlock(i);}}if (p->last != 0)p = static_cast<leafNode*>(node[p->last]);else break;}buffer[0] = count;}void deleteLarger(T x) {int count = 0;T buffer[30000];leafNode *p = findLeafNode(x);while (1) {for (int i = 0; i < p->size; i++) {if (p->getKey(i)>x) {buffer[++count] = p->getKey(i);}}if (p->next != -1)p = static_cast<leafNode*>(node[p->next]);else break;}for (int i = 1; i <= count; i++) {Delete(buffer[i]);}}void deleteSmaller(T x) {int count = 0;T buffer[30000];leafNode *p = findLeafNode(x);while (1) {for (int i = 0; i < p->size; i++) {if (p->getKey(i)<x) {buffer[++count] = p->getKey(i);}}if (p->last != 0)p = static_cast<leafNode*>(node[p->last]);else break;}for (int i = 1; i <= count; i++) {Delete(buffer[i]);}}void deleteLargerAndEqual(T x) {int count = 0;T buffer[30000];leafNode *p = findLeafNode(x);while (1) {for (int i = 0; i < p->size; i++) {if (p->getKey(i)>=x) {buffer[++count] = p->getKey(i);}}if (p->next != -1)p = static_cast<leafNode*>(node[p->next]);else break;}for (int i = 1; i <= count; i++) {Delete(buffer[i]);}}void deleteSmallerAndEqual(T x) {int count = 0;T buffer[30000];leafNode *p = findLeafNode(x);while (1) {for (int i = 0; i < p->size; i++) {if (p->getKey(i)<=x) {buffer[++count] = p->getKey(i);}}if (p->last != 0)p = static_cast<leafNode*>(node[p->last]);else break;}for (int i = 1; i <= count; i++) {Delete(buffer[i]);}}};#endif


main,cpp


#include"BPlusTree.h"#include<stdlib.h>#include<time.h>int main(){srand(unsigned(time(nullptr)));BPlusTree<int> *p = new BPlusTree<int>(10,"dB1","int");for (int i = 0; i <10000; i++) {//int x = rand() % 10000000;int x = i;p->insert(x,i); }p->print();p->save();for (int i = 0; i <10000; i++) {//int x = rand() % 10000000;int x = i;p->Delete(x);}printf("\n-------------------------------\n");    p->print();system("pause");}

部分接口


#define _CRT_SECURE_NO_WARNINGS #include "BPlusTree.h"#include<cstdlib>#include<cstdio>#include<iostream>#include<fstream>#include<string>BPlusTree<int> *p1 = nullptr;BPlusTree<float> *p2 = nullptr;BPlusTree<std::string> *p3 = nullptr;std::string type = "";int RANK;//删除返回blockNum//int* select(std::string tableName,int operation,T element);void selectInt(int *buffer, std::string tableName, int op, int element){std::string path = tableName;load(path);if (op == 0) {//等于int ans = p1->equal(element);buffer[0] = 1;buffer[1] = ans;}else if (op == 1) {//大于p1->larger(buffer, element);}else if (op == 2) {//大于等于p1->largerAndEqual(buffer, element);}else if (op == 3) {//小于p1->smaller(buffer, element);}else if (op == 4) {//小于等于p1->smallerAndEqual(buffer, element);}}void selectFloat(int *buffer, std::string tableName, int op, float element){std::string path = tableName;load(path);if (op == 0) {//等于int ans = p1->equal(element);buffer[0] = 1;buffer[1] = ans;}else if (op == 1) {//大于p2->larger(buffer, element);}else if (op == 2) {//大于等于p2->largerAndEqual(buffer, element);}else if (op == 3) {//小于p2->smaller(buffer, element);}else if (op == 4) {//小于等于p2->smallerAndEqual(buffer, element);}}void selectString(int *buffer, std::string tableName, int op, std::string element){std::string path = tableName;load(path);if (op == 0) {//等于int ans = p3->equal(element);buffer[0] = 1;buffer[1] = ans;}else if (op == 1) {//大于p3->larger(buffer, element);}else if (op == 2) {//大于等于p3->largerAndEqual(buffer, element);}else if (op == 3) {//小于p3->smaller(buffer, element);}else if (op == 4) {//小于等于p3->smallerAndEqual(buffer, element);}}void createTree(std::string tableName, std::string type, int size){RANK = (4096 - 5 * sizeof(int)) / (2 * size);if (type == "int") {p1 = new BPlusTree<int>(RANK, tableName, type);p1->save();}else if (type == "float") {p2 = new BPlusTree<float>(RANK, tableName, type);p2->save();}else if (type == "string") {p3 = new BPlusTree<std::string>(RANK, tableName, type);p3->save();}}void deleteInt(std::string tableName, int op, int data){std::string path = tableName;load(path);if (op == 0) {//等于p1->Delete(data);}else if (op == 1) {//大于p1->deleteLarger(data);}else if (op == 2) {//大于等于p1->deleteLargerAndEqual(data);}else if (op == 3) {//小于p1->deleteSmaller(data);}else if (op == 4) {//小于等于p1->deleteSmallerAndEqual(data);}p1->save();}void deleteFloat(std::string tableName, int op, float data){std::string path = tableName;load(path);if (op == 0) {//等于p2->Delete(data);}else if (op == 1) {//大于p2->deleteLarger(data);}else if (op == 2) {//大于等于p2->deleteLargerAndEqual(data);}else if (op == 3) {//小于p2->deleteSmaller(data);}else if (op == 4) {//小于等于p2->deleteSmallerAndEqual(data);}p2->save();}void deleteString(std::string tableName, int op, std::string data){std::string path = tableName;load(path);if (op == 0) {//等于p3->Delete(data);}else if (op == 1) {//大于p3->deleteLarger(data);}else if (op == 2) {//大于等于p3->deleteLargerAndEqual(data);}else if (op == 3) {//小于p3->deleteSmaller(data);}else if (op == 4) {//小于等于p3->deleteSmallerAndEqual(data);}p3->save();}void dropTable(const char* tableName){remove(tableName);}//dropTable(string tableName);BPlusTree<int>* getIndexInt(std::string indexName){int RANK = (4096 - 5 * sizeof(int)) / (2 * sizeof(int));p1 = new BPlusTree<int>(RANK, indexName + ".txt", "int");p1->save();return p1;}BPlusTree<float>* getIndexFloat(std::string indexName){int RANK = (4096 - 5 * sizeof(int)) / (2 * sizeof(float));p2 = new BPlusTree<float>(RANK, indexName + ".txt", "float");p2->save();return p2;}BPlusTree<std::string>* getIndexString(std::string indexName, int size){int RANK = (4096 - 5 * sizeof(int)) / (2 * size);p3 = new BPlusTree<std::string>(RANK, indexName + ".txt", "string");p3->save();return p3;}//select id > 3//select(std::string tableName, op operation);bool isKeyInt(std::string tableName, int data){std::string path = tableName;load(path);return p1->isKey(data);}bool isKeyFloat(std::string tableName, float data){std::string path = tableName;load(path);// load(path);return p2->isKey(data);}bool isKeyString(std::string tableName, std::string data){std::string path = tableName;load(path);if (!p3)std::cout << "no" << std::endl;return p3->isKey(data);}void insertInt(std::string tableName, int data, int offset){std::string path = tableName;load(path);p1->insert(data, offset);p1->save();}void insertFloat(std::string tableName, float data, int offset){std::string path = tableName;load(path);p2->insert(data, offset);p2->save();}void insertString(std::string tableName, std::string data, int offset){std::string path = tableName;load(path);p3->insert(data, offset);p3->save();}



0 0
原创粉丝点击