Skip to content

Commit 6f9038b

Browse files
committed
fix some delete bug but some other always exits
1 parent 8a8ac65 commit 6f9038b

File tree

4 files changed

+51
-81
lines changed

4 files changed

+51
-81
lines changed

B-Tree/BTree/Delete.class.php

Lines changed: 36 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -126,31 +126,36 @@ private function _deleteKeyFromLeaf (BTree_Node $node, $key) {
126126
return false;
127127
}
128128

129+
private function _deleteMoveNeighbor (BTree_Node $node, $key, $deleteFlag = BTree_Node::DELETE_FLAG_RIGHT) {
130+
131+
132+
}
133+
129134
/**
130135
* 从左叶侧节点借值进行删除
131136
*
132137
* @param BTree_Node $node 叶节点
133138
* @param string $key 关键词
134139
* @return bool 成功返回true|如果邻居节点不存在返回false
135140
*/
136-
private function _deleteMoveLeft (BTree_Node $node, $key, $deleteFlag = BTree_Node::DELETE_FLAG_RIGHT) {
141+
private function _deleteMoveLeft (BTree_Node $node, $key) {
137142

138-
$parentNode = $node->parent();
139-
$neighborLeft = $this->_neighborLeft($node);
143+
$parentNode = $node->parent();
144+
$neighborLeft = $this->_neighborLeft($node);
140145

141146
if (!($neighborLeft instanceof BTree_Node)) {
142147

143148
return false;
144149
}
145150

146-
$keyParentLeft = $parentNode->pointerLeftKey($node->pointer());
151+
$keyParentLeft = $parentNode->pointerLeftKey($node->pointer());
147152

148153
if (count($neighborLeft->data()) > $this->_leastNumberKeys()) {
149154

150155
$valueParentLeft = $parentNode->match($keyParentLeft);
151156
$keyLeft = $neighborLeft->getRightBorderKey();
152157
$valueLeft = $neighborLeft->match($keyLeft);
153-
$node->delete($key, $deleteFlag);
158+
$node->delete($key, BTree_Node::DELETE_FLAG_RIGHT);
154159
$node->insert($keyParentLeft, $valueParentLeft, $neighborLeft->rightBorderChild(), $node->leftBorderChild());
155160
$parentNode->replaceKey($keyParentLeft, $keyLeft, $valueLeft);
156161
$neighborLeft->delete($keyLeft, BTree_Node::DELETE_FLAG_RIGHT);
@@ -163,7 +168,7 @@ private function _deleteMoveLeft (BTree_Node $node, $key, $deleteFlag = BTree_No
163168

164169
$this->_deleteMerge($neighborLeft, $node, $parentNode, $keyParentLeft, $key);
165170

166-
return true;
171+
return true;
167172
}
168173

169174
/**
@@ -173,24 +178,24 @@ private function _deleteMoveLeft (BTree_Node $node, $key, $deleteFlag = BTree_No
173178
* @param string $key 关键词
174179
* @return bool 成功返回true|如果邻居节点不存在返回false
175180
*/
176-
private function _deleteMoveRight (BTree_Node $node, $key, $deleteFlag = BTree_Node::DELETE_FLAG_RIGHT) {
181+
private function _deleteMoveRight (BTree_Node $node, $key) {
177182

178-
$parentNode = $node->parent();
179-
$neighborRight = $this->_neighborRight($node);
183+
$parentNode = $node->parent();
184+
$neighborRight = $this->_neighborRight($node);
180185

181186
if (!($neighborRight instanceof BTree_Node)) {
182187

183188
return false;
184189
}
185190

186-
$keyParentRight = $parentNode->pointerRightKey($node->pointer());
191+
$keyParentRight = $parentNode->pointerRightKey($node->pointer());
187192

188193
if (count($neighborRight->data()) > $this->_leastNumberKeys()) {
189194

190195
$valueParentRight = $parentNode->match($keyParentRight);
191196
$keyRight = $neighborRight->getLeftBorderKey();
192197
$valueRight = $neighborRight->match($keyRight);
193-
$node->delete($key, $deleteFlag);
198+
$node->delete($key, BTree_Node::DELETE_FLAG_RIGHT);
194199
$node->insert($keyParentRight, $valueParentRight, $node->rightBorderChild(), $neighborRight->leftBorderChild());
195200
$parentNode->replaceKey($keyParentRight, $keyRight, $valueRight);
196201
$neighborRight->delete($keyRight, BTree_Node::DELETE_FLAG_LEFT);
@@ -203,7 +208,7 @@ private function _deleteMoveRight (BTree_Node $node, $key, $deleteFlag = BTree_N
203208

204209
$this->_deleteMerge($node, $neighborRight, $parentNode, $keyParentRight, $key);
205210

206-
return true;
211+
return true;
207212
}
208213

209214
/**
@@ -225,52 +230,12 @@ private function _deleteMerge (BTree_Node $left, BTree_Node $right, BTree_Node $
225230
return $this->_mergeStore($left, $right, $parent, $nextParent, $midKey, $midValue, $key);
226231
}
227232

228-
$neighborRight = $this->_neighborRight($parent);
229-
230-
if ($neighborRight instanceof BTree_Node) {
231-
232-
$nextRight = $neighborRight;
233-
$nextLeft = $parent;
234-
$nextMidKey = $nextParent->pointerRightKey($parent->pointer());
233+
if ($this->_deleteMoveRight($parent, $midKey) || $this->_deleteMoveLeft($parent, $midKey)) {
235234

236-
if (count($neighborRight->data()) > $this->_leastNumberKeys()) {
237-
238-
$this->_deleteMoveRight($parent, $midKey);
239-
} else {
240-
241-
$this->_deleteMerge($nextLeft, $nextRight, $nextParent, $nextMidKey, $midKey);
242-
}
235+
return $this->_mergeStore($left, $right, $parent, $nextParent, $midKey, $midValue, $key, true);
243236
}
244237

245-
$neighborLeft = $this->_neighborLeft($parent);
246-
247-
if ($this->canMergeWithNeighbor($neighborLeft)) {
248-
249-
$nextRight = $parent;
250-
$nextLeft = $neighborLeft;
251-
$nextMidKey = $nextParent->pointerRightKey($neighborLeft->pointer());
252-
253-
if (count($neighborLeft->data()) > $this->_leastNumberKeys()) {
254-
255-
$this->_deleteMoveLeft($parent, $midKey);
256-
} else {
257-
258-
$this->_deleteMerge($nextLeft, $nextRight, $nextParent, $nextMidKey, $midKey);
259-
}
260-
}
261-
262-
return $this->_mergeStore($left, $right, $parent, $nextParent, $midKey, $midValue, $key);
263-
}
264-
265-
/**
266-
* 判断是否可以合并上级
267-
*
268-
* @param mixed $neighbor 上级节点
269-
* @return bool 判断结果
270-
*/
271-
private function canMergeWithNeighbor ($neighbor) {
272-
273-
return $neighbor instanceof BTree_Node && count($neighbor->data()) > $this->_leastNumberKeys();
238+
return false;
274239
}
275240

276241
/**
@@ -288,22 +253,28 @@ private function _canMergeImmediately (BTree_Node $parent, BTree_Node $nextParen
288253
/**
289254
* 合并删除
290255
*
291-
* @param BTree_Node $left 左侧节点
292-
* @param BTree_Node $right 右侧节点
293-
* @param BTree_Node $parent 上级节点
294-
* @param BTree_Node $nextParent 上级节点的上级节点
295-
* @param string $midKey 相夹关键词
296-
* @param string $midValue 相夹值
297-
* @param string $key 目标关键词
298-
* @return BTree_Node 左侧节点
256+
* @param BTree_Node $left 左侧节点
257+
* @param BTree_Node $right 右侧节点
258+
* @param BTree_Node $parent 上级节点
259+
* @param BTree_Node $nextParent 上级节点的上级节点
260+
* @param string $midKey 相夹关键词
261+
* @param string $midValue 相夹值
262+
* @param string $key 目标关键词
263+
* @param bool $isSaveParent 上级节点是否已保存
264+
* @return BTree_Node 左侧节点
299265
*/
300-
private function _mergeStore (BTree_Node $left, BTree_Node $right, BTree_Node $parent, BTree_Node $nextParent, $midKey, $midValue, $key) {
266+
private function _mergeStore (BTree_Node $left, BTree_Node $right, BTree_Node $parent, BTree_Node $nextParent, $midKey, $midValue, $key, $isSaveParent = false) {
301267

302268
$left->insert($midKey, $midValue, $left->rightBorderChild(), $right->leftBorderChild());
303269
$left->merge($right);
304270
$left->delete($key, BTree_Node::DELETE_FLAG_RIGHT);
305271
$parent->delete($midKey, BTree_Node::DELETE_FLAG_RIGHT);
306-
$this->_mergeStoreParent($parent, $left, $nextParent);
272+
273+
if (!$isSaveParent) {
274+
275+
$this->_mergeStoreParent($parent, $left, $nextParent);
276+
}
277+
307278
$this->_store->writeNode($left);
308279

309280
return $left;

B-Tree/BTree/Insert.class.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public function call ($params) {
5050

5151
if (BTree_Validate::value($currentNode->match($key))) {
5252

53-
throw new Exception('key exists');
53+
throw new Exception('key ' . $key . ' exists');
5454
}
5555

5656
$this->_insertNode($currentNode, $key, $value);

B-Tree/BTree/Node.class.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,9 @@ public function __construct ($data = array(), $children = array(), $parent = NU
4949
$keyList = array_map('strval', array_keys($data));
5050
$valueList = array_map('intval', array_values($data));
5151
$this->_data = array_combine($keyList, $valueList);
52-
$this->_children = array_slice(array_values($children), 0, count($data) + 1);
52+
$this->_children = count($data) < count($children)
53+
? array_slice(array_values($children), 0, count($data) + 1)
54+
: array_pad(array_values($children), count($data) + 1, 0);
5355
$this->_parent = $parent;
5456
$this->_pointer = $pointer;
5557
}
@@ -231,7 +233,7 @@ public function replaceKey ($keyOld, $keyNew, $valueNew) {
231233

232234
public function isLeaf () {
233235

234-
return $this->_children[0] <= 0;
236+
return 0 == count($this->_children) || $this->_children[0] <= 0;
235237
}
236238

237239
/**

test/BTree.php

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
include 'init.inc.php';
44

55
$options = array(
6-
'number_slots' => 5,
7-
'length_key' => 100,
6+
'number_slots' => 3,
7+
'length_key' => 10,
88
);
99
$file = 'index.btree';
1010
$index = BTree::open($file, $options);
@@ -59,6 +59,13 @@
5959
'key' => $key,
6060
)
6161
);
62+
63+
if (false != $index->command('select', array('key'=>$key))) {
64+
65+
echo "$offset delete failure: $key \n";
66+
exit;
67+
}
68+
6269
echo "$offset delete seccess: $key \n";
6370
$offset ++;
6471
}
@@ -106,7 +113,7 @@
106113

107114
case 'debug' :
108115

109-
$pointer = (int) $argv[2];
116+
$pointer = isset($argv[2]) ? (int) $argv[2] : 0;
110117

111118
$index->command(
112119
$command,
@@ -120,13 +127,3 @@
120127
$index = NULL;
121128

122129

123-
124-
/**
125-
35 46 71
126-
27 30 39 43
127-
25 26 28 29 31 32 33 34
128-
129-
46 71
130-
30 35 39 43
131-
26 27 28 29 31 32 33 34
132-
*/

0 commit comments

Comments
 (0)