diff --git a/vindex/map_test.go b/vindex/map_test.go index 769f28c..1e89164 100644 --- a/vindex/map_test.go +++ b/vindex/map_test.go @@ -22,6 +22,7 @@ import ( "crypto/sha256" "fmt" "iter" + "math/rand" "os" "path" "sync" @@ -43,6 +44,9 @@ import ( const ( skey = "PRIVATE+KEY+logandmap+38581672+AXJ0FKWOcO2ch6WC8kP705Ed3Gxu7pVtZLhfHAQwp+FE" vkey = "logandmap+38581672+Ab/PCr1eCclRPRMBqw/r5An1xO71MCnImLiospEq6b4l" + + benchNumEntries = 10000 + benchDuplicationRatio = 0.5 ) func TestVerifiableIndex(t *testing.T) { @@ -338,3 +342,86 @@ func (s *inMemoryTreeSource) Append(leafStr string) { s.leaves = append(s.leaves, leaf) s.t.Append(rfc6962.DefaultHasher.HashLeaf(leaf)) } + +func runBenchmark(b *testing.B, opts vindex.Options) { + ctx := context.Background() + s, v, err := fnote.NewEd25519SignerVerifier(skey) + if err != nil { + b.Fatal(err) + } + + inputLog := &inMemoryTreeSource{ + t: testonly.New(rfc6962.DefaultHasher), + leaves: make([][]byte, 0), + s: s, + v: v, + } + + rng := rand.New(rand.NewSource(12345)) + + var uniqueKeys []string + for i := range benchNumEntries { + var key string + if len(uniqueKeys) > 0 && rng.Float64() < benchDuplicationRatio { + key = uniqueKeys[rng.Intn(len(uniqueKeys))] + } else { + key = fmt.Sprintf("key-%d", len(uniqueKeys)) + uniqueKeys = append(uniqueKeys, key) + } + inputLog.Append(fmt.Sprintf("%s: %d", key, i)) + } + + mapFn := func(leaf []byte) [][sha256.Size]byte { + k, _, found := bytes.Cut(leaf, []byte(":")) + if !found { + panic("colon not found") + } + return [][sha256.Size]byte{sha256.Sum256(k)} + } + + b.ResetTimer() + b.ReportAllocs() + + for b.Loop() { + b.StopTimer() + dir, err := os.MkdirTemp("", "vindex-bench") + if err != nil { + b.Fatal(err) + } + + iterCtx, iterCancel := context.WithCancel(ctx) + + outputLog, closer, err := vindex.NewOutputLog(iterCtx, path.Join(dir, "outputlog"), s, v, vindex.OutputLogOpts{}) + b.Cleanup(func() { + iterCancel() + _ = os.RemoveAll(dir) + if closer != nil { + closer() + } + }) + if err != nil { + b.Fatal(err) + } + + vi, err := vindex.NewVerifiableIndex(iterCtx, inputLog, mapFn, outputLog, dir, opts) + if err != nil { + b.Fatal(err) + } + + b.StartTimer() + if err := vi.Update(iterCtx); err != nil { + b.Fatal(err) + } + if err := vi.Close(); err != nil { + b.Fatal(err) + } + } +} + +func BenchmarkBuild_InMemory(b *testing.B) { + runBenchmark(b, vindex.Options{PersistIndex: false}) +} + +func BenchmarkBuild_OnDisk(b *testing.B) { + runBenchmark(b, vindex.Options{PersistIndex: true}) +}