Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions db_reader.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package nimbusdb

import (
"sync"
"github.com/google/btree"
)

// DbReader is used to iterate over key-value pairs in the database.
type DbReader struct {
db *Db
currentItem btree.Item
mu sync.Mutex
}

// NewDbReader creates a new DbReader for the given database.
func NewDbReader(db *Db) *DbReader {
return &DbReader{
db: db,
}
}

// Read fetches up to n key-value pairs from the database.
func (r *DbReader) Read(n int) ([]*KeyValuePair, error) {
r.mu.Lock()
defer r.mu.Unlock()

var result []*KeyValuePair
var lastItem btree.Item = nil

processItem := func(i btree.Item) bool {
if len(result) >= n {
return false
}
it := i.(*item)
kv := &KeyValuePair{
Key: it.key,
Value: it.v,
}
result = append(result, kv)
lastItem = i
return true
}

// If currentItem is nil, start from the beginning
if r.currentItem == nil {
r.db.keyDir.tree.Ascend(processItem)
} else {
// Continue from the current item
r.db.keyDir.tree.AscendGreaterOrEqual(r.currentItem, processItem)
}

if lastItem != nil {
r.currentItem = lastItem
}

return result, nil
}
38 changes: 38 additions & 0 deletions tests/db_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -293,3 +293,41 @@ func Test_ConcurrentDelete(t *testing.T) {
}
wg.Wait()
}

func TestDbReaderBasicReading(t *testing.T) {
// Initialize database and insert test data
d, err := nimbusdb.Open(opts)
assert.NoError(t, err)
defer d.Close()

// Insert known data into the database
for i := 0; i < 10; i++ {
key := fmt.Sprintf("key%02d", i) // Zero-padding for numeric order
value := fmt.Sprintf("value%d", i)
_, err := d.Set(&nimbusdb.KeyValuePair{Key: []byte(key), Value: []byte(value)})
assert.NoError(t, err)
}

// Initialize DbReader
reader := nimbusdb.NewDbReader(d)

// Read 10 items
items, err := reader.Read(3)
assert.NoError(t, err)
assert.Len(t, items, 3)

// Verify the items
for i, kv := range items {
expectedKey := fmt.Sprintf("key%02d", i)
expectedValue := fmt.Sprintf("value%d", i)
assert.Equal(t, utils.Encode(expectedKey), kv.Key)

// Decoding the value assuming it's a byte slice
// Adjust the decoding based on how it's encoded
valueStr := (kv.Value) // Direct conversion if it's []byte
assert.Equal(t, utils.Encode(expectedValue), valueStr)
}

// Cleanup
os.RemoveAll(opts.Path)
}
18 changes: 18 additions & 0 deletions utils/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,24 @@ func Encode(d interface{}) []byte {
}
}

func Decode(b []byte, originalType interface{}) (interface{}, error) {
switch originalType.(type) {
case string:
return string(b), nil
case int64:
return ByteToInt64(b), nil
case int32:
return ByteToInt32(b), nil
case int:
int32Val := ByteToInt32(b)
return int(int32Val), nil
default:
// Assuming default case is []byte
return b, nil
}
}


func ReadFile(path string) ([]byte, error) {
data, err := os.ReadFile(path)
if err != nil {
Expand Down