package benchmark import ( "context" "fmt" "testing" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/teststore" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/testutil" meta "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/metabase" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/writecache" "github.com/stretchr/testify/require" ) func BenchmarkWritecacheSeq(b *testing.B) { const payloadSize = 8 << 10 b.Run("bbolt_seq", func(b *testing.B) { benchmarkPutSeq(b, newCache(b), payloadSize) }) } func BenchmarkWritecachePar(b *testing.B) { const payloadSize = 8 << 10 b.Run("bbolt_par", func(b *testing.B) { benchmarkPutPar(b, newCache(b), payloadSize) }) } func BenchmarkWriteAfterDelete(b *testing.B) { const payloadSize = 32 << 10 const parallel = 25 cache := newCache(b) benchmarkPutPrepare(b, cache) b.Run(fmt.Sprintf("%dB_before", payloadSize), func(b *testing.B) { b.SetParallelism(parallel) benchmarkRunPar(b, cache, payloadSize) }) require.NoError(b, cache.Flush(context.Background(), false, false)) b.Run(fmt.Sprintf("%dB_after", payloadSize), func(b *testing.B) { b.SetParallelism(parallel) benchmarkRunPar(b, cache, payloadSize) }) require.NoError(b, cache.Close(context.Background())) } func benchmarkPutSeq(b *testing.B, cache writecache.Cache, size uint64) { benchmarkPutPrepare(b, cache) defer func() { require.NoError(b, cache.Close(context.Background())) }() ctx := context.Background() objGen := testutil.RandObjGenerator{ObjSize: size} b.ResetTimer() for range b.N { obj := objGen.Next() rawData, err := obj.Marshal() require.NoError(b, err, "marshaling object") prm := common.PutPrm{ Address: testutil.AddressFromObject(b, obj), Object: obj, RawData: rawData, } if _, err := cache.Put(ctx, prm); err != nil { b.Fatalf("putting: %v", err) } } } func benchmarkPutPar(b *testing.B, cache writecache.Cache, size uint64) { benchmarkPutPrepare(b, cache) defer func() { require.NoError(b, cache.Close(context.Background())) }() benchmarkRunPar(b, cache, size) } func benchmarkRunPar(b *testing.B, cache writecache.Cache, size uint64) { ctx := context.Background() b.ResetTimer() b.RunParallel(func(pb *testing.PB) { objGen := testutil.RandObjGenerator{ObjSize: size} for pb.Next() { obj := objGen.Next() rawData, err := obj.Marshal() require.NoError(b, err, "marshaling object") prm := common.PutPrm{ Address: testutil.AddressFromObject(b, obj), Object: obj, RawData: rawData, } if _, err := cache.Put(ctx, prm); err != nil { b.Fatalf("putting: %v", err) } } }) } func benchmarkPutPrepare(b *testing.B, cache writecache.Cache) { require.NoError(b, cache.Open(context.Background(), mode.ReadWrite), "opening") require.NoError(b, cache.Init(context.Background()), "initializing") } type testMetabase struct{} func (testMetabase) UpdateStorageID(context.Context, meta.UpdateStorageIDPrm) (meta.UpdateStorageIDRes, error) { return meta.UpdateStorageIDRes{}, nil } func newCache(b *testing.B) writecache.Cache { bs := teststore.New( teststore.WithPut(func(pp common.PutPrm) (common.PutRes, error) { return common.PutRes{}, nil }), ) return writecache.New( writecache.WithPath(b.TempDir()), writecache.WithBlobstor(bs), writecache.WithMetabase(testMetabase{}), writecache.WithMaxCacheSize(256<<30), ) }