B+ tree 的特点
(1)在叶子节点存储value,其他的存储key
(2)普通的node(非叶子和根)child的个数>=key的个数
m==5 则key个数=[m/2, m-1],也就是[2,4],child的个数>=key的个数,[2,5]
insert 操作
(1)找到合适的叶子节点,执行(2)
(2)在叶子节点进行插入,执行(3)
(3)判断该叶子节点key的数量是否超过最大值,不超过则结束,否则(4)
(4)均分该叶子节点,并上移中间的key的值到父节点,现在处理的节点变成父节点,跳到(3),一直循环,直到处理节点的父节点keysize大小合适
插入{5,8,10,15,16,17,18, 19,20,21,22,6,9,7};
[+] log construction, can use it C:\Desktop\t\PaintTree/_log/log.html
[0]06:15:59[info][5864] [Start::doSomething] test 1 (Start.cpp:29)
[1]06:15:59[info][5864] [Start::doSomething] insert start (Start.cpp:30)
[2]06:15:59[test][5864] [BPTree<int,char>::insert] insert _key: 5 _value: E (BPTree.h:65)
[3]06:15:59[debg][5864] [BPTree<int,char>::insert] find leaf (BPTree.h:67)
[4]06:15:59[debg][5864] [BPTree<int,char>::insert] insert node, <(5:E),> (BPTree.h:78)
[5]06:15:59[debg][5864] [BPTree<int,char>::insert] all tree :
<(5:E),P:>
(BPTree.h:81)
[6]06:15:59[test][5864] [BPTree<int,char>::insert] insert _key: 8 _value: H (BPTree.h:65)
[7]06:15:59[debg][5864] [BPTree<int,char>::insert] find leaf <(5:E),> (BPTree.h:67)
[8]06:15:59[test][5864] [BPTree<int,char>::insert] <(5:E),> loc: 1 _key: 8 _value: H is_exist_key: 0 (BPTree.h:75)
[9]06:15:59[debg][5864] [BPTree<int,char>::insert] insert node, <(5:E),(8:H),> (BPTree.h:78)
[10]06:15:59[debg][5864] [BPTree<int,char>::insert] all tree :
<(5:E),(8:H),P:>
(BPTree.h:81)
[11]06:16:00[test][5864] [BPTree<int,char>::insert] insert _key: 10 _value: J (BPTree.h:65)
[12]06:16:00[debg][5864] [BPTree<int,char>::insert] find leaf <(5:E),(8:H),> (BPTree.h:67)
[13]06:16:00[test][5864] [BPTree<int,char>::insert] <(5:E),(8:H),> loc: 2 _key: 10 _value: J is_exist_key: 0 (BPTree.h:75)
[14]06:16:00[debg][5864] [BPTree<int,char>::insert] insert node, <(5:E),(8:H),(10:J),> (BPTree.h:78)
[15]06:16:00[debg][5864] [BPTree<int,char>::insert] all tree :
<(5:E),(8:H),(10:J),P:>
(BPTree.h:81)
[16]06:16:00[test][5864] [BPTree<int,char>::insert] insert _key: 15 _value: O (BPTree.h:65)
[17]06:16:00[debg][5864] [BPTree<int,char>::insert] find leaf <(5:E),(8:H),(10:J),> (BPTree.h:67)
[18]06:16:00[test][5864] [BPTree<int,char>::insert] <(5:E),(8:H),(10:J),> loc: 3 _key: 15 _value: O is_exist_key: 0 (BPTree.h:75)
[19]06:16:00[debg][5864] [BPTree<int,char>::insert] insert node, <(5:E),(8:H),(10:J),(15:O),> (BPTree.h:78)
[20]06:16:00[debg][5864] [BPTree<int,char>::insert] all tree :
<(5:E),(8:H),(10:J),(15:O),P:>
(BPTree.h:81)
[21]06:16:00[test][5864] [BPTree<int,char>::insert] insert _key: 16 _value: P (BPTree.h:65)
[22]06:16:00[debg][5864] [BPTree<int,char>::insert] find leaf <(5:E),(8:H),(10:J),(15:O),> (BPTree.h:67)
[23]06:16:00[test][5864] [BPTree<int,char>::insert] <(5:E),(8:H),(10:J),(15:O),> loc: 4 _key: 16 _value: P is_exist_key: 0 (BPTree.h:75)
[24]06:16:00[debg][5864] [BPTree<int,char>::insert] insert node, <(5:E),(8:H),(10:J),(15:O),(16:P),> (BPTree.h:78)
[25]06:16:00[debg][5864] [BPTree<int,char>::adjustmentNodeAfterInsert] getNodeInfo(left_node): <(5:E),(8:H),> move_up_key: 8 getNodeInfo(right_node): <(10:J),(15:O),(16:P),> (BPTree.h:131)
[26]06:16:00[debg][5864] [BPTree<int,char>::insert] all tree :
<8,P:>
<(5:E),(8:H),P:<8,>> <(10:J),(15:O),(16:P),P:<8,>>
(BPTree.h:81)
[27]06:16:00[test][5864] [BPTree<int,char>::insert] insert _key: 17 _value: Q (BPTree.h:65)
[28]06:16:00[debg][5864] [BPTree<int,char>::insert] find leaf <(10:J),(15:O),(16:P),> (BPTree.h:67)
[29]06:16:00[test][5864] [BPTree<int,char>::insert] <(10:J),(15:O),(16:P),> loc: 3 _key: 17 _value: Q is_exist_key: 0 (BPTree.h:75)
[30]06:16:00[debg][5864] [BPTree<int,char>::insert] insert node, <(10:J),(15:O),(16:P),(17:Q),> (BPTree.h:78)
[31]06:16:00[debg][5864] [BPTree<int,char>::insert] all tree :
<8,P:>
<(5:E),(8:H),P:<8,>> <(10:J),(15:O),(16:P),(17:Q),P:<8,>>
(BPTree.h:81)
[32]06:16:00[test][5864] [BPTree<int,char>::insert] insert _key: 18 _value: R (BPTree.h:65)
[33]06:16:00[debg][5864] [BPTree<int,char>::insert] find leaf <(10:J),(15:O),(16:P),(17:Q),> (BPTree.h:67)
[34]06:16:00[test][5864] [BPTree<int,char>::insert] <(10:J),(15:O),(16:P),(17:Q),> loc: 4 _key: 18 _value: R is_exist_key: 0 (BPTree.h:75)
[35]06:16:00[debg][5864] [BPTree<int,char>::insert] insert node, <(10:J),(15:O),(16:P),(17:Q),(18:R),> (BPTree.h:78)
[36]06:16:00[debg][5864] [BPTree<int,char>::adjustmentNodeAfterInsert] getNodeInfo(left_node): <(10:J),(15:O),> move_up_key: 15 getNodeInfo(right_node): <(16:P),(17:Q),(18:R),> (BPTree.h:131)
[37]06:16:00[debg][5864] [BPTree<int,char>::insert] all tree :
<8,15,P:>
<(5:E),(8:H),P:<8,15,>> <(10:J),(15:O),P:<8,15,>> <(16:P),(17:Q),(18:R),P:<8,15,>>
(BPTree.h:81)
[38]06:16:00[test][5864] [BPTree<int,char>::insert] insert _key: 19 _value: S (BPTree.h:65)
[39]06:16:00[debg][5864] [BPTree<int,char>::insert] find leaf <(16:P),(17:Q),(18:R),> (BPTree.h:67)
[40]06:16:00[test][5864] [BPTree<int,char>::insert] <(16:P),(17:Q),(18:R),> loc: 3 _key: 19 _value: S is_exist_key: 0 (BPTree.h:75)
[41]06:16:00[debg][5864] [BPTree<int,char>::insert] insert node, <(16:P),(17:Q),(18:R),(19:S),> (BPTree.h:78)
[42]06:16:00[debg][5864] [BPTree<int,char>::insert] all tree :
<8,15,P:>
<(5:E),(8:H),P:<8,15,>> <(10:J),(15:O),P:<8,15,>> <(16:P),(17:Q),(18:R),(19:S),P:<8,15,>>
(BPTree.h:81)
[43]06:16:00[test][5864] [BPTree<int,char>::insert] insert _key: 20 _value: T (BPTree.h:65)
[44]06:16:00[debg][5864] [BPTree<int,char>::insert] find leaf <(16:P),(17:Q),(18:R),(19:S),> (BPTree.h:67)
[45]06:16:00[test][5864] [BPTree<int,char>::insert] <(16:P),(17:Q),(18:R),(19:S),> loc: 4 _key: 20 _value: T is_exist_key: 0 (BPTree.h:75)
[46]06:16:00[debg][5864] [BPTree<int,char>::insert] insert node, <(16:P),(17:Q),(18:R),(19:S),(20:T),> (BPTree.h:78)
[47]06:16:00[debg][5864] [BPTree<int,char>::adjustmentNodeAfterInsert] getNodeInfo(left_node): <(16:P),(17:Q),> move_up_key: 17 getNodeInfo(right_node): <(18:R),(19:S),(20:T),> (BPTree.h:131)
[48]06:16:00[debg][5864] [BPTree<int,char>::insert] all tree :
<8,15,17,P:>
<(5:E),(8:H),P:<8,15,17,>> <(10:J),(15:O),P:<8,15,17,>> <(16:P),(17:Q),P:<8,15,17,>> <(18:R),(19:S),(20:T),P:<8,15,17,>>
(BPTree.h:81)
[49]06:16:00[test][5864] [BPTree<int,char>::insert] insert _key: 21 _value: U (BPTree.h:65)
[50]06:16:00[debg][5864] [BPTree<int,char>::insert] find leaf <(18:R),(19:S),(20:T),> (BPTree.h:67)
[51]06:16:00[test][5864] [BPTree<int,char>::insert] <(18:R),(19:S),(20:T),> loc: 3 _key: 21 _value: U is_exist_key: 0 (BPTree.h:75)
[52]06:16:00[debg][5864] [BPTree<int,char>::insert] insert node, <(18:R),(19:S),(20:T),(21:U),> (BPTree.h:78)
[53]06:16:00[debg][5864] [BPTree<int,char>::insert] all tree :
<8,15,17,P:>
<(5:E),(8:H),P:<8,15,17,>> <(10:J),(15:O),P:<8,15,17,>> <(16:P),(17:Q),P:<8,15,17,>> <(18:R),(19:S),(20:T),(21:U),P:<8,15,17,>>
(BPTree.h:81)
[54]06:16:00[test][5864] [BPTree<int,char>::insert] insert _key: 22 _value: V (BPTree.h:65)
[55]06:16:00[debg][5864] [BPTree<int,char>::insert] find leaf <(18:R),(19:S),(20:T),(21:U),> (BPTree.h:67)
[56]06:16:00[test][5864] [BPTree<int,char>::insert] <(18:R),(19:S),(20:T),(21:U),> loc: 4 _key: 22 _value: V is_exist_key: 0 (BPTree.h:75)
[57]06:16:00[debg][5864] [BPTree<int,char>::insert] insert node, <(18:R),(19:S),(20:T),(21:U),(22:V),> (BPTree.h:78)
[58]06:16:00[debg][5864] [BPTree<int,char>::adjustmentNodeAfterInsert] getNodeInfo(left_node): <(18:R),(19:S),> move_up_key: 19 getNodeInfo(right_node): <(20:T),(21:U),(22:V),> (BPTree.h:131)
[59]06:16:00[debg][5864] [BPTree<int,char>::insert] all tree :
<8,15,17,19,P:>
<(5:E),(8:H),P:<8,15,17,19,>> <(10:J),(15:O),P:<8,15,17,19,>> <(16:P),(17:Q),P:<8,15,17,19,>> <(18:R),(19:S),P:<8,15,17,19,>> <(20:T),(21:U),(22:V),P:<8,15,17,19,>>
(BPTree.h:81)
[60]06:16:00[test][5864] [BPTree<int,char>::insert] insert _key: 6 _value: F (BPTree.h:65)
[61]06:16:00[debg][5864] [BPTree<int,char>::insert] find leaf <(5:E),(8:H),> (BPTree.h:67)
[62]06:16:00[test][5864] [BPTree<int,char>::insert] <(5:E),(8:H),> loc: 1 _key: 6 _value: F is_exist_key: 0 (BPTree.h:75)
[63]06:16:00[debg][5864] [BPTree<int,char>::insert] insert node, <(5:E),(6:F),(8:H),> (BPTree.h:78)
[64]06:16:00[debg][5864] [BPTree<int,char>::insert] all tree :
<8,15,17,19,P:>
<(5:E),(6:F),(8:H),P:<8,15,17,19,>> <(10:J),(15:O),P:<8,15,17,19,>> <(16:P),(17:Q),P:<8,15,17,19,>> <(18:R),(19:S),P:<8,15,17,19,>> <(20:T),(21:U),(22:V),P:<8,15,17,19,>>
(BPTree.h:81)
[65]06:16:00[test][5864] [BPTree<int,char>::insert] insert _key: 9 _value: I (BPTree.h:65)
[66]06:16:00[debg][5864] [BPTree<int,char>::insert] find leaf <(10:J),(15:O),> (BPTree.h:67)
[67]06:16:00[test][5864] [BPTree<int,char>::insert] <(10:J),(15:O),> loc: 0 _key: 9 _value: I is_exist_key: 0 (BPTree.h:75)
[68]06:16:00[debg][5864] [BPTree<int,char>::insert] insert node, <(9:I),(10:J),(15:O),> (BPTree.h:78)
[69]06:16:00[debg][5864] [BPTree<int,char>::insert] all tree :
<8,15,17,19,P:>
<(5:E),(6:F),(8:H),P:<8,15,17,19,>> <(9:I),(10:J),(15:O),P:<8,15,17,19,>> <(16:P),(17:Q),P:<8,15,17,19,>> <(18:R),(19:S),P:<8,15,17,19,>> <(20:T),(21:U),(22:V),P:<8,15,17,19,>>
(BPTree.h:81)
[70]06:16:01[test][5864] [BPTree<int,char>::insert] insert _key: 7 _value: G (BPTree.h:65)
[71]06:16:01[debg][5864] [BPTree<int,char>::insert] find leaf <(5:E),(6:F),(8:H),> (BPTree.h:67)
[72]06:16:01[test][5864] [BPTree<int,char>::insert] <(5:E),(6:F),(8:H),> loc: 2 _key: 7 _value: G is_exist_key: 0 (BPTree.h:75)
[73]06:16:01[debg][5864] [BPTree<int,char>::insert] insert node, <(5:E),(6:F),(7:G),(8:H),> (BPTree.h:78)
[74]06:16:01[debg][5864] [BPTree<int,char>::insert] all tree :
<8,15,17,19,P:>
<(5:E),(6:F),(7:G),(8:H),P:<8,15,17,19,>> <(9:I),(10:J),(15:O),P:<8,15,17,19,>> <(16:P),(17:Q),P:<8,15,17,19,>> <(18:R),(19:S),P:<8,15,17,19,>> <(20:T),(21:U),(22:V),P:<8,15,17,19,>>
(BPTree.h:81)
图
插入5:
插入8
插入10
插入15
插入16
插入17,
插入18,
插入 19,
插入20,
插入21,
插入22,
插入6,
插入9,
插入7
void insert(const_key_type_reference _key,value_type _value) {
//1.find proper leaf
LOGXT("insert ", VAR_DATA(_key), VAR_DATA(_value));
auto [node_leaf, loc,is_exist_key] = findProperLeaf(_key);
LOGXD("find leaf", getNodeInfo(node_leaf));
if (getRoot() == nullptr) {
getRoot() = new node_type(true);
node_leaf = getRoot();
getRoot()->getKeys().emplace_back(_key);
getRoot()->getValues().emplace_back(_value);
}
else {
LOGXT(getNodeInfo(node_leaf), VAR_DATA(loc), VAR_DATA(_key), VAR_DATA(_value), VAR_DATA(is_exist_key));
leafNodeInsert(node_leaf, loc, _key, _value, is_exist_key);
}
LOGXD("insert node,",getNodeInfo(node_leaf));
adjustmentNodeAfterInsert(node_leaf);
LOGXD("all tree :", displayTree());
}
std::tuple<node_type_ptr, key_type, node_type_ptr> splitNode(node_type_ptr _node, size_type _loc) {
/// <summary>
/// loc : [1,2,3,4] ,loc=1-->2,
/// </summary>
/// <param name="_node"></param>
/// <param name="_loc"></param>
/// <returns></returns>
node_type_ptr left_node = nullptr;
node_type_ptr right_node = nullptr;
key_type move_up_key;
do {
if (_node == nullptr)break;
if (_loc == 0)break;
auto& keys = _node->getKeys();
if (keys.size() <= _loc)break;;
bool is_leaf = _node->isLeaf();
right_node = new node_type(is_leaf);
right_node->getParent() = _node->getParent();
//======================================================
move_up_key = keys[_loc-1];
(right_node->getKeys()).insert(right_node->getKeys().begin(), keys.begin() + _loc, keys.end());
keys.erase(keys.begin() + _loc, keys.end());
if (is_leaf) {
right_node->getNext() = _node->getNext();
_node->getNext() = right_node;
auto& values = _node->getValues();
(right_node->getValues()).insert(right_node->getValues().begin(), values.begin() + _loc, values.end());
values.erase(values.begin() + _loc, values.end());
}
else {
auto& values = _node->getChilds();
right_node->getChilds().insert(right_node->getChilds().begin(), values.begin() + _loc, values.end());
values.erase(values.begin() + _loc, values.end());
}
updataChildParent(left_node);
updataChildParent(right_node);
} while (false);
return std::tuple(_node, move_up_key, right_node);
}
void adjustmentNodeAfterInsert(node_type_ptr _node) {
do {
if(_node==nullptr)break;
auto& keys = _node->getKeys();
if (keys.size() <= getNodeMaxSize())break;
size_type loc = (getNodeMaxSize()+1) / 2;
auto [left_node, move_up_key, right_node] = splitNode(_node,loc);
LOGXD(VAR_DATA(getNodeInfo(left_node)), VAR_DATA(move_up_key), VAR_DATA( getNodeInfo(right_node)));
if (_node == getRoot()) {
node_type_ptr new_root = new node_type(false);
auto& new_keys = new_root->getKeys();
auto& new_childs = new_root->getChilds();
new_childs.emplace_back(left_node);
new_keys.emplace_back(move_up_key);
new_childs.emplace_back(right_node);
new_root->getParent() = nullptr;
getRoot() = new_root;
updataChildParent(new_root);
}
else {
node_type_ptr parent = _node->getParent();
auto& parent_keys = parent->getKeys();
auto& parent_childs = parent->getChilds();
auto [is_eixst,loc]= findProperKeyindex(parent, move_up_key);
parent_keys.insert(parent_keys.begin() + loc, move_up_key);
parent_childs.insert(parent_childs.begin() + loc+1, right_node);
}
adjustmentNodeAfterInsert(_node->getParent());
} while (false);
}
//tool
std::tuple<bool, size_type> findProperKeyindex(node_type_ptr _node, const_key_type_reference _key) {
/// <summary>
/// bool if exist key will true
/// size_type is proper index
/// </summary>
/// <param name="_key"></param>
/// <returns></returns>
node_type_ptr node = _node;
auto keys = node->getKeys();
const size_type len = keys.size();
bool is_exist = false;
size_type loc = -1;
if (_node == nullptr)return std::tuple(is_exist, loc);
for (size_type i = 0; i < len; i++) {
loc = i;
if (keys[i] > _key)break;
if (keys[i] == _key) { is_exist = true; break; }
if (len == i + 1)loc += 1;
}
return std::tuple(is_exist, loc);
}
std::tuple<node_type_ptr, size_type,bool> findProperLeaf(const_key_type_reference _key) {
node_type_ptr node = getRoot();
size_type loc_ = -1;
bool is_exist_key_ = false;
while (true) {
if (node == nullptr) {
loc_ = 0;
break;
}
auto [is_exist_key, loc] = findProperKeyindex(node, _key);
if (node->isLeaf()) {
loc_ = loc;
is_exist_key_ = is_exist_key;
break;
}
node = node->getChilds()[loc];
}
return std::tuple(node, loc_,is_exist_key_);
}
remove
(1)找到叶子节点中是否存在key,如果不存在,结束,否则(2)
(2)在找到的叶子节点进行删除key以及value操作,到(3)
(3)判断当前叶子节点的key size ,如果>=key_min_size ,结束,否则(4)
(4)当前叶子节点是否根节点,如果是,判断key size ==0 ,那就delete root,root=ullptr,key size !=0 则结束, 叶子节点不是根节点的话,则寻找兄弟节点,到(5)
(5)兄弟节点key size > key_min_size ,则移动兄弟节点的key ,称为x,父节点在当前节点和兄弟节点处进行x的替换,当前节点找合适位置(头或尾)进行x的添加,然后当前节点变成父节点,进入(4),兄弟节点key size <= key_min_size,进入(6)
(6)兄弟节点和当前节点合并,删除兄弟节点和两节点之间的父节点的key值,如果父节点是root且删除key之后,key size=0,则当前节点变成root,结束,否则当前节点变成父节点,进入(4)
[91]06:16:01[test][5864] [BPTree<int,char>::erase] remove key _key: 5 (BPTree.h:164)
[92]06:16:01[debg][5864] [BPTree<int,char>::erase] find getNodeInfo(node_leaf): <(5:E),(6:F),(7:G),(8:H),> (BPTree.h:170)
[93]06:16:01[debg][5864] [BPTree<int,char>::adjustmentTreeNodeAfterErase] start adjustment getNodeInfo(_node): <(6:F),(7:G),(8:H),> (BPTree.h:216)
[94]06:16:01[debg][5864] [BPTree<int,char>::adjustmentTreeNodeAfterErase] case 1: getNodeInfo(_node): <(6:F),(7:G),(8:H),> (BPTree.h:232)
[95]06:16:01[test][5864] [BPTree<int,char>::erase] remove key _key: 8 (BPTree.h:164)
[96]06:16:01[debg][5864] [BPTree<int,char>::erase] find getNodeInfo(node_leaf): <(6:F),(7:G),(8:H),> (BPTree.h:170)
[97]06:16:01[debg][5864] [BPTree<int,char>::adjustmentTreeNodeAfterErase] start adjustment getNodeInfo(_node): <(6:F),(7:G),> (BPTree.h:216)
[98]06:16:01[debg][5864] [BPTree<int,char>::adjustmentTreeNodeAfterErase] case 1: getNodeInfo(_node): <(6:F),(7:G),> (BPTree.h:232)
[99]06:16:01[test][5864] [BPTree<int,char>::erase] remove key _key: 10 (BPTree.h:164)
[100]06:16:01[debg][5864] [BPTree<int,char>::erase] find getNodeInfo(node_leaf): <(9:I),(10:J),(15:O),> (BPTree.h:170)
[101]06:16:01[debg][5864] [BPTree<int,char>::adjustmentTreeNodeAfterErase] start adjustment getNodeInfo(_node): <(9:I),(15:O),> (BPTree.h:216)
[102]06:16:01[debg][5864] [BPTree<int,char>::adjustmentTreeNodeAfterErase] case 1: getNodeInfo(_node): <(9:I),(15:O),> (BPTree.h:232)
[103]06:16:01[test][5864] [BPTree<int,char>::erase] remove key _key: 15 (BPTree.h:164)
[104]06:16:01[debg][5864] [BPTree<int,char>::erase] find getNodeInfo(node_leaf): <(9:I),(15:O),> (BPTree.h:170)
[105]06:16:01[debg][5864] [BPTree<int,char>::adjustmentTreeNodeAfterErase] start adjustment getNodeInfo(_node): <(9:I),> (BPTree.h:216)
[106]06:16:01[debg][5864] [BPTree<int,char>::adjustmentTreeNodeAfterErase] case 3,merge node to target_node:start: getNodeInfo(_node): <(9:I),> getNodeInfo(parent): <8,15,17,19,> getNodeInfo(bro_node): <(6:F),(7:G),> (BPTree.h:300)
[107]06:16:01[debg][5864] [BPTree<int,char>::adjustmentTreeNodeAfterErase] case 3,merge node to target_node:result: getNodeInfo(_node): <(6:F),(7:G),(9:I),> getNodeInfo(parent): <15,17,19,> getNodeInfo(bro_node): <> (BPTree.h:329)
[108]06:16:01[debg][5864] [BPTree<int,char>::adjustmentTreeNodeAfterErase] start adjustment getNodeInfo(_node): <15,17,19,> (BPTree.h:216)
[109]06:16:01[test][5864] [BPTree<int,char>::erase] remove key _key: 16 (BPTree.h:164)
[110]06:16:01[debg][5864] [BPTree<int,char>::erase] find getNodeInfo(node_leaf): <(16:P),(17:Q),> (BPTree.h:170)
[111]06:16:01[debg][5864] [BPTree<int,char>::adjustmentTreeNodeAfterErase] start adjustment getNodeInfo(_node): <(17:Q),> (BPTree.h:216)
[112]06:16:01[debg][5864] [BPTree<int,char>::adjustmentTreeNodeAfterErase] case 2,bro split,start: getNodeInfo(_node): <(17:Q),> getNodeInfo(parent): <15,17,19,> getNodeInfo(bro_node): <(6:F),(7:G),(9:I),> move_key: 9 (BPTree.h:269)
[113]06:16:01[debg][5864] [BPTree<int,char>::adjustmentTreeNodeAfterErase] case 2,bro split,result: getNodeInfo(_node): <(9:I),(17:Q),> getNodeInfo(parent): <7,17,19,> getNodeInfo(bro_node): <(6:F),(7:G),> move_key: 9 (BPTree.h:294)
[114]06:16:01[test][5864] [BPTree<int,char>::erase] remove key _key: 17 (BPTree.h:164)
[115]06:16:01[debg][5864] [BPTree<int,char>::erase] find getNodeInfo(node_leaf): <(9:I),(17:Q),> (BPTree.h:170)
[116]06:16:01[debg][5864] [BPTree<int,char>::adjustmentTreeNodeAfterErase] start adjustment getNodeInfo(_node): <(9:I),> (BPTree.h:216)
[117]06:16:01[debg][5864] [BPTree<int,char>::adjustmentTreeNodeAfterErase] case 3,merge node to target_node:start: getNodeInfo(_node): <(9:I),> getNodeInfo(parent): <7,17,19,> getNodeInfo(bro_node): <(6:F),(7:G),> (BPTree.h:300)
[118]06:16:01[debg][5864] [BPTree<int,char>::adjustmentTreeNodeAfterErase] case 3,merge node to target_node:result: getNodeInfo(_node): <(6:F),(7:G),(9:I),> getNodeInfo(parent): <17,19,> getNodeInfo(bro_node): <> (BPTree.h:329)
[119]06:16:01[debg][5864] [BPTree<int,char>::adjustmentTreeNodeAfterErase] start adjustment getNodeInfo(_node): <17,19,> (BPTree.h:216)
[120]06:16:01[test][5864] [BPTree<int,char>::erase] remove key _key: 18 (BPTree.h:164)
[121]06:16:01[debg][5864] [BPTree<int,char>::erase] find getNodeInfo(node_leaf): <(18:R),(19:S),> (BPTree.h:170)
[122]06:16:01[debg][5864] [BPTree<int,char>::adjustmentTreeNodeAfterErase] start adjustment getNodeInfo(_node): <(19:S),> (BPTree.h:216)
[123]06:16:01[debg][5864] [BPTree<int,char>::adjustmentTreeNodeAfterErase] case 2,bro split,start: getNodeInfo(_node): <(19:S),> getNodeInfo(parent): <17,19,> getNodeInfo(bro_node): <(6:F),(7:G),(9:I),> move_key: 9 (BPTree.h:269)
[124]06:16:01[debg][5864] [BPTree<int,char>::adjustmentTreeNodeAfterErase] case 2,bro split,result: getNodeInfo(_node): <(9:I),(19:S),> getNodeInfo(parent): <7,19,> getNodeInfo(bro_node): <(6:F),(7:G),> move_key: 9 (BPTree.h:294)
[125]06:16:01[test][5864] [BPTree<int,char>::erase] remove key _key: 19 (BPTree.h:164)
[126]06:16:01[debg][5864] [BPTree<int,char>::erase] find getNodeInfo(node_leaf): <(9:I),(19:S),> (BPTree.h:170)
[127]06:16:01[debg][5864] [BPTree<int,char>::adjustmentTreeNodeAfterErase] start adjustment getNodeInfo(_node): <(9:I),> (BPTree.h:216)
[128]06:16:01[debg][5864] [BPTree<int,char>::adjustmentTreeNodeAfterErase] case 2,bro split,start: getNodeInfo(_node): <(9:I),> getNodeInfo(parent): <7,19,> getNodeInfo(bro_node): <(20:T),(21:U),(22:V),> move_key: 20 (BPTree.h:269)
[129]06:16:01[debg][5864] [BPTree<int,char>::adjustmentTreeNodeAfterErase] case 2,bro split,result: getNodeInfo(_node): <(9:I),(20:T),> getNodeInfo(parent): <7,20,> getNodeInfo(bro_node): <(21:U),(22:V),> move_key: 20 (BPTree.h:294)
[130]06:16:01[test][5864] [BPTree<int,char>::erase] remove key _key: 20 (BPTree.h:164)
[131]06:16:01[debg][5864] [BPTree<int,char>::erase] find getNodeInfo(node_leaf): <(9:I),(20:T),> (BPTree.h:170)
[132]06:16:01[debg][5864] [BPTree<int,char>::adjustmentTreeNodeAfterErase] start adjustment getNodeInfo(_node): <(9:I),> (BPTree.h:216)
[133]06:16:01[debg][5864] [BPTree<int,char>::adjustmentTreeNodeAfterErase] case 3,merge node to target_node:start: getNodeInfo(_node): <(9:I),> getNodeInfo(parent): <7,20,> getNodeInfo(bro_node): <(6:F),(7:G),> (BPTree.h:300)
[134]06:16:01[debg][5864] [BPTree<int,char>::adjustmentTreeNodeAfterErase] case 3,merge node to target_node:result: getNodeInfo(_node): <(6:F),(7:G),(9:I),> getNodeInfo(parent): <20,> getNodeInfo(bro_node): <> (BPTree.h:329)
[135]06:16:01[debg][5864] [BPTree<int,char>::adjustmentTreeNodeAfterErase] start adjustment getNodeInfo(_node): <20,> (BPTree.h:216)
[136]06:16:01[test][5864] [BPTree<int,char>::erase] remove key _key: 21 (BPTree.h:164)
[137]06:16:01[debg][5864] [BPTree<int,char>::erase] find getNodeInfo(node_leaf): <(21:U),(22:V),> (BPTree.h:170)
[138]06:16:01[debg][5864] [BPTree<int,char>::adjustmentTreeNodeAfterErase] start adjustment getNodeInfo(_node): <(22:V),> (BPTree.h:216)
[139]06:16:01[debg][5864] [BPTree<int,char>::adjustmentTreeNodeAfterErase] case 2,bro split,start: getNodeInfo(_node): <(22:V),> getNodeInfo(parent): <20,> getNodeInfo(bro_node): <(6:F),(7:G),(9:I),> move_key: 9 (BPTree.h:269)
[140]06:16:01[debg][5864] [BPTree<int,char>::adjustmentTreeNodeAfterErase] case 2,bro split,result: getNodeInfo(_node): <(9:I),(22:V),> getNodeInfo(parent): <7,> getNodeInfo(bro_node): <(6:F),(7:G),> move_key: 9 (BPTree.h:294)
[141]06:16:01[test][5864] [BPTree<int,char>::erase] remove key _key: 22 (BPTree.h:164)
[142]06:16:01[debg][5864] [BPTree<int,char>::erase] find getNodeInfo(node_leaf): <(9:I),(22:V),> (BPTree.h:170)
[143]06:16:01[debg][5864] [BPTree<int,char>::adjustmentTreeNodeAfterErase] start adjustment getNodeInfo(_node): <(9:I),> (BPTree.h:216)
[144]06:16:01[debg][5864] [BPTree<int,char>::adjustmentTreeNodeAfterErase] case 3,merge node to target_node:start: getNodeInfo(_node): <(9:I),> getNodeInfo(parent): <7,> getNodeInfo(bro_node): <(6:F),(7:G),> (BPTree.h:300)
[145]06:16:01[debg][5864] [BPTree<int,char>::adjustmentTreeNodeAfterErase] case 3,merge node to target_node:result: getNodeInfo(_node): <(6:F),(7:G),(9:I),> getNodeInfo(parent): <> getNodeInfo(bro_node): <> (BPTree.h:329)
[146]06:16:01[test][5864] [BPTree<int,char>::erase] remove key _key: 6 (BPTree.h:164)
[147]06:16:01[debg][5864] [BPTree<int,char>::erase] find getNodeInfo(node_leaf): <(6:F),(7:G),(9:I),> (BPTree.h:170)
[148]06:16:01[debg][5864] [BPTree<int,char>::adjustmentTreeNodeAfterErase] start adjustment getNodeInfo(_node): <(7:G),(9:I),> (BPTree.h:216)
[149]06:16:01[test][5864] [BPTree<int,char>::erase] remove key _key: 9 (BPTree.h:164)
[150]06:16:01[debg][5864] [BPTree<int,char>::erase] find getNodeInfo(node_leaf): <(7:G),(9:I),> (BPTree.h:170)
[151]06:16:01[debg][5864] [BPTree<int,char>::adjustmentTreeNodeAfterErase] start adjustment getNodeInfo(_node): <(7:G),> (BPTree.h:216)
[152]06:16:01[test][5864] [BPTree<int,char>::erase] remove key _key: 7 (BPTree.h:164)
[153]06:16:01[debg][5864] [BPTree<int,char>::erase] find getNodeInfo(node_leaf): <(7:G),> (BPTree.h:170)
[154]06:16:01[debg][5864] [BPTree<int,char>::adjustmentTreeNodeAfterErase] start adjustment getNodeInfo(_node): <> (BPTree.h:216)
[155]06:16:02[debg][5864] [Start::doSomething] values tree is null (Start.cpp:57)
删除
5,
8,
10,
15,
16,
17,
18,
19,
20,
21,
22,
6,
9,
7
//remove
void erase(const_key_type_reference _key) {
do {
//0.judge exist key
LOGXT("remove key", VAR_DATA(_key));
auto [node_leaf, loc, is_find] = findProperLeaf(_key);
if (is_find == false) {
LOGXW("key no exist", VAR_DATA(_key));
break;
}
LOGXD("find", VAR_DATA(getNodeInfo(node_leaf)));
//1.delete key
auto& keys = node_leaf->getKeys();
keys.erase(keys.begin() + loc);
auto& values = node_leaf->getValues();
values.erase(values.begin() + loc);
//2.adjustment tree
adjustmentTreeNodeAfterErase(node_leaf);
} while (false);
}
size_type findNodeLocInParent(node_type_ptr _node) {
size_type loc = -1;
do {
if (_node == nullptr)break;
node_type_ptr parent = _node->getParent();
if(parent==nullptr)break;
auto parent_childs = parent->getChilds();
for(size_type i=0;i<parent_childs.size();i++){
if (parent_childs[i] == _node) {
loc = i;
break;
}
}
} while (false);
return loc;
}
std::tuple<node_type_ptr, size_type> findBroNode(node_type_ptr _node,bool _is_left=true) {
node_type_ptr bro_node = nullptr;
size_type parent_loc = -1;
do {
if (_node == nullptr)break;
node_type_ptr parent = _node->getParent();
if (parent == nullptr)break;
size_type node_loc = findNodeLocInParent(_node);
if (node_loc == -1)break;
if (_is_left && node_loc == 0)break;
if (_is_left == false && node_loc == parent->getChilds().size() - 1)break;
parent_loc = _is_left ? node_loc - 1 : node_loc + 1;
bro_node = parent->getChilds()[parent_loc];
} while (false);
return std::tuple(bro_node, parent_loc);
}
void adjustmentTreeNodeAfterErase(node_type_ptr _node) {
do {
LOGXD("start adjustment", VAR_DATA(getNodeInfo(_node)));
if (_node == nullptr)break;
auto& target_keys = _node->getKeys();
node_type_ptr parent = _node->getParent();
if (parent == nullptr) {
if (getRoot() != _node) {
LOGXF("tree have error");
}
if (target_keys.size() == 0) {
delete _node;
getRoot() = nullptr;
}
break;
}
//1.key size >= min size
if (target_keys.size() >= getNodeMinSize()) {
LOGXD("case 1:", VAR_DATA(getNodeInfo(_node)));
break;
}
//2.find bro_node
node_type_ptr left_bro_node = nullptr;
size_type left_bro_node_loc = -1;
node_type_ptr right_bro_node = nullptr;
size_type right_bro_node_loc = -1;
auto find_result = findBroNode(_node, true);
left_bro_node = std::get<0>(find_result);
left_bro_node_loc = std::get<1>(find_result);
find_result = findBroNode(_node, false);
right_bro_node = std::get<0>(find_result);
right_bro_node_loc = std::get<1>(find_result);
bool is_left_bro = left_bro_node?true:false;
node_type_ptr bro_node = nullptr;
if (left_bro_node && left_bro_node->getKeys().size() > getNodeMinSize()) {
bro_node = left_bro_node;
is_left_bro = true;
}
else if (right_bro_node && right_bro_node->getKeys().size() > getNodeMinSize()) {
is_left_bro = false;
bro_node = right_bro_node;
}
else {
bro_node = is_left_bro ? left_bro_node : right_bro_node;
}
//3.if bro_node size > min_size ,can split key of x,parent replace x,target_node will add x
auto& bro_keys = bro_node->getKeys();
auto& parent_keys = parent->getKeys();
if (bro_keys.size() > getNodeMinSize()) {
//3.1 deal key
size_type bro_split_loc = is_left_bro ? bro_keys.size() - 1 : 0;
size_type parent_replace_loc = is_left_bro ? left_bro_node_loc : right_bro_node_loc - 1;
size_type target_node_add_loc = is_left_bro ? 0 : target_keys.size();
key_type move_key = bro_keys[bro_split_loc];
LOGXD("case 2,bro split,start:", VAR_DATA(getNodeInfo(_node)), VAR_DATA(getNodeInfo(parent)),
VAR_DATA(getNodeInfo(bro_node)), VAR_DATA(move_key));
bro_keys.erase(bro_keys.begin() + bro_split_loc);
parent_keys[parent_replace_loc] = move_key;
if (is_left_bro)parent_keys[parent_replace_loc] = bro_keys[bro_split_loc - 1];
//add this line, this will not same ,because find not same
target_keys.insert(target_keys.begin() + target_node_add_loc, move_key);
//3.2 deal value or child
if (_node->isLeaf()) {
auto& target_values = _node->getValues();
auto& bro_values = bro_node->getValues();
value_type move_value = bro_values[bro_split_loc];
bro_values.erase(bro_values.begin() + bro_split_loc);
target_values.insert(target_values.begin() + target_node_add_loc, move_value);
}
else {
auto& target_childs = _node->getChilds();
auto& bro_childs = bro_node->getChilds();
size_type bro_split_child_loc = is_left_bro ? bro_childs.size()-1 : 0;
size_type target_node_add_child_loc = is_left_bro ? 0 : target_childs.size();
node_type_ptr move_child = bro_childs[bro_split_child_loc];
bro_childs.erase(bro_childs.begin() + bro_split_child_loc);
target_childs.insert(target_childs.begin() + target_node_add_child_loc, move_child);
updataChildParent(_node);
}
LOGXD("case 2,bro split,result:", VAR_DATA(getNodeInfo(_node)), VAR_DATA(getNodeInfo(parent)),
VAR_DATA(getNodeInfo(bro_node)), VAR_DATA(move_key));
break;
}
//4.bro_key size is <=min_size, can merge bro_node to target_node
{
LOGXD("case 3,merge node to target_node:start:", VAR_DATA(getNodeInfo(_node)), VAR_DATA(getNodeInfo(parent)),
VAR_DATA(getNodeInfo(bro_node)));
size_type parent_erase_size = is_left_bro ? left_bro_node_loc : right_bro_node_loc - 1;
size_type target_insert_loc = is_left_bro ? 0 : target_keys.size();
parent_keys.erase(parent_keys.begin() + parent_erase_size);
target_keys.insert(target_keys.begin()+target_insert_loc, bro_keys.begin(), bro_keys.end());
bro_keys.clear();
if (_node->isLeaf()) {
auto& target_values = _node->getValues();
auto& bro_values = bro_node->getValues();
target_values.insert(target_values.begin()+target_insert_loc,
bro_values.begin(), bro_values.end());
bro_values.clear();
}
else {
auto& target_childs = _node->getChilds();
auto& bro_childs = bro_node->getChilds();
size_type target_insert_child_loc = is_left_bro ? 0 : target_childs.size();
target_childs.insert(target_childs.begin()+target_insert_child_loc,
bro_childs.begin(), bro_childs.end());
bro_childs.clear();
}
size_type parent_erase_child_loc = is_left_bro ? left_bro_node_loc : right_bro_node_loc;
auto& parent_childs = parent->getChilds();
parent_childs.erase(parent_childs.begin() + parent_erase_child_loc);
updataChildParent(_node);
LOGXD("case 3,merge node to target_node:result:", VAR_DATA(getNodeInfo(_node)), VAR_DATA(getNodeInfo(parent)),
VAR_DATA(getNodeInfo(bro_node)));
delete bro_node;
if (parent == getRoot()&&parent_keys.size()==0) {
getRoot() = _node;
getRoot()->getParent() = nullptr;
delete parent;
break;
}
adjustmentTreeNodeAfterErase(parent);
}
} while (false);
}