Files
srdb/sst/sst_test.go
bourdon ae87c38776 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
2025-10-08 06:38:28 +08:00

184 lines
3.4 KiB
Go

package sst
import (
"os"
"testing"
)
func TestSST(t *testing.T) {
// 1. 创建测试文件
file, err := os.Create("test.sst")
if err != nil {
t.Fatal(err)
}
defer os.Remove("test.sst")
// 2. 写入数据
writer := NewWriter(file)
// 添加 1000 行数据
for i := int64(1); i <= 1000; i++ {
row := &Row{
Seq: i,
Time: 1000000 + i,
Data: map[string]interface{}{
"name": "user_" + string(rune(i)),
"age": 20 + i%50,
},
}
err := writer.Add(row)
if err != nil {
t.Fatal(err)
}
}
// 完成写入
err = writer.Finish()
if err != nil {
t.Fatal(err)
}
file.Close()
t.Logf("Written 1000 rows")
// 3. 读取数据
reader, err := NewReader("test.sst")
if err != nil {
t.Fatal(err)
}
defer reader.Close()
// 验证 Header
header := reader.GetHeader()
if header.RowCount != 1000 {
t.Errorf("Expected 1000 rows, got %d", header.RowCount)
}
if header.MinKey != 1 {
t.Errorf("Expected MinKey=1, got %d", header.MinKey)
}
if header.MaxKey != 1000 {
t.Errorf("Expected MaxKey=1000, got %d", header.MaxKey)
}
t.Logf("Header: RowCount=%d, MinKey=%d, MaxKey=%d",
header.RowCount, header.MinKey, header.MaxKey)
// 4. 查询测试
for i := int64(1); i <= 1000; i++ {
row, err := reader.Get(i)
if err != nil {
t.Errorf("Failed to get key %d: %v", i, err)
continue
}
if row.Seq != i {
t.Errorf("Key %d: expected Seq=%d, got %d", i, i, row.Seq)
}
if row.Time != 1000000+i {
t.Errorf("Key %d: expected Time=%d, got %d", i, 1000000+i, row.Time)
}
}
// 测试不存在的 key
_, err = reader.Get(1001)
if err == nil {
t.Error("Key 1001 should not exist")
}
_, err = reader.Get(0)
if err == nil {
t.Error("Key 0 should not exist")
}
t.Log("All tests passed!")
}
func TestHeaderSerialization(t *testing.T) {
// 创建 Header
header := &Header{
Magic: MagicNumber,
Version: Version,
Compression: CompressionSnappy,
IndexOffset: 256,
IndexSize: 1024,
RootOffset: 512,
DataOffset: 2048,
DataSize: 10240,
RowCount: 100,
MinKey: 1,
MaxKey: 100,
MinTime: 1000000,
MaxTime: 1000100,
}
// 序列化
data := header.Marshal()
if len(data) != HeaderSize {
t.Errorf("Expected size %d, got %d", HeaderSize, len(data))
}
// 反序列化
header2 := UnmarshalHeader(data)
if header2 == nil {
t.Fatal("Unmarshal failed")
}
// 验证
if header2.Magic != header.Magic {
t.Error("Magic mismatch")
}
if header2.Version != header.Version {
t.Error("Version mismatch")
}
if header2.Compression != header.Compression {
t.Error("Compression mismatch")
}
if header2.RowCount != header.RowCount {
t.Error("RowCount mismatch")
}
if header2.MinKey != header.MinKey {
t.Error("MinKey mismatch")
}
if header2.MaxKey != header.MaxKey {
t.Error("MaxKey mismatch")
}
// 验证
if !header2.Validate() {
t.Error("Header validation failed")
}
t.Log("Header serialization test passed!")
}
func BenchmarkSSTGet(b *testing.B) {
// 创建测试文件
file, _ := os.Create("bench.sst")
defer os.Remove("bench.sst")
writer := NewWriter(file)
for i := int64(1); i <= 10000; i++ {
row := &Row{
Seq: i,
Time: 1000000 + i,
Data: map[string]interface{}{
"value": i,
},
}
writer.Add(row)
}
writer.Finish()
file.Close()
// 打开读取器
reader, _ := NewReader("bench.sst")
defer reader.Close()
// 性能测试
b.ResetTimer()
for i := 0; i < b.N; i++ {
key := int64(i%10000 + 1)
reader.Get(key)
}
}