@@ -61,7 +61,7 @@ const (
61
61
InternalNodeChildSize = uint32_t (unsafe .Sizeof (uint32_t (0 )))
62
62
InternalNodeCellSize = InternalNodeKeySize + InternalNodeChildSize
63
63
InternalNodeSpaceForCells = PageSize - InternalNodeHeaderSize
64
- InternalNodeMaxCells = InternalNodeSpaceForCells / InternalNodeCellSize
64
+ InternalNodeMaxCells = 3
65
65
)
66
66
67
67
const (
@@ -107,10 +107,12 @@ func (p *LeafPage) printLeafNode() {
107
107
func (c * Cursor ) leafNodeSplitAndInsert (key uint32_t , value * Row ) {
108
108
oldHeader , oldBody := c .table .pager .getPage (c .pageNum )
109
109
oldPage := & LeafPage {header : oldHeader , body : (* LeafPageBody )(oldBody )}
110
+ oldMax := oldPage .getMaxKey ()
110
111
newPageNum := c .table .pager .getUnusedPageNum ()
111
112
newHeader , newBody := c .table .pager .getPage (newPageNum )
112
113
newPage := & LeafPage {header : newHeader , body : (* LeafPageBody )(newBody )}
113
114
newPage .initializeLeafNode ()
115
+ newPage .header .parentPointer = oldPage .header .parentPointer
114
116
* newPage .leafNodeNextLeaf () = * oldPage .leafNodeNextLeaf ()
115
117
* oldPage .leafNodeNextLeaf () = newPageNum
116
118
@@ -141,8 +143,17 @@ func (c *Cursor) leafNodeSplitAndInsert(key uint32_t, value *Row) {
141
143
if oldPage .header .isRoot != 0 {
142
144
c .table .createNewRoot (newPageNum )
143
145
} 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 )
146
157
}
147
158
}
148
159
@@ -169,6 +180,14 @@ func (t *Table) createNewRoot(rightChildPageNum uint32_t) {
169
180
leftChildMaxKey := leftChild .getMaxKey ()
170
181
* (internalNode .internalNodeKey (0 )) = leftChildMaxKey
171
182
* (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
172
191
}
173
192
174
193
func (p * InternalPage ) internalNodeNumKeys () * uint32_t {
@@ -182,8 +201,8 @@ func (p *InternalPage) internalNodeRightChild() *uint32_t {
182
201
return & p .body .rightChild
183
202
}
184
203
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 ])
187
206
}
188
207
189
208
func (p * InternalPage ) internalNodeChild (childNum uint32_t ) * uint32_t {
@@ -194,7 +213,7 @@ func (p *InternalPage) internalNodeChild(childNum uint32_t) *uint32_t {
194
213
} else if childNum == numKeys {
195
214
return p .internalNodeRightChild ()
196
215
}
197
- return p .internalNodeCell (childNum )
216
+ return & ( p .internalNodeCell (childNum ). value )
198
217
}
199
218
200
219
func (p * InternalPage ) internalNodeKey (keyNum uint32_t ) * uint32_t {
@@ -269,23 +288,27 @@ func (p *Pager) printTree(pageNum, indentationLevel uint32_t) {
269
288
}
270
289
}
271
290
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 ()
276
293
277
294
minIndex , maxIndex := uint32_t (0 ), numKeys
278
295
for minIndex != maxIndex {
279
296
index := (minIndex + maxIndex ) / 2
280
- keyToRight := * internalPage .internalNodeKey (index )
297
+ keyToRight := * p .internalNodeKey (index )
281
298
if keyToRight >= key {
282
299
maxIndex = index
283
300
} else {
284
301
minIndex = index + 1
285
302
}
286
303
}
304
+ return minIndex
305
+ }
287
306
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 )
289
312
childHeader , _ := t .pager .getPage (childNum )
290
313
switch childHeader .pageType {
291
314
case PageLeaf :
@@ -298,3 +321,70 @@ func (t *Table) internalNodeFind(pageNum, key uint32_t) *Cursor {
298
321
func (p * LeafPage ) leafNodeNextLeaf () * uint32_t {
299
322
return & (p .body .nextLeaf )
300
323
}
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
+
0 commit comments