diff --git a/pkg/local_object_storage/engine/error_test.go b/pkg/local_object_storage/engine/error_test.go index 9655034ac..fc56b8df6 100644 --- a/pkg/local_object_storage/engine/error_test.go +++ b/pkg/local_object_storage/engine/error_test.go @@ -19,7 +19,7 @@ import ( const errSmallSize = 256 -func newEngineWithErrorThreshold(t *testing.T, dir string, errThreshold uint32) (*StorageEngine, string, [2]*shard.ID) { +func newEngineWithErrorThreshold(t testing.TB, dir string, errThreshold uint32) (*StorageEngine, string, [2]*shard.ID) { if dir == "" { var err error diff --git a/pkg/local_object_storage/engine/tree_test.go b/pkg/local_object_storage/engine/tree_test.go new file mode 100644 index 000000000..ef79deb8e --- /dev/null +++ b/pkg/local_object_storage/engine/tree_test.go @@ -0,0 +1,72 @@ +package engine + +import ( + "strconv" + "testing" + + "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/pilorama" + cidtest "github.com/nspcc-dev/neofs-sdk-go/container/id/test" + "github.com/nspcc-dev/neofs-sdk-go/object" +) + +func BenchmarkTreeVsSearch(b *testing.B) { + b.Run("10 objects", func(b *testing.B) { + benchmarkTreeVsSearch(b, 10) + }) + b.Run("100 objects", func(b *testing.B) { + benchmarkTreeVsSearch(b, 100) + }) + b.Run("1000 objects", func(b *testing.B) { + benchmarkTreeVsSearch(b, 1000) + }) +} + +func benchmarkTreeVsSearch(b *testing.B, objCount int) { + e, _, _ := newEngineWithErrorThreshold(b, "", 0) + cid := cidtest.ID() + treeID := "someTree" + + for i := 0; i < objCount; i++ { + obj := generateObjectWithCID(b, cid) + addAttribute(obj, pilorama.AttributeFilename, strconv.Itoa(i)) + err := Put(e, obj) + if err != nil { + b.Fatal(err) + } + _, err = e.TreeAddByPath(cid, treeID, pilorama.AttributeFilename, nil, + []pilorama.KeyValue{{pilorama.AttributeFilename, []byte(strconv.Itoa(i))}}) + if err != nil { + b.Fatal(err) + } + } + + b.Run("search", func(b *testing.B) { + var prm SelectPrm + prm.WithContainerID(cid) + + var fs object.SearchFilters + fs.AddFilter(pilorama.AttributeFilename, strconv.Itoa(objCount/2), object.MatchStringEqual) + prm.WithFilters(fs) + + for i := 0; i < b.N; i++ { + res, err := e.Select(prm) + if err != nil { + b.Fatal(err) + } + if count := len(res.addrList); count != 1 { + b.Fatalf("expected 1 object, got %d", count) + } + } + }) + b.Run("TreeGetByPath", func(b *testing.B) { + for i := 0; i < b.N; i++ { + nodes, err := e.TreeGetByPath(cid, treeID, pilorama.AttributeFilename, []string{strconv.Itoa(objCount / 2)}, true) + if err != nil { + b.Fatal(err) + } + if count := len(nodes); count != 1 { + b.Fatalf("expected 1 object, got %d", count) + } + } + }) +}