Skip to content

Commit db84838

Browse files
committed
Create server
1 parent cbd4b6e commit db84838

File tree

15 files changed

+648
-560
lines changed

15 files changed

+648
-560
lines changed

.tool-versions

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
golang 1.23.1
22
zig 0.13.0
33
bun 1.2.2
4+
buf 1.50.0

secretary/btree.go

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package secretary
22

33
import (
4+
"bytes"
45
"fmt"
56

67
"github.com/codeharik/secretary/utils"
@@ -27,7 +28,7 @@ func NewBTree(
2728

2829
safeCollectionName := utils.SafeCollectionString(collectionName)
2930
if len(safeCollectionName) < 5 || len(safeCollectionName) > MAX_COLLECTION_NAME_LENGTH {
30-
return nil, ErrorInvalidCollectionName()
31+
return nil, ErrorInvalidCollectionName
3132
}
3233

3334
if err := utils.EnsureDir(fmt.Sprintf("%s/%s", SECRETARY, safeCollectionName)); err != nil {
@@ -107,3 +108,48 @@ func (tree *BTree) SaveHeader() error {
107108

108109
return tree.nodeBatchStore.WriteAt(0, header)
109110
}
111+
112+
func NewBTreeReadHeader(collectionName string) (*BTree, error) {
113+
temp, err := NewBTree(collectionName,
114+
10,
115+
0,
116+
0,
117+
125,
118+
0,
119+
)
120+
if err != nil {
121+
return nil, err
122+
}
123+
124+
diskData, err := temp.nodeBatchStore.ReadAt(0, SECRETARY_HEADER_LENGTH)
125+
if err != nil {
126+
return nil, err
127+
}
128+
129+
data := bytes.Trim(diskData, "-")[len(SECRETARY):]
130+
var deserializedTree BTree
131+
err = binstruct.Deserialize(data, &deserializedTree)
132+
if err != nil {
133+
return nil, err
134+
}
135+
136+
return &deserializedTree, nil
137+
}
138+
139+
func (t *BTree) Height() int {
140+
if t.root == nil {
141+
return 0
142+
}
143+
144+
height := 0
145+
node := t.root
146+
for node != nil {
147+
height++
148+
if len(node.children) == 0 { // Leaf node reached
149+
break
150+
}
151+
node = node.children[0] // Move to the first child
152+
}
153+
154+
return height
155+
}

secretary/btree_test.go

Lines changed: 35 additions & 184 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ func TestBtreeInvalid(t *testing.T) {
7474
}
7575
}
7676

77-
func TestSaveHeader(t *testing.T) {
77+
func TestSaveReadHeader(t *testing.T) {
7878
tree, err := NewBTree(
7979
"TestSaveHeader",
8080
10,
@@ -87,210 +87,61 @@ func TestSaveHeader(t *testing.T) {
8787
t.Fatal(err)
8888
}
8989

90-
// Save header
9190
err = tree.SaveHeader()
9291
if err != nil {
9392
t.Fatalf("SaveHeader failed: %v", err)
9493
}
9594

96-
// Retrieve data from mock store
97-
savedData, err := tree.nodeBatchStore.ReadAt(0, SECRETARY_HEADER_LENGTH)
95+
deserializedTree, err := NewBTreeReadHeader(tree.CollectionName)
9896
if err != nil {
99-
t.Fatalf("Failed to read written data: %v", err)
100-
}
101-
102-
// Serialize again for comparison
103-
expectedData, err := tree.createHeader()
104-
if err != nil {
105-
t.Fatalf("Failed to serialize expected data: %v", err)
97+
t.Fatal(err)
10698
}
10799

108-
if len(savedData) != SECRETARY_HEADER_LENGTH {
109-
t.Fatalf("Expected serialized data to be %d bytes, got %d", SECRETARY_HEADER_LENGTH, len(expectedData))
100+
eq, err := binstruct.Compare(*tree, *deserializedTree)
101+
if !eq || err != nil {
102+
t.Fatalf("\nShould be Equal\n")
110103
}
111104

112-
// Compare written data with expected serialized header
113-
if !bytes.Equal(savedData, expectedData) {
114-
t.Errorf("Saved header does not match expected serialized data")
105+
tJson, tErr := binstruct.MarshalJSON(*tree)
106+
dJson, dErr := binstruct.MarshalJSON(deserializedTree)
107+
if dErr != nil || tErr != nil || bytes.Compare(tJson, dJson) != 0 {
108+
t.Log("\n", string(tJson), "\n", string(dJson))
115109
}
116110
}
117111

118-
// func TestSearchOperations(t *testing.T) {
119-
// tree, _ := NewBPlusTree(4)
120-
// keys := []int{10, 5, 15, 20, 25, 30, 35}
121-
122-
// // Test search on empty tree
123-
// if tree.Search(10) {
124-
// t.Error("Search should return false on empty tree")
125-
// }
126-
127-
// // Insert keys and verify existence
128-
// for _, key := range keys {
129-
// tree.Insert(key)
130-
// if !tree.Search(key) {
131-
// t.Errorf("Key %d should exist after insertion", key)
132-
// }
133-
// }
134-
135-
// // Test non-existent keys
136-
// nonExistent := []int{-5, 7, 33, 100}
137-
// for _, key := range nonExistent {
138-
// if tree.Search(key) {
139-
// t.Errorf("Key %d should not exist", key)
140-
// }
141-
// }
142-
143-
// // Test after deletions
144-
// tree.Delete(15)
145-
// if tree.Search(15) {
146-
// t.Error("Deleted key 15 should not exist")
147-
// }
148-
// }
149-
150-
// func TestInsertAndSearch(t *testing.T) {
151-
// tree, _ := NewBPlusTree(4)
152-
// keys := []int{10, 5, 15, 20, 25, 30, 35}
153-
154-
// for _, key := range keys {
155-
// tree.Insert(key)
156-
// }
157-
158-
// // Test existing keys
159-
// for _, key := range keys {
160-
// if !tree.Search(key) {
161-
// t.Errorf("Key %d should exist", key)
162-
// }
163-
// }
164-
165-
// // Test non-existent keys
166-
// nonExistent := []int{-5, 7, 33, 100}
167-
// for _, key := range nonExistent {
168-
// if tree.Search(key) {
169-
// t.Errorf("Key %d should not exist", key)
170-
// }
171-
// }
172-
// }
173-
174-
// func TestLeafNodeOperations(t *testing.T) {
175-
// tree, _ := NewBPlusTree(4)
176-
177-
// // Test single node insertion
178-
// tree.Insert(10)
179-
// if !tree.root.leaf || tree.root.numKeys != 1 {
180-
// t.Error("Root should be single-key leaf node")
181-
// }
182-
183-
// // Test leaf node split
184-
// keys := []int{20, 30, 40} // Fill root leaf node
185-
// for _, key := range keys {
186-
// tree.Insert(key)
187-
// }
188-
189-
// // After inserting 40, the leaf should split
190-
// if tree.root.leaf {
191-
// t.Error("Root should be internal node after split")
192-
// }
193-
// if tree.root.numKeys != 1 {
194-
// t.Error("Root should have one key after first split")
195-
// }
196-
// }
197-
198-
// func TestDeleteOperations(t *testing.T) {
199-
// tree, _ := NewBPlusTree(4)
200-
// keys := []int{5, 10, 15, 20, 25, 30, 35, 40}
201-
// for _, key := range keys {
202-
// tree.Insert(key)
203-
// }
204-
205-
// // Test simple deletion
206-
// tree.Delete(15)
207-
// if tree.Search(15) {
208-
// t.Error("Deleted key 15 should not exist")
209-
// }
210-
211-
// // Test deletion causing rebalance
212-
// tree.Delete(5)
213-
// tree.Delete(10)
214-
// tree.Delete(20)
215-
216-
// remaining := []int{25, 30, 35, 40}
217-
// for _, key := range remaining {
218-
// if !tree.Search(key) {
219-
// t.Errorf("Key %d should exist after deletions", key)
220-
// }
221-
// }
222-
// }
112+
// func TestBTreeHeight(t *testing.T) {
113+
// tree := &BTree{}
223114

224-
// func TestRangeQueries(t *testing.T) {
225-
// tree, _ := NewBPlusTree(4)
226-
// for i := 0; i < 20; i++ {
227-
// tree.Insert(i * 5) // 0, 5, 10, ..., 95
115+
// // Insert first key-value pair (root node only)
116+
// key1 := []byte(utils.GenerateRandomString(16))
117+
// value1 := []byte("Hello world!")
118+
// err := tree.Insert(key1, value1)
119+
// if err != nil {
120+
// t.Errorf("Insert failed: %s", err)
228121
// }
229-
230-
// testCases := []struct {
231-
// start, end int
232-
// expected []int
233-
// }{
234-
// {0, 100, generateSequence(0, 95, 5)},
235-
// {25, 50, generateSequence(25, 50, 5)},
236-
// {12, 18, []int{15}},
237-
// {100, 200, []int{}},
238-
// {0, 0, []int{0}},
122+
// if tree.Height() != 1 {
123+
// t.Errorf("Expected height 1, got %d", tree.Height())
239124
// }
240125

241-
// for _, tc := range testCases {
242-
// result := tree.FindRange(tc.start, tc.end)
243-
// if !slices.Equal(result, tc.expected) {
244-
// t.Errorf("Range [%d-%d] expected %v, got %v",
245-
// tc.start, tc.end, tc.expected, result)
126+
// // Insert more keys to increase height
127+
// for i := 0; i < 3; i++ {
128+
// key := []byte(utils.GenerateRandomString(16))
129+
// value := []byte(fmt.Sprintf("value : %d", i))
130+
// err = tree.Insert(key, value)
131+
// if err != nil {
132+
// t.Errorf("Insert failed: %s", err)
246133
// }
247134
// }
248-
// }
249-
250-
// func TestLeafLinkage(t *testing.T) {
251-
// tree, _ := NewBPlusTree(4)
252-
// keys := []int{5, 10, 15, 20, 25, 30, 35, 40}
253-
// for _, key := range keys {
254-
// tree.Insert(key)
255-
// }
256135

257-
// // Verify leaf order
258-
// expected := []int{5, 10, 15, 20, 25, 30, 35, 40}
259-
// var leaves []int
260-
// current := tree.findLeaf(-1)
261-
// for current != nil {
262-
// leaves = append(leaves, current.keys[:current.numKeys]...)
263-
// current = current.next
136+
// // Check if the height increased after multiple insertions
137+
// if tree.Height() != 3 {
138+
// t.Errorf("Expected height %d", tree.Height())
264139
// }
265140

266-
// if !slices.Equal(leaves, expected) {
267-
// t.Errorf("Leaf traversal order incorrect, got %v", leaves)
268-
// }
269-
// }
270-
271-
// func TestInternalNodeOperations(t *testing.T) {
272-
// tree, _ := NewBPlusTree(4)
273-
274-
// // Insert enough keys to create multiple levels
275-
// for i := 100; i > 0; i-- {
276-
// tree.Insert(i)
277-
// }
278-
279-
// // Verify root properties
280-
// if tree.root.leaf || tree.root.numKeys < 1 {
281-
// t.Error("Root should be internal node with multiple keys")
282-
// }
283-
284-
// // Verify search in deep tree
285-
// if !tree.Search(42) || tree.Search(101) {
286-
// t.Error("Search in deep tree failed")
287-
// }
288-
// }
289-
290-
// func generateSequence(start, end, step int) []int {
291-
// var seq []int
292-
// for i := start; i <= end; i += step {
293-
// seq = append(seq, i)
141+
// jsonOutput, err := tree.ConvertBTreeToJSON()
142+
// if err != nil {
143+
// fmt.Println("Error:", err)
144+
// return
294145
// }
295-
// return seq
146+
// t.Log(tree.Order, jsonOutput)
296147
// }

0 commit comments

Comments
 (0)