Skip to content

Commit 984149c

Browse files
committed
split BTreeController
1 parent 274ad56 commit 984149c

File tree

6 files changed

+871
-832
lines changed

6 files changed

+871
-832
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
using MiniSQL.IndexManager.Models;
2+
3+
namespace MiniSQL.IndexManager.Controllers
4+
{
5+
public partial class BTreeController
6+
{
7+
public BTreeNode OccupyNewTableNode()
8+
{
9+
BTreeNode newNode = GetNewNode(PageTypes.LeafTablePage);
10+
return newNode;
11+
}
12+
}
13+
}
Lines changed: 315 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,315 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using MiniSQL.BufferManager.Models;
4+
using MiniSQL.IndexManager.Models;
5+
using MiniSQL.Library.Exceptions;
6+
using MiniSQL.Library.Models;
7+
8+
namespace MiniSQL.IndexManager.Controllers
9+
{
10+
public partial class BTreeController
11+
{
12+
public BTreeNode DeleteCells(BTreeNode root, Expression expression, string keyName, List<AttributeDeclaration> attributeDeclarations)
13+
{
14+
List<BTreeCell> nodesTobeDeleted = FindCells(root, expression, keyName, attributeDeclarations);
15+
foreach (var cell in nodesTobeDeleted)
16+
{
17+
root = Delete(cell, root);
18+
}
19+
return root;
20+
}
21+
22+
public BTreeNode Delete(DBRecord key, BTreeNode Root)
23+
{
24+
BTreeNode NodeTobeDeleted = FindNode(key, Root);
25+
if (NodeTobeDeleted == null)
26+
{
27+
throw new KeyNotExistsException("Cannot find the key!");
28+
}
29+
return Delete_entry(NodeTobeDeleted, key, Root);
30+
}
31+
32+
public BTreeNode Delete(BTreeCell keyCell, BTreeNode Root)
33+
{
34+
DBRecord key = keyCell.Key;
35+
return Delete(key, Root);
36+
}
37+
38+
private BTreeNode Delete_leaf_redistri(BTreeNode NodetobeDeleted, DBRecord key, BTreeNode Root)
39+
{
40+
BTreeCell cell;
41+
UInt16 offset;
42+
int indexInOffsetArray;
43+
44+
MemoryPage parentPage = _pager.ReadPage((int)NodetobeDeleted.ParentPage);
45+
BTreeNode parentNode = new BTreeNode(parentPage);
46+
47+
(cell, offset, indexInOffsetArray) = parentNode.FindBTreeCell(key);
48+
//the deleted node is not on the right page of parentNode
49+
if (cell != null)
50+
{
51+
MemoryPage brotherPage = _pager.ReadPage((int)NodetobeDeleted.RightPage);
52+
BTreeNode brotherNode = new BTreeNode(brotherPage);
53+
//If there is a node on the left of the deleted node,it need to be connected to the brother node.
54+
if (indexInOffsetArray >= 1)
55+
{
56+
InternalTableCell leftNodeCell = (InternalTableCell)parentNode.GetBTreeCell(parentNode.CellOffsetArray[indexInOffsetArray - 1]);
57+
MemoryPage leftPage = _pager.ReadPage((int)leftNodeCell.ChildPage);
58+
BTreeNode leftNode = new BTreeNode(leftPage);
59+
leftNode.RightPage = (uint)brotherNode.GetRawPage().PageNumber;
60+
}
61+
62+
if (brotherNode.NumCells + NodetobeDeleted.NumCells <= MaxCell) //merge
63+
{
64+
//After the merge,one cell in the parentNode will be deleted
65+
parentNode.DeleteBTreeCell(cell);
66+
//merge two node
67+
for (int i = 0; i < NodetobeDeleted.NumCells; i++)
68+
{
69+
brotherNode.InsertBTreeCell(NodetobeDeleted.GetBTreeCell(NodetobeDeleted.CellOffsetArray[i]));
70+
}
71+
DeleteNode(NodetobeDeleted);
72+
73+
}
74+
else //redistribute
75+
{
76+
BTreeCell movedCell = brotherNode.GetBTreeCell(brotherNode.CellOffsetArray[0]);
77+
DBRecord newKey = brotherNode.GetBTreeCell(brotherNode.CellOffsetArray[1]).Key;
78+
79+
NodetobeDeleted.InsertBTreeCell(movedCell);
80+
brotherNode.DeleteBTreeCell(movedCell);
81+
82+
BTreeCell parent_Cell;
83+
UInt16 parent_offset;
84+
int parent_indexInOffsetArray;
85+
(parent_Cell, parent_offset, parent_indexInOffsetArray) = parentNode.FindBTreeCell(key);
86+
87+
InternalTableCell newCell = new InternalTableCell(newKey, (uint)NodetobeDeleted.GetRawPage().PageNumber);
88+
parentNode.DeleteBTreeCell(parent_Cell);
89+
parentNode.InsertBTreeCell(newCell);
90+
91+
}
92+
}
93+
//The node to be deleted is on the rightpage,the brother node is on the left
94+
else
95+
{
96+
InternalTableCell brotherCell = (InternalTableCell)parentNode.GetBTreeCell(parentNode.CellOffsetArray[parentNode.NumCells - 1]);
97+
MemoryPage brotherPage = _pager.ReadPage((int)brotherCell.ChildPage);
98+
BTreeNode brotherNode = new BTreeNode(brotherPage);
99+
100+
//The right page of brother node should be 0
101+
102+
brotherNode.RightPage = NodetobeDeleted.RightPage;
103+
104+
if (brotherNode.NumCells + NodetobeDeleted.NumCells <= MaxCell) //merge
105+
{
106+
//After the merge,one cell in the parentNode will be deleted
107+
parentNode.DeleteBTreeCell(brotherCell);
108+
//merge two node
109+
for (int i = 0; i < NodetobeDeleted.NumCells; i++)
110+
{
111+
brotherNode.InsertBTreeCell(NodetobeDeleted.GetBTreeCell(NodetobeDeleted.CellOffsetArray[i]));
112+
}
113+
DeleteNode(NodetobeDeleted);
114+
parentNode.RightPage = (uint)brotherNode.GetRawPage().PageNumber;
115+
116+
}
117+
else //redistribute
118+
{
119+
BTreeCell movedCell = brotherNode.GetBTreeCell(brotherNode.CellOffsetArray[brotherNode.NumCells - 1]);
120+
DBRecord newKey = movedCell.Key;
121+
122+
NodetobeDeleted.InsertBTreeCell(movedCell);
123+
brotherNode.DeleteBTreeCell(movedCell);
124+
125+
BTreeCell parent_Cell;
126+
UInt16 parent_offset;
127+
int parent_indexInOffsetArray;
128+
(parent_Cell, parent_offset, parent_indexInOffsetArray) = parentNode.FindBTreeCell(key);
129+
130+
InternalTableCell newCell = new InternalTableCell(newKey, (uint)NodetobeDeleted.GetRawPage().PageNumber);
131+
parentNode.DeleteBTreeCell(parent_Cell);
132+
parentNode.InsertBTreeCell(newCell);
133+
134+
}
135+
136+
}
137+
138+
139+
NodetobeDeleted = parentNode;
140+
//deal with parent Nodes
141+
return Delete_internal_redistribute(NodetobeDeleted, key, Root);
142+
}
143+
144+
private BTreeNode Delete_internal_redistribute(BTreeNode NodetobeDeleted, DBRecord key, BTreeNode Root)
145+
{
146+
InternalTableCell tmpCell;
147+
MemoryPage tmpPage;
148+
BTreeNode tmpNode;
149+
150+
BTreeCell cell;
151+
UInt16 offset;
152+
int indexInOffsetArray;
153+
154+
MemoryPage parentPage = null;
155+
BTreeNode parentNode = null;
156+
157+
while (NodetobeDeleted.NumCells < (MaxCell + 1) / 2)
158+
{
159+
//The root
160+
if (NodetobeDeleted.ParentPage == 0)
161+
{
162+
if (NodetobeDeleted.NumCells == 0)
163+
{
164+
MemoryPage NewRootPage = _pager.ReadPage((int)NodetobeDeleted.RightPage);
165+
BTreeNode newRoot = new BTreeNode(NewRootPage);
166+
newRoot.ParentPage = 0;
167+
return newRoot;
168+
}
169+
return Root;
170+
}
171+
else
172+
{
173+
parentPage = _pager.ReadPage((int)NodetobeDeleted.ParentPage);
174+
parentNode = new BTreeNode(parentPage);
175+
(cell, offset, indexInOffsetArray) = parentNode.FindBTreeCell(key);
176+
//The node to be deleted isn't on the rightpage
177+
if (cell != null)
178+
{
179+
InternalTableCell brotherCell = null;
180+
MemoryPage brotherPage = null;
181+
BTreeNode brotherNode = null;
182+
//if the right brother is on rightpage
183+
if (indexInOffsetArray + 1 == parentNode.NumCells)
184+
{
185+
brotherPage = _pager.ReadPage((int)parentNode.RightPage);
186+
brotherNode = new BTreeNode(brotherPage);
187+
188+
}
189+
else
190+
{
191+
brotherCell = (InternalTableCell)parentNode.GetBTreeCell(parentNode.CellOffsetArray[indexInOffsetArray + 1]);
192+
brotherPage = _pager.ReadPage((int)brotherCell.ChildPage);
193+
brotherNode = new BTreeNode(brotherPage);
194+
}
195+
//merge
196+
if (brotherNode.NumCells + NodetobeDeleted.NumCells < MaxCell)
197+
{
198+
for (int i = 0; i < NodetobeDeleted.NumCells; i++)
199+
{
200+
tmpCell = (InternalTableCell)NodetobeDeleted.GetBTreeCell(NodetobeDeleted.CellOffsetArray[i]);
201+
202+
brotherNode.InsertBTreeCell(tmpCell);
203+
204+
tmpPage = _pager.ReadPage((int)tmpCell.ChildPage);
205+
tmpNode = new BTreeNode(tmpPage);
206+
tmpNode.ParentPage = (uint)brotherNode.GetRawPage().PageNumber;
207+
}
208+
//move the cell in parentNode to brotherNode
209+
InternalTableCell insertCell = new InternalTableCell(cell.Key, (uint)NodetobeDeleted.RightPage);
210+
brotherNode.InsertBTreeCell(insertCell);
211+
tmpPage = _pager.ReadPage((int)insertCell.ChildPage);
212+
tmpNode = new BTreeNode(tmpPage);
213+
tmpNode.ParentPage = (uint)brotherNode.GetRawPage().PageNumber;
214+
215+
DeleteNode(NodetobeDeleted);
216+
parentNode.DeleteBTreeCell(cell);
217+
}
218+
//redistribute
219+
else
220+
{
221+
InternalTableCell movedCell = (InternalTableCell)brotherNode.GetBTreeCell(brotherNode.CellOffsetArray[0]);
222+
DBRecord upperKey = movedCell.Key;
223+
DBRecord downKey = cell.Key;
224+
225+
InternalTableCell insertDeletedCell = new InternalTableCell(downKey, (uint)NodetobeDeleted.RightPage);
226+
NodetobeDeleted.InsertBTreeCell(insertDeletedCell);
227+
NodetobeDeleted.RightPage = movedCell.ChildPage;
228+
229+
tmpPage = _pager.ReadPage((int)movedCell.ChildPage);
230+
tmpNode = new BTreeNode(tmpPage);
231+
tmpNode.ParentPage = (uint)NodetobeDeleted.GetRawPage().PageNumber;
232+
233+
InternalTableCell insertParentCell = new InternalTableCell(upperKey, (uint)NodetobeDeleted.GetRawPage().PageNumber);
234+
parentNode.DeleteBTreeCell(cell);
235+
parentNode.InsertBTreeCell(insertParentCell);
236+
brotherNode.DeleteBTreeCell(movedCell);
237+
238+
}
239+
240+
}
241+
//The node to be deleted is on the rightpage
242+
else
243+
{
244+
InternalTableCell brotherCell = null;
245+
MemoryPage brotherPage = null;
246+
BTreeNode brotherNode = null;
247+
248+
brotherCell = (InternalTableCell)parentNode.GetBTreeCell(parentNode.CellOffsetArray[parentNode.NumCells - 1]);
249+
brotherPage = _pager.ReadPage((int)brotherCell.ChildPage);
250+
brotherNode = new BTreeNode(brotherPage);
251+
//merge
252+
if (brotherNode.NumCells + NodetobeDeleted.NumCells < MaxCell)
253+
{
254+
for (int i = 0; i < brotherNode.NumCells; i++)
255+
{
256+
tmpCell = (InternalTableCell)brotherNode.GetBTreeCell(brotherNode.CellOffsetArray[i]);
257+
258+
NodetobeDeleted.InsertBTreeCell(tmpCell);
259+
260+
tmpPage = _pager.ReadPage((int)tmpCell.ChildPage);
261+
tmpNode = new BTreeNode(tmpPage);
262+
tmpNode.ParentPage = (uint)NodetobeDeleted.GetRawPage().PageNumber;
263+
}
264+
//move the cell in parentNode to brotherNode
265+
InternalTableCell insertCell = new InternalTableCell(brotherCell.Key, (uint)brotherNode.RightPage);
266+
NodetobeDeleted.InsertBTreeCell(insertCell);
267+
tmpPage = _pager.ReadPage((int)insertCell.ChildPage);
268+
tmpNode = new BTreeNode(tmpPage);
269+
tmpNode.ParentPage = (uint)NodetobeDeleted.GetRawPage().PageNumber;
270+
271+
DeleteNode(brotherNode);
272+
parentNode.DeleteBTreeCell(parentNode.GetBTreeCell(parentNode.CellOffsetArray[parentNode.NumCells - 1]));
273+
}
274+
//redistribute
275+
else
276+
{
277+
DBRecord downKey = parentNode.GetBTreeCell(parentNode.CellOffsetArray[parentNode.NumCells - 1]).Key;
278+
InternalTableCell insertDeletedCell = new InternalTableCell(downKey, brotherNode.RightPage);
279+
NodetobeDeleted.InsertBTreeCell(insertDeletedCell);
280+
281+
282+
InternalTableCell movedCell = (InternalTableCell)brotherNode.GetBTreeCell(brotherNode.CellOffsetArray[brotherNode.NumCells - 1]);
283+
brotherNode.RightPage = movedCell.ChildPage;
284+
DBRecord upperKey = movedCell.Key;
285+
InternalTableCell insertParentCell = new InternalTableCell(upperKey, (uint)brotherNode.GetRawPage().PageNumber);
286+
parentNode.InsertBTreeCell(insertParentCell);
287+
brotherNode.DeleteBTreeCell(movedCell);
288+
289+
tmpPage = _pager.ReadPage((int)brotherNode.RightPage);
290+
tmpNode = new BTreeNode(tmpPage);
291+
tmpNode.ParentPage = (uint)brotherNode.GetRawPage().PageNumber;
292+
}
293+
}
294+
}
295+
NodetobeDeleted = parentNode;
296+
}
297+
return Root;
298+
}
299+
300+
private BTreeNode Delete_entry(BTreeNode NodetobeDeleted, DBRecord key, BTreeNode Root)
301+
{
302+
BTreeCell cell;
303+
UInt16 offset;
304+
int indexInOffsetArray;
305+
(cell, offset, indexInOffsetArray) = NodetobeDeleted.FindBTreeCell(key, false);
306+
NodetobeDeleted.DeleteBTreeCell(cell);
307+
308+
if (NodetobeDeleted.NumCells < MaxCell / 2 && NodetobeDeleted.ParentPage != 0)
309+
{
310+
return Delete_leaf_redistri(NodetobeDeleted, key, Root);
311+
}
312+
return Root;
313+
}
314+
}
315+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
using MiniSQL.BufferManager.Models;
2+
using MiniSQL.IndexManager.Models;
3+
4+
namespace MiniSQL.IndexManager.Controllers
5+
{
6+
public partial class BTreeController
7+
{
8+
public void RemoveTree(BTreeNode root)
9+
{
10+
if (root.PageType == PageTypes.LeafIndexPage || root.PageType == PageTypes.LeafTablePage)
11+
{
12+
DeleteNode(root);
13+
return;
14+
}
15+
if (root.PageType == PageTypes.InternalIndexPage)
16+
{
17+
foreach (BTreeCell cell in root)
18+
{
19+
MemoryPage page = _pager.ReadPage((int)((InternalIndexCell)cell).ChildPage);
20+
BTreeNode node = new BTreeNode(page);
21+
RemoveTree(node);
22+
}
23+
}
24+
else // (root.PageType == PageTypes.InternalTablePage)
25+
{
26+
foreach (BTreeCell cell in root)
27+
{
28+
MemoryPage page = _pager.ReadPage((int)((InternalTableCell)cell).ChildPage);
29+
BTreeNode node = new BTreeNode(page);
30+
RemoveTree(node);
31+
}
32+
}
33+
MemoryPage rightPage = _pager.ReadPage((int)root.RightPage);
34+
BTreeNode rightNode = new BTreeNode(rightPage);
35+
RemoveTree(rightNode);
36+
// post-order traversal
37+
DeleteNode(root);
38+
}
39+
}
40+
}

0 commit comments

Comments
 (0)