Skip to content

Commit 33408ea

Browse files
committed
part 13
1 parent 612063e commit 33408ea

File tree

3 files changed

+112
-15
lines changed

3 files changed

+112
-15
lines changed

db/btree.go

+102-12
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ const (
6161
InternalNodeChildSize = uint32_t(unsafe.Sizeof(uint32_t(0)))
6262
InternalNodeCellSize = InternalNodeKeySize + InternalNodeChildSize
6363
InternalNodeSpaceForCells = PageSize - InternalNodeHeaderSize
64-
InternalNodeMaxCells = InternalNodeSpaceForCells / InternalNodeCellSize
64+
InternalNodeMaxCells = 3
6565
)
6666

6767
const (
@@ -107,10 +107,12 @@ func (p *LeafPage) printLeafNode() {
107107
func (c *Cursor) leafNodeSplitAndInsert(key uint32_t, value *Row) {
108108
oldHeader, oldBody := c.table.pager.getPage(c.pageNum)
109109
oldPage := &LeafPage{header: oldHeader, body: (*LeafPageBody)(oldBody)}
110+
oldMax := oldPage.getMaxKey()
110111
newPageNum := c.table.pager.getUnusedPageNum()
111112
newHeader, newBody := c.table.pager.getPage(newPageNum)
112113
newPage := &LeafPage{header: newHeader, body: (*LeafPageBody)(newBody)}
113114
newPage.initializeLeafNode()
115+
newPage.header.parentPointer = oldPage.header.parentPointer
114116
*newPage.leafNodeNextLeaf() = *oldPage.leafNodeNextLeaf()
115117
*oldPage.leafNodeNextLeaf() = newPageNum
116118

@@ -141,8 +143,17 @@ func (c *Cursor) leafNodeSplitAndInsert(key uint32_t, value *Row) {
141143
if oldPage.header.isRoot != 0 {
142144
c.table.createNewRoot(newPageNum)
143145
} else {
144-
fmt.Println("Need to implement updating parent after split.")
145-
os.Exit(ExitFailure)
146+
//fmt.Println("Need to implement updating parent after split.")
147+
//os.Exit(ExitFailure)
148+
parentPageNum := oldPage.header.parentPointer
149+
newMax := oldPage.getMaxKey()
150+
parentHeader, parentBody := c.table.pager.getPage(parentPageNum)
151+
parentPage := InternalPage{
152+
header: parentHeader,
153+
body: (*InternalPageBody)(parentBody),
154+
}
155+
parentPage.updateInternalNodeKey(oldMax, newMax)
156+
c.table.internalNodeInsert(parentPageNum, newPageNum)
146157
}
147158
}
148159

@@ -169,6 +180,14 @@ func (t *Table) createNewRoot(rightChildPageNum uint32_t) {
169180
leftChildMaxKey := leftChild.getMaxKey()
170181
*(internalNode.internalNodeKey(0)) = leftChildMaxKey
171182
*(internalNode.internalNodeRightChild()) = rightChildPageNum
183+
rightChildHeader, _ := t.pager.getPage(rightChildPageNum)
184+
leftChild.header.parentPointer = t.rootPageNum
185+
rightChildHeader.parentPointer = t.rootPageNum
186+
}
187+
188+
func (p *InternalPage) updateInternalNodeKey(oldKey, newKey uint32_t) {
189+
oldChildMax := p.internalNodeFindChild(oldKey)
190+
*p.internalNodeKey(oldChildMax) = newKey
172191
}
173192

174193
func (p *InternalPage) internalNodeNumKeys() *uint32_t {
@@ -182,8 +201,8 @@ func (p *InternalPage) internalNodeRightChild() *uint32_t {
182201
return &p.body.rightChild
183202
}
184203

185-
func (p *InternalPage) internalNodeCell(cellNum uint32_t) *uint32_t {
186-
return &(p.body.cells[cellNum].value)
204+
func (p *InternalPage) internalNodeCell(cellNum uint32_t) *InternalPageCell {
205+
return &(p.body.cells[cellNum])
187206
}
188207

189208
func (p *InternalPage) internalNodeChild(childNum uint32_t) *uint32_t {
@@ -194,7 +213,7 @@ func (p *InternalPage) internalNodeChild(childNum uint32_t) *uint32_t {
194213
} else if childNum == numKeys {
195214
return p.internalNodeRightChild()
196215
}
197-
return p.internalNodeCell(childNum)
216+
return &(p.internalNodeCell(childNum).value)
198217
}
199218

200219
func (p *InternalPage) internalNodeKey(keyNum uint32_t) *uint32_t {
@@ -269,23 +288,27 @@ func (p *Pager) printTree(pageNum, indentationLevel uint32_t) {
269288
}
270289
}
271290

272-
func (t *Table) internalNodeFind(pageNum, key uint32_t) *Cursor {
273-
header, body := t.pager.getPage(pageNum)
274-
internalPage := InternalPage{header: header, body: (*InternalPageBody)(body)}
275-
numKeys := *internalPage.internalNodeNumKeys()
291+
func (p *InternalPage) internalNodeFindChild(key uint32_t) uint32_t {
292+
numKeys := *p.internalNodeNumKeys()
276293

277294
minIndex, maxIndex := uint32_t(0), numKeys
278295
for minIndex != maxIndex {
279296
index := (minIndex + maxIndex) / 2
280-
keyToRight := *internalPage.internalNodeKey(index)
297+
keyToRight := *p.internalNodeKey(index)
281298
if keyToRight >= key {
282299
maxIndex = index
283300
} else {
284301
minIndex = index + 1
285302
}
286303
}
304+
return minIndex
305+
}
287306

288-
childNum := *internalPage.internalNodeCell(minIndex)
307+
func (t *Table) internalNodeFind(pageNum, key uint32_t) *Cursor {
308+
header, body := t.pager.getPage(pageNum)
309+
internalPage := &InternalPage{header: header, body: (*InternalPageBody)(body)}
310+
childIndex := internalPage.internalNodeFindChild(key)
311+
childNum := *internalPage.internalNodeChild(childIndex)
289312
childHeader, _ := t.pager.getPage(childNum)
290313
switch childHeader.pageType {
291314
case PageLeaf:
@@ -298,3 +321,70 @@ func (t *Table) internalNodeFind(pageNum, key uint32_t) *Cursor {
298321
func (p *LeafPage) leafNodeNextLeaf() *uint32_t {
299322
return &(p.body.nextLeaf)
300323
}
324+
325+
func (t *Table) internalNodeInsert(parentPageNum, childPageNum uint32_t) {
326+
parentHeader, parentBody := t.pager.getPage(parentPageNum)
327+
parentPage := InternalPage{header: parentHeader, body: (*InternalPageBody)(parentBody)}
328+
childHeader, childBody := t.pager.getPage(childPageNum)
329+
var childMaxKey uint32_t
330+
if childHeader.pageType == PageLeaf {
331+
childPage := LeafPage{header: childHeader, body: (*LeafPageBody)(childBody)}
332+
childMaxKey = childPage.getMaxKey()
333+
} else {
334+
childPage := InternalPage{header: childHeader, body: (*InternalPageBody)(childBody)}
335+
childMaxKey = childPage.getMaxKey()
336+
}
337+
index := parentPage.internalNodeFindChild(childMaxKey)
338+
339+
originalNumKeys := *parentPage.internalNodeNumKeys()
340+
*parentPage.internalNodeNumKeys() = originalNumKeys + 1
341+
342+
if originalNumKeys >= InternalNodeMaxCells {
343+
fmt.Println("Need to implement splitting internal node")
344+
os.Exit(ExitFailure)
345+
}
346+
347+
rightChildPageNum := *parentPage.internalNodeRightChild()
348+
rightChildHeader, _ := t.pager.getPage(rightChildPageNum)
349+
350+
var rightChildMaxKey uint32_t
351+
if rightChildHeader.pageType == PageLeaf {
352+
rightChildPage := LeafPage{header: childHeader, body: (*LeafPageBody)(childBody)}
353+
rightChildMaxKey = rightChildPage.getMaxKey()
354+
} else {
355+
rightChildPage := InternalPage{header: childHeader, body: (*InternalPageBody)(childBody)}
356+
rightChildMaxKey = rightChildPage.getMaxKey()
357+
}
358+
if childMaxKey > rightChildMaxKey {
359+
*parentPage.internalNodeChild(originalNumKeys) = rightChildPageNum
360+
*parentPage.internalNodeKey(originalNumKeys) = rightChildMaxKey
361+
} else {
362+
for i := originalNumKeys; i > index; i-- {
363+
destination := parentPage.internalNodeCell(i)
364+
source := parentPage.internalNodeCell(i-1)
365+
source.moveTo(destination)
366+
}
367+
*parentPage.internalNodeChild(index) = childPageNum
368+
*parentPage.internalNodeKey(index) = childMaxKey
369+
}
370+
}
371+
372+
373+
374+
375+
376+
377+
378+
379+
380+
381+
382+
383+
384+
385+
386+
387+
388+
389+
390+

db/db_tutorial.go

+5
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,11 @@ func (c *LeafPageCell) moveTo(dest *LeafPageCell) {
175175
((*[LeafNodeCellSize]byte)(unsafe.Pointer(c)))[:])
176176
}
177177

178+
func (c *InternalPageCell) moveTo(dest *InternalPageCell) {
179+
copy(((*[InternalNodeCellSize]byte)(unsafe.Pointer(dest)))[:],
180+
((*[InternalNodeCellSize]byte)(unsafe.Pointer(c)))[:])
181+
}
182+
178183
func pagerOpen(fileName *string) *Pager {
179184
fd, err := os.OpenFile(*fileName, os.O_RDWR|os.O_CREATE, 0755) //fd实际为file指针,文件描述符用*File.fd()获取
180185
if err != nil {

db_test.py

+5-3
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,9 @@ def __init__(self, arg):
3535
self.select = "select"
3636
self.tester = MainTest(arg)
3737

38-
def function_test(self):
38+
def function_test(self, i):
3939
output = ''
40-
cmds = [self.sampleCapacity.format(id=0), self.select]
40+
cmds = [self.sampleCapacity.format(id=i), self.select]
4141
for c in cmds:
4242
self.tester.send(c)
4343
output += self.tester.recv()
@@ -78,4 +78,6 @@ def test_field_capacity(self):
7878
if __name__ == '__main__':
7979
testArgs = ('./main',)
8080
tester = LimitTest(testArgs)
81-
tester.test_table_capacity()
81+
for i in range(20):
82+
tester.function_test(i)
83+
tester.tester.send(tester.exit)

0 commit comments

Comments
 (0)