From b2ebca7a5e2db98276d1e26afbc93ad284355637 Mon Sep 17 00:00:00 2001 From: zhonghong Date: Sat, 11 May 2024 18:30:27 +0800 Subject: [PATCH] B tree --- .gitignore | 1 + bTree.go | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ go.mod | 3 +++ 3 files changed, 75 insertions(+) create mode 100644 .gitignore create mode 100644 bTree.go create mode 100644 go.mod diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..723ef36 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.idea \ No newline at end of file diff --git a/bTree.go b/bTree.go new file mode 100644 index 0000000..3b8252b --- /dev/null +++ b/bTree.go @@ -0,0 +1,71 @@ +package bluedb + +import "encoding/binary" + +// BNode +// | type | nkeys | pointers | offsets | key-values +// | 2B | 2B | nkeys * 8B | nkeys * 2B | ... +// This is the format of the KV pair. Lengths followed by data. +// | klen | vlen | key | val | +// | 2B | 2B | ... | ... | +type BNode struct { + data []byte +} + +type BTree struct { + // 根节点指针 + root uint64 + + // 获取BNode + get func(uint64) BNode + // 分配一个新页 + new func(BNode) uint64 + // 删除页 + del func(BNode) +} + +// 页配置 +const ( + HEADER = 4 + BTREE_PAGE_SIZE = 4096 + BTREE_MAX_KEY_LEN = 1000 + BTREE_MAX_VALUE_LEN = 3000 +) + +func init() { + nodeMax := HEADER + 8 + 2 + 4 + BTREE_MAX_KEY_LEN + BTREE_MAX_VALUE_LEN + assert(nodeMax <= BTREE_PAGE_SIZE) +} + +func assert(expression bool) { + if !expression { + panic("校验不通过") + } +} + +// header +func (node *BNode) dataType() uint16 { + return binary.LittleEndian.Uint16(node.data) +} + +func (node *BNode) keyCount() uint16 { + return binary.LittleEndian.Uint16(node.data[2:4]) +} + +func (node *BNode) setHeader(dataType uint16, keyCount uint16) { + binary.LittleEndian.PutUint16(node.data[0:2], dataType) + binary.LittleEndian.PutUint16(node.data[2:4], keyCount) +} + +// pointer +func (node *BNode) getPointer(idNum uint16) uint64 { + assert(idNum < node.keyCount()) + pos := HEADER + 8*idNum + return binary.LittleEndian.Uint64(node.data[pos:]) +} + +func (node *BNode) setPointer(idNum uint16, val uint64) { + assert(idNum < node.keyCount()) + pos := HEADER + 8*idNum + binary.LittleEndian.PutUint64(node.data[pos:], val) +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..197e3e1 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module bluedb + +go 1.19