When the single root leaf fills up, splitting it needs somewhere to put the separator - so the tree grows a new internal root above it. Today you wire the leaf split into Put and create that new root, taking the tree from one level to two.
Split a full root leaf on insert and create a new internal root holding the separator, raising the tree's height to two.
A leaf split produces a separator that has to live somewhere, and when the leaf that split was the whole tree there is no parent to hold it. The answer is to grow the tree upward: allocate a fresh internal node whose single separator is that key and whose two children are the old leaf (now the left half) and the new right leaf, then point the tree’s root at it. The tree just got one level taller.
This “grow at the root” move is the only way a B+Tree ever increases its height, and it is why all leaves always stay at the same depth - the tree never lengthens one branch, it lifts the whole root. Today handles the first, simplest case, where the thing that splits is the root itself. The next lesson pushes inserts down into a taller tree, where a leaf deep below splits and its separator has to climb back up to an existing parent.
const maxKeys = 3 // small teaching order; real fanout is 255func (t *Tree) Put(key, val uint64) {// insert into root leaf; if it now exceeds maxKeys:// rightID := t.pager.AllocPage()// left,right,sep := splitLeaf(leaf, rightID)// write left to t.root, right to rightID// newRoot := &InternalNode{Keys:[sep], Children:[t.root, rightID]}// t.root = alloc+write(newRoot)}