package indexDB_test import ( "fmt" "os" "runtime" "testing" "time" "apigo.cc/go/cast" "apigo.cc/go/indexDB" "apigo.cc/go/rand" ) func mockVector(dim int) []float32 { v := make([]float32, dim) for i := 0; i < dim; i++ { v[i] = rand.Float[float32](0.0, 1.0) } return v } func reportMem(t *testing.T, msg string) { var m runtime.MemStats runtime.ReadMemStats(&m) t.Logf("%s: Alloc = %v MiB, TotalAlloc = %v MiB, Sys = %v MiB, NumGC = %v", msg, m.Alloc/1024/1024, m.TotalAlloc/1024/1024, m.Sys/1024/1024, m.NumGC) } func TestVectorPerformance(t *testing.T) { fPath := "perf_fulltext" vPath := "perf_vector" defer os.RemoveAll(fPath) defer os.RemoveAll(vPath) dim := 128 count := 1000 embeddingFunc := func(text string) ([]float32, error) { return mockVector(dim), nil } dbUnauth, err := indexDB.GetDB(fPath, vPath, embeddingFunc, nil) if err != nil { t.Fatalf("Failed to create engine: %v", err) } db := dbUnauth.Auth("_system") reportMem(t, "Before adding docs") start := time.Now() for i := 0; i < count; i++ { id := fmt.Sprintf("doc_%d", i) text := fmt.Sprintf("This is document number %d with some content to index for fulltext search.", i) meta := map[string]any{"index": i, "category": "test"} err := db.Add(id, text, meta, nil) if err != nil { t.Fatalf("Failed to add doc %d: %v", i, err) } if (i+1)%200 == 0 { t.Logf("Added %d docs...", i+1) } } t.Logf("Added %d docs in %v", count, time.Since(start)) reportMem(t, "After adding docs") // Search test t.Log("Testing search performance...") start = time.Now() results, err := db.Search("", "document 500", 10, nil) if err != nil { t.Fatalf("Search failed: %v", err) } t.Logf("Search returned %d results in %v", len(results), time.Since(start)) for _, r := range results { t.Logf("Result: ID=%s, Score=%f", r.ID, r.Score) } reportMem(t, "After search") // Filter search t.Log("Testing search with filter...") filter := []indexDB.Condition{ {Field: "index", Operator: "gt", Value: 800}, } start = time.Now() results, err = db.Search("", "document", 10, filter) if err != nil { t.Fatalf("Filtered search failed: %v", err) } t.Logf("Filtered search returned %d results in %v", len(results), time.Since(start)) for _, r := range results { idx := cast.To[float64](r.Metadata["index"]) if idx <= 800 { t.Errorf("Result %s has index %v, expected > 800", r.ID, idx) } } } func BenchmarkSearch(b *testing.B) { fPath := "bench_fulltext" vPath := "bench_vector" defer os.RemoveAll(fPath) defer os.RemoveAll(vPath) dim := 128 embeddingFunc := func(text string) ([]float32, error) { return mockVector(dim), nil } dbUnauth, _ := indexDB.GetDB(fPath, vPath, embeddingFunc, nil) db := dbUnauth.Auth("_system") for i := 0; i < 500; i++ { _ = db.Add(fmt.Sprintf("d%d", i), "content", nil, nil) } b.ResetTimer() for i := 0; i < b.N; i++ { _, _ = db.Search("", "content", 10, nil) } }