Initial commit: SRDB - High-performance LSM-Tree database

- Core engine with MemTable, SST, WAL
- B+Tree indexing for SST files  
- Leveled compaction strategy
- Multi-table database management
- Schema validation and secondary indexes
- Query builder with complex conditions
- Web UI with HTMX for data visualization
- Command-line tools for diagnostics
This commit is contained in:
2025-10-08 06:38:12 +08:00
commit ae87c38776
61 changed files with 15475 additions and 0 deletions

106
btree/reader.go Normal file
View File

@@ -0,0 +1,106 @@
package btree
import (
"sort"
"github.com/edsrzf/mmap-go"
)
// Reader 用于查询 B+Tree (mmap)
type Reader struct {
mmap mmap.MMap
rootOffset int64
}
// NewReader 创建查询器
func NewReader(mmap mmap.MMap, rootOffset int64) *Reader {
return &Reader{
mmap: mmap,
rootOffset: rootOffset,
}
}
// Get 查询 key返回数据位置
func (r *Reader) Get(key int64) (dataOffset int64, dataSize int32, found bool) {
if r.rootOffset == 0 {
return 0, 0, false
}
nodeOffset := r.rootOffset
for {
// 读取节点 (零拷贝)
if nodeOffset+NodeSize > int64(len(r.mmap)) {
return 0, 0, false
}
nodeData := r.mmap[nodeOffset : nodeOffset+NodeSize]
node := Unmarshal(nodeData)
if node == nil {
return 0, 0, false
}
// 叶子节点
if node.NodeType == NodeTypeLeaf {
// 二分查找
idx := sort.Search(len(node.Keys), func(i int) bool {
return node.Keys[i] >= key
})
if idx < len(node.Keys) && node.Keys[idx] == key {
return node.DataOffsets[idx], node.DataSizes[idx], true
}
return 0, 0, false
}
// 内部节点,继续向下
// keys[i] 是分隔符children[i] 包含 < keys[i] 的数据
// children[i+1] 包含 >= keys[i] 的数据
idx := sort.Search(len(node.Keys), func(i int) bool {
return node.Keys[i] > key
})
// idx 现在指向第一个 > key 的位置
// 我们应该走 children[idx]
if idx >= len(node.Children) {
idx = len(node.Children) - 1
}
nodeOffset = node.Children[idx]
}
}
// GetAllKeys 获取 B+Tree 中所有的 key按顺序
func (r *Reader) GetAllKeys() []int64 {
if r.rootOffset == 0 {
return nil
}
var keys []int64
r.traverseLeafNodes(r.rootOffset, func(node *BTreeNode) {
keys = append(keys, node.Keys...)
})
return keys
}
// traverseLeafNodes 遍历所有叶子节点
func (r *Reader) traverseLeafNodes(nodeOffset int64, callback func(*BTreeNode)) {
if nodeOffset+NodeSize > int64(len(r.mmap)) {
return
}
nodeData := r.mmap[nodeOffset : nodeOffset+NodeSize]
node := Unmarshal(nodeData)
if node == nil {
return
}
if node.NodeType == NodeTypeLeaf {
// 叶子节点,执行回调
callback(node)
} else {
// 内部节点,递归遍历所有子节点
for _, childOffset := range node.Children {
r.traverseLeafNodes(childOffset, callback)
}
}
}