frostfs-node/pkg/services/object/search/local.go
Leonard Lyubich 08b9ae547a [#45] object/search: Add filtering parent objects
In previous implementation object.Search services allowed to search only
physically stored objects. This limitation did not allow getting the ID of
the split object.

Extend search execution logic with parent object filtering. Parent objects
that passed filters are now included in the result

Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
2020-10-02 11:25:36 +03:00

69 lines
1.5 KiB
Go

package searchsvc
import (
"context"
objectSDK "github.com/nspcc-dev/neofs-api-go/pkg/object"
"github.com/nspcc-dev/neofs-node/pkg/core/object"
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/bucket"
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/localstore"
"github.com/nspcc-dev/neofs-node/pkg/services/object/search/query"
"github.com/pkg/errors"
)
type localStream struct {
query query.Query
storage *localstore.Storage
}
type searchQueryFilter struct {
localstore.FilterPipeline
query query.Query
ch chan<- []*objectSDK.ID
}
func (s *localStream) stream(ctx context.Context, ch chan<- []*objectSDK.ID) error {
idList := make([]*objectSDK.ID, 0)
filter := &searchQueryFilter{
query: s.query,
ch: ch,
}
if err := s.storage.Iterate(filter, func(meta *localstore.ObjectMeta) bool {
select {
case <-ctx.Done():
return true
default:
idList = append(idList, meta.Head().GetID())
return false
}
}); err != nil && !errors.Is(errors.Cause(err), bucket.ErrIteratingAborted) {
return errors.Wrapf(err, "(%T) could not iterate over local storage", s)
}
ch <- idList
return nil
}
func (f *searchQueryFilter) Pass(ctx context.Context, meta *localstore.ObjectMeta) *localstore.FilterResult {
loop:
for obj := meta.Head(); obj.GetID() != nil; obj = object.NewFromSDK(obj.GetParent()) {
if !f.query.Match(obj) {
continue
}
select {
case <-ctx.Done():
break loop
case f.ch <- []*objectSDK.ID{obj.GetID()}:
}
}
return localstore.ResultPass()
}