commit ca2740a2e7fa7a96a81ca76aca4e84e33b456fb3 Author: Timmelmann <41704604+Timmelmann@users.noreply.github.com> Date: Sat Aug 8 14:29:33 2026 +0200 moved the database-go project to this repository diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..9a9d867 --- /dev/null +++ b/go.mod @@ -0,0 +1,11 @@ +module timmelmann/database + +go 1.24.5 + +require github.com/stretchr/testify v1.11.1 + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..cc8b3f4 --- /dev/null +++ b/go.sum @@ -0,0 +1,9 @@ +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/models/b_tree.go b/models/b_tree.go new file mode 100644 index 0000000..10cc1bf --- /dev/null +++ b/models/b_tree.go @@ -0,0 +1,69 @@ +package models + +import "encoding/binary" +import "testify/assert" +const HEADER = 4 + +const BTREE_PAGE_SIZE = 4096 +const BTREE_MAX_KEY_SIZE = 1000 +const BTREE_MAX_VAL_SIZE = 1000 + +type BNode []byte + +type BTree struct { + root uint64 + get func(uint64) []byte + new func([]byte) uint64 + del func(uint64) +} + +func init() { + noode1max := HEADER + 8 + 2 + 4 + BTREE_MAX_KEY_SIZE + BTREE_MAX_VAL_SIZE + assert(noode1max <= BTREE_PAGE_SIZE) +} + +func (node BNode) btype() uint16 { + return binary.LittleEndian.Uint16(node[0:2]) +} + +func (node BNode) nkeys() uint16 { + return binary.LittleEndian.Uint16(node[2:4]) +} + +func (node BNode) setHeader(btype uint16, nkeys uint16) { + binary.LittleEndian.PutUint16(node[0:2], btype) + binary.LittleEndian.PutUint16(node[2:4], nkeys) +} + +func (node BNode) getPtr(ids uint16) uint64 { + assert(ids < node.nkeys()) + pos := HEADER + 8*ids + return binary.LittleEndian.Uint64(node[pos:]) +} + +func (node BNode) setPtr(idx uint16, val uint64) { + assert(idx <= node.nkeys()) + pos := HEADER + 8*idx + binary.LittleEndian.PutUint64(node[pos:], val) +} + +func (node BNode) getOffset(idx uint16) uint16 { + if (idx == 0) { + return 0 + } + pos := HEADER + 8*node.nkeys() + 2*(idx - 1) + return binary.LittleEndian.Uint16(node[pos:]) +} + +func (node BNode) kvPos(idx uint16) (uint16) { + assert(idx < node.nkeys()) + return 4 + 8*node.nkeys() + 2*node.nkeys() + node.getOffset(idx) +} + +func(node BNode) getKey(idx uint16) []byte { + assert(idx < node.nkeys()) + pos := node.kvPos(idx) + klen := binary.LittleEndian.Uint16(node[pos:]) + vlen := binary.LittleEndian.Uint16(node[pos+2:]) + return node[pos+4+klen:][:vlen] +} \ No newline at end of file diff --git a/models/node.go b/models/node.go new file mode 100644 index 0000000..107edb8 --- /dev/null +++ b/models/node.go @@ -0,0 +1,30 @@ +package models + +import ( + "github.com/stretchr/testify/assert" +) +const ( + BNODE_NODE = 1 + BNODE_LEAF = 2 + BTREE_PAGE_SIZE = 4096 + BTREE_MAX_KEY_SIZE = 1000 + BTREE_MAX_VAL_SIZE = 3000 +) + +type Node struct { + keys [][]byte + vals [][]byte + kids []*Node +} + +func init() { + node1max := HEADER + 8 + 2 + 4 + BTREE_MAX_KEY_SIZE + BTREE_MAX_VAL_SIZE + assert(node1max <= BTREE_PAGE_SIZE) +} +func Encode(node *Node) []byte { + return nil +} + +func Decode(page []byte) (*Node, error) { + return nil, nil +} \ No newline at end of file diff --git a/models/utils.go b/models/utils.go new file mode 100644 index 0000000..7e08d73 --- /dev/null +++ b/models/utils.go @@ -0,0 +1,32 @@ +package models + +import "encoding/binary" + +const ( + BNODE_NODE = 1 + BNODE_LEAF = 2 +) + +func (node BNode) btype() uint16 { + return binary.LittleEndian.Uint16(node[0:2]) +} + + +func (node BNode) nkeys() uint16 { + return binary.LittleEndian.Uint16(node[2:4]) +} + + +func (node BNode) setHeader(btype uint16, nkeys uint16) { + binary.LittleEndian.PutUint16(node[0:2], btype) + binary.LittleEndian.PutUint16(node[2:4], nkeys) +} + +func (node BNode) getPrt(ids uint16) uint64{ + assert(ids < node.nkeys()) + pos := HEADER + 8*ids + return binary.LittleEndian.Uint64(node[pos:]) +} + +func (node BNode) setPtr(idx uint16, val uint64) { +} \ No newline at end of file diff --git a/storage/file_storage.go b/storage/file_storage.go new file mode 100644 index 0000000..070450b --- /dev/null +++ b/storage/file_storage.go @@ -0,0 +1,45 @@ +package storage + +import ( + "fmt" + "os" +) + +func SaveData1(path string, data []byte) error { + file, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0664) + if err != nil { + return err + } + defer file.Close() + + _, err = file.Write(data) + if err != nil { + return err + } + + return file.Sync() +} + +func SaveData2(path string, data []byte) error { + tmp := fmt.Sprintf("%s.tmp.%d", path, randomInt()) + file, err := os.OpenFile(tmp, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0664) + if err != nil { + return err + } + defer func () { + file.Close() + if err != nil { + os.Remove(tmp) + } + }() + + if _, err = file.Write(data); err != nil { + return err + } + if err = file.Sync(); err != nil { + return err + } + + err = os.Rename(tmp, path) + return err +} \ No newline at end of file