From 82f5bc77acae6afb2997742a9a6aefe1dac8f0da Mon Sep 17 00:00:00 2001 From: chewxy Date: Wed, 18 Nov 2020 10:59:01 +1100 Subject: [PATCH 1/3] Updated node.search to add a linear search if numKeys < 4 --- z/btree.go | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/z/btree.go b/z/btree.go index 38d4f21c..c0c8beac 100644 --- a/z/btree.go +++ b/z/btree.go @@ -494,28 +494,6 @@ func (n node) search(k uint64) int { return N } return int(simd.Search(n[:2*N], k)) - // lo, hi := 0, N - // // Reduce the search space using binary seach and then do linear search. - // for hi-lo > 32 { - // mid := (hi + lo) / 2 - // km := n.key(mid) - // if k == km { - // return mid - // } - // if k > km { - // // key is greater than the key at mid, so move right. - // lo = mid + 1 - // } else { - // // else move left. - // hi = mid - // } - // } - // for i := lo; i <= hi; i++ { - // if ki := n.key(i); ki >= k { - // return i - // } - // } - // return N } func (n node) maxKey() uint64 { idx := n.numKeys() From 160e517550b6da3bb935caab28b9f13c4b87c1a5 Mon Sep 17 00:00:00 2001 From: chewxy Date: Wed, 18 Nov 2020 15:27:27 +1100 Subject: [PATCH 2/3] More being done. But at this point it touches too much for me to be comfortable with --- z/btree.go | 66 +++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 60 insertions(+), 6 deletions(-) diff --git a/z/btree.go b/z/btree.go index c0c8beac..a3d821e5 100644 --- a/z/btree.go +++ b/z/btree.go @@ -63,7 +63,7 @@ func (t *Tree) initRootNode() { // This is the root node. t.newNode(0) // This acts as the rightmost pointer (all the keys are <= this key). - t.Set(absoluteMax, 0) + t.setRightmost(absoluteMax, 0) } // NewTree returns a memory mapped B+ tree with given filename. @@ -153,6 +153,8 @@ func BytesToUint64Slice(b []byte) []uint64 { } func (t *Tree) newNode(bit uint64) node { + //pc, _, line, _ := runtime.Caller(1) + //log.Printf("%v:%v called newnode %d", runtime.FuncForPC(pc).Name(), line, bit) var pageId uint64 if t.freePage > 0 { pageId = t.freePage @@ -172,6 +174,7 @@ func (t *Tree) newNode(bit uint64) node { } zeroOut(n) n.setBit(bit) + //log.Printf("isLeaf? %v", n.isLeaf()) n.setAt(keyOffset(maxKeys), pageId) return n } @@ -197,10 +200,12 @@ func (t *Tree) node(pid uint64) node { // Set sets the key-value pair in the tree. func (t *Tree) Set(k, v uint64) { + //pc, _, line, _ := runtime.Caller(1) + //log.Printf("%v:%v called Set k %d v %d", runtime.FuncForPC(pc).Name(), line, k, v) if k == math.MaxUint64 || k == 0 { panic("Error setting zero or MaxUint64") } - root := t.set(1, k, v) + root := t.set(1, k, v, false) if root.isFull() { right := t.split(1) left := t.newNode(root.bits()) @@ -221,10 +226,16 @@ func (t *Tree) Set(k, v uint64) { // For internal nodes, they contain . // where all entries <= key are stored in the corresponding ptr. -func (t *Tree) set(pid, k, v uint64) node { +func (t *Tree) set(pid, k, v uint64, isRightmost bool) node { + //pc, _, line, _ := runtime.Caller(1) + //log.Printf("%v:%v called set pid %d k %v v %v", runtime.FuncForPC(pc).Name(), line, pid, k, v) n := t.node(pid) if n.isLeaf() { - return n.set(k, v) + // log.Printf("isLeaf. isRightmost %v", isRightmost) + if !isRightmost { + return n.setAsLeaf(k, v) + } + return n.setRightmostLeaf(k, v) } // This is an internal node. @@ -243,7 +254,7 @@ func (t *Tree) set(pid, k, v uint64) node { n = t.node(pid) n.setAt(valOffset(idx), child.pageID()) } - child = t.set(child.pageID(), k, v) + child = t.set(child.pageID(), k, v, isRightmost) // Re-read n as the underlying buffer for tree might have changed during set. n = t.node(pid) if child.isFull() { @@ -265,6 +276,32 @@ func (t *Tree) set(pid, k, v uint64) node { return n } +// setRightmost sets the key-value pair in the tree. +func (t *Tree) setRightmost(k, v uint64) { + //pc, _, line, _ := runtime.Caller(1) + //log.Printf("%v:%v called setRightmost k %d v %d", runtime.FuncForPC(pc).Name(), line, k, v) + if k == math.MaxUint64 || k == 0 { + panic("Error setting zero or MaxUint64") + } + root := t.set(1, k, v, true) + if root.isFull() { + right := t.split(1) + left := t.newNode(root.bits()) + // Re-read the root as the underlying buffer for tree might have changed during split. + root = t.node(1) + copy(left[:keyOffset(maxKeys)], root) + left.setNumKeys(root.numKeys()) + + // reset the root node. + zeroOut(root[:keyOffset(maxKeys)]) + root.setNumKeys(0) + + // set the pointers for left and right child in the root node. + root.set(left.maxKey(), left.pageID()) + root.set(right.maxKey(), right.pageID()) + } +} + // Get looks for key and returns the corresponding value. // If key is not found, 0 is returned. func (t *Tree) Get(k uint64) uint64 { @@ -377,7 +414,7 @@ func (t *Tree) split(pid uint64) node { nn := t.newNode(n.bits()) // Re-read n as the underlying buffer for tree might have changed during newNode. n = t.node(pid) - rightHalf := n[keyOffset(maxKeys/2):keyOffset(maxKeys)] + rightHalf := n[keyOffset(maxKeys/2):keyOffset(maxKeys-1)] copy(nn, rightHalf) nn.setNumKeys(maxKeys - maxKeys/2) @@ -440,6 +477,7 @@ func (n node) val(i int) uint64 { return n.uint64(valOffset(i)) } func (n node) data(i int) []uint64 { return n[keyOffset(i):keyOffset(i+1)] } func (n node) setAt(start int, k uint64) { + //log.Printf("set %v at %v", k, start) n[start] = k } @@ -571,6 +609,22 @@ func (n node) set(k, v uint64) node { panic("shouldn't reach here") } +func (n node) setAsLeaf(k, v uint64) node { + idx := n.numKeys() + //log.Printf("%v\n%v", idx, n) + n.setAt(keyOffset(idx), k) + n.setAt(valOffset(idx), v) + n.setNumKeys(n.numKeys() + 1) + return n +} +func (n node) setRightmostLeaf(k, v uint64) node { + idx := maxKeys - 1 + n.setAt(keyOffset(idx), k) + n.setAt(valOffset(idx), v) + n.setNumKeys(n.numKeys() + 1) + return n +} + func (n node) iterate(fn func(node, int)) { for i := 0; i < maxKeys; i++ { if k := n.key(i); k > 0 { From 54dc6e1b06468a11c1542f92e540c52793fe6081 Mon Sep 17 00:00:00 2001 From: chewxy Date: Wed, 18 Nov 2020 15:28:41 +1100 Subject: [PATCH 3/3] wat --- z/btree.go | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/z/btree.go b/z/btree.go index a3d821e5..18b79810 100644 --- a/z/btree.go +++ b/z/btree.go @@ -153,8 +153,6 @@ func BytesToUint64Slice(b []byte) []uint64 { } func (t *Tree) newNode(bit uint64) node { - //pc, _, line, _ := runtime.Caller(1) - //log.Printf("%v:%v called newnode %d", runtime.FuncForPC(pc).Name(), line, bit) var pageId uint64 if t.freePage > 0 { pageId = t.freePage @@ -174,7 +172,6 @@ func (t *Tree) newNode(bit uint64) node { } zeroOut(n) n.setBit(bit) - //log.Printf("isLeaf? %v", n.isLeaf()) n.setAt(keyOffset(maxKeys), pageId) return n } @@ -200,8 +197,6 @@ func (t *Tree) node(pid uint64) node { // Set sets the key-value pair in the tree. func (t *Tree) Set(k, v uint64) { - //pc, _, line, _ := runtime.Caller(1) - //log.Printf("%v:%v called Set k %d v %d", runtime.FuncForPC(pc).Name(), line, k, v) if k == math.MaxUint64 || k == 0 { panic("Error setting zero or MaxUint64") } @@ -227,11 +222,8 @@ func (t *Tree) Set(k, v uint64) { // For internal nodes, they contain . // where all entries <= key are stored in the corresponding ptr. func (t *Tree) set(pid, k, v uint64, isRightmost bool) node { - //pc, _, line, _ := runtime.Caller(1) - //log.Printf("%v:%v called set pid %d k %v v %v", runtime.FuncForPC(pc).Name(), line, pid, k, v) n := t.node(pid) if n.isLeaf() { - // log.Printf("isLeaf. isRightmost %v", isRightmost) if !isRightmost { return n.setAsLeaf(k, v) } @@ -278,8 +270,6 @@ func (t *Tree) set(pid, k, v uint64, isRightmost bool) node { // setRightmost sets the key-value pair in the tree. func (t *Tree) setRightmost(k, v uint64) { - //pc, _, line, _ := runtime.Caller(1) - //log.Printf("%v:%v called setRightmost k %d v %d", runtime.FuncForPC(pc).Name(), line, k, v) if k == math.MaxUint64 || k == 0 { panic("Error setting zero or MaxUint64") } @@ -477,7 +467,6 @@ func (n node) val(i int) uint64 { return n.uint64(valOffset(i)) } func (n node) data(i int) []uint64 { return n[keyOffset(i):keyOffset(i+1)] } func (n node) setAt(start int, k uint64) { - //log.Printf("set %v at %v", k, start) n[start] = k } @@ -611,7 +600,6 @@ func (n node) set(k, v uint64) node { func (n node) setAsLeaf(k, v uint64) node { idx := n.numKeys() - //log.Printf("%v\n%v", idx, n) n.setAt(keyOffset(idx), k) n.setAt(valOffset(idx), v) n.setNumKeys(n.numKeys() + 1)