Skip to content

Commit

Permalink
Initial insertion
Browse files Browse the repository at this point in the history
  • Loading branch information
eliben committed Aug 31, 2024
1 parent d77be85 commit 5c38eb6
Showing 1 changed file with 46 additions and 0 deletions.
46 changes: 46 additions & 0 deletions btree/btree.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package btree

import "slices"

type BTree[K, V any] struct {
cmp func(K, K) int

Expand All @@ -10,6 +12,7 @@ type BTree[K, V any] struct {
// the root must have between t-1 and 2t-1 keys (inclusive).
// Nodes with 2t-1 keys are considered "full".
const tee = 10
const teeFull = tee*2 - 1

type node[K, V any] struct {
// Key ordering invariants (defining n=len(keys)):
Expand Down Expand Up @@ -72,3 +75,46 @@ func (bt *BTree[K, V]) getFromNode(key K, n *node[K, V]) (v V, ok bool) {
// recurse into children[i]
return bt.getFromNode(key, n.children[i])
}

// splitChild splits n.children[i] into two children nodes and moves the
// median key of n.children[i] into n. It assumes that n isn't full,
// but n.children[i] is full.
func (bt *BTree[K, V]) splitChild(n *node[K, V], i int) {
// Notation: y is the i-th child of n (the one being split), and z is the
// new node created to adopt y's t-1 largest keys.
y := n.children[i]
if len(n.keys) == teeFull || len(y.keys) != teeFull {
panic("expect n to be non-full and y to be full")
}
z := &node[K, V]{
leaf: y.leaf,
}

// Move keys to z.
// Before the move, y.keys:
//
// k[0] k[1] ... k[t-2] k[t-1] k[t] k[t+1] ... k[2t-2]
//
// k[t-1] is the median key -- it will move to n.
// k[0]..k[t-2] will stay with y
// k[t]..k[2t-2] will move to z
z.keys = make([]nodeKey[K, V], tee-1)
medianKey := y.keys[tee-1]
copy(z.keys, y.keys[tee:])
y.keys = y.keys[:tee-1]

// Move children to z.
//
// The first t children stay with y; the other t children move to z.
if !y.leaf {
z.children = make([]*node[K, V], tee)
copy(z.children, y.children[tee:])
y.children = y.children[:tee]
}

// Place the median key in n
n.keys = slices.Insert(n.keys, i, medianKey)

// Place the pointer to z after the pointer to y in n
n.children = slices.Insert(n.children, i+1, z)
}

0 comments on commit 5c38eb6

Please sign in to comment.