Skip to content

Commit

Permalink
fix(filter): create hybrid scheme (#164)
Browse files Browse the repository at this point in the history
  • Loading branch information
plastikfan committed Sep 8, 2024
1 parent 0c2d20b commit 59f3844
Show file tree
Hide file tree
Showing 36 changed files with 653 additions and 491 deletions.
3 changes: 1 addition & 2 deletions Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ tasks:
cmds:
- go test ./core

tf-filter:
tf:
cmds:
- go test ./internal/filtering

Expand Down Expand Up @@ -191,7 +191,6 @@ tasks:
- mkdir -p ./internal/kernel/coverage
- mkdir -p ./internal/level/coverage
- mkdir -p ./internal/measure/coverage
- mkdir -p ./internal/override/coverage
- mkdir -p ./internal/services/coverage
- mkdir -p ./internal/level/coverage
- mkdir -p ./internal/third/bus/coverage
Expand Down
21 changes: 2 additions & 19 deletions builders.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"github.com/snivilised/traverse/enums"
"github.com/snivilised/traverse/internal/kernel"
"github.com/snivilised/traverse/internal/measure"
"github.com/snivilised/traverse/internal/override"
"github.com/snivilised/traverse/internal/third/lo"
"github.com/snivilised/traverse/internal/types"
"github.com/snivilised/traverse/pref"
Expand All @@ -18,6 +17,7 @@ type buildArtefacts struct {
}

type Builders struct {
using *pref.Using
readerFS pref.ReadDirFileSystemBuilder
queryFS pref.QueryStatusFileSystemBuilder
options optionsBuilder
Expand Down Expand Up @@ -48,22 +48,6 @@ func (bs *Builders) buildAll() (*buildArtefacts, error) {

// BUILD NAVIGATOR
//
actions := &override.Actions{
HandleChildren: override.NewActionCtrl[override.HandleChildrenInterceptor](
func(inspection override.Inspection, mums measure.MutableMetrics) {
// [KEEP-FILTER-IN-SYNC] keep this in sync with filter-plugin/childScheme.init
files := inspection.Sort(enums.EntryTypeFile)
inspection.AssignChildren(files)

// The behaviour of this default child handler is to assign
// the children and tick the metrics. However, when filtering is
// active, then this handler should be overridden by the filter
// to only tick the child metric, if their parent is filtered in.
//
mums[enums.MetricNoChildFilesFound].Times(uint(len(files)))
},
),
}

artefacts, navErr := bs.navigator.Build(o, &types.Resources{
FS: FileSystems{
Expand All @@ -72,7 +56,6 @@ func (bs *Builders) buildAll() (*buildArtefacts, error) {
R: ext.resFS(),
},
Supervisor: measure.New(),
Actions: actions,
})

if navErr != nil {
Expand All @@ -86,6 +69,7 @@ func (bs *Builders) buildAll() (*buildArtefacts, error) {
// BUILD PLUGINS
//
plugins, pluginsErr := bs.plugins.build(o,
bs.using,
artefacts.Mediator,
artefacts.Kontroller,
ext.plugin(artefacts),
Expand All @@ -109,7 +93,6 @@ func (bs *Builders) buildAll() (*buildArtefacts, error) {
order := manifest(active)
artefacts.Mediator.Arrange(active, order)
pi := &types.PluginInit{
Actions: actions,
O: o,
Controls: artefacts.Mediator.Controls(),
}
Expand Down
11 changes: 7 additions & 4 deletions director.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (

"github.com/snivilised/traverse/internal/feat/filter"
"github.com/snivilised/traverse/internal/feat/hiber"
"github.com/snivilised/traverse/internal/feat/nanny"
"github.com/snivilised/traverse/internal/feat/resume"
"github.com/snivilised/traverse/internal/feat/sampling"
"github.com/snivilised/traverse/internal/kernel"
Expand All @@ -13,12 +14,12 @@ import (
"github.com/snivilised/traverse/pref"
)

type ifActive func(o *pref.Options, mediator types.Mediator) types.Plugin
type ifActive func(o *pref.Options, using *pref.Using, mediator types.Mediator) types.Plugin

// features interrogates options and invokes requests on behalf of the user
// to activate features according to option selections. other plugins will
// be initialised after primary plugins
func features(o *pref.Options, mediator types.Mediator,
func features(o *pref.Options, using *pref.Using, mediator types.Mediator,
kc types.KernelController,
others ...types.Plugin,
) (plugins []types.Plugin, err error) {
Expand All @@ -29,7 +30,7 @@ func features(o *pref.Options, mediator types.Mediator,
// order. How can we decouple ourselves from this
// requirement? => the cure is worse than the disease
//
hiber.IfActive, filter.IfActive, sampling.IfActive,
hiber.IfActive, nanny.IfActive, filter.IfActive, sampling.IfActive,
}
)

Expand All @@ -44,7 +45,7 @@ func features(o *pref.Options, mediator types.Mediator,
},
lo.Reduce(all,
func(acc []types.Plugin, query ifActive, _ int) []types.Plugin {
if plugin := query(o, mediator); plugin != nil {
if plugin := query(o, using, mediator); plugin != nil {
acc = append(acc, plugin)
}
return acc
Expand Down Expand Up @@ -73,6 +74,7 @@ func Prime(using *pref.Using, settings ...pref.Option) *Builders {
// by a panic.
//
return &Builders{
using: using,
readerFS: pref.CreateReadDirFS(func() fs.ReadDirFS {
if using.GetReadDirFS != nil {
return using.GetReadDirFS()
Expand Down Expand Up @@ -129,6 +131,7 @@ func Resume(was *Was, settings ...pref.Option) *Builders {
// path was.
//
return &Builders{
using: &was.Using,
readerFS: pref.CreateReadDirFS(func() fs.ReadDirFS {
if was.Using.GetReadDirFS != nil {
return was.Using.GetReadDirFS()
Expand Down
15 changes: 8 additions & 7 deletions enums/metric-en-auto.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion enums/metric-en.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ type Metric uint
// if new metrics are added, ensure that navigationMetricsFactory.new is kept
// in sync.
const (
_ Metric = iota

// MetricNoFilesInvoked represents the no of files invoked for during traversal
//
MetricNoFilesInvoked Metric = iota // metric-no-of-files
MetricNoFilesInvoked // metric-no-of-files

// MetricNoFilesFilteredOut represents the no of files filtered out
//
Expand Down
5 changes: 3 additions & 2 deletions enums/role-en-auto.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions enums/role-en.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ const (
RoleClientFilter // client-filter-role
RoleHibernate // hibernate-role
RoleSampler // sampler-role
RoleNanny // nanny-role
)
5 changes: 4 additions & 1 deletion internal-traverse-defs.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,24 +21,27 @@ func (fn optionals) build(ext extent) (*pref.Options, error) {
// pluginsBuilder
type pluginsBuilder interface {
build(o *pref.Options,
using *pref.Using,
mediator types.Mediator,
kc types.KernelController,
others ...types.Plugin,
) ([]types.Plugin, error)
}

type activated func(*pref.Options,
*pref.Using,
types.Mediator,
types.KernelController,
...types.Plugin,
) ([]types.Plugin, error)

func (fn activated) build(o *pref.Options,
using *pref.Using,
mediator types.Mediator,
kc types.KernelController,
others ...types.Plugin,
) ([]types.Plugin, error) {
return fn(o, mediator, kc, others...)
return fn(o, using, mediator, kc, others...)
}

type fsBuilder interface {
Expand Down
20 changes: 20 additions & 0 deletions internal/feat/filter/errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package filter

import (
"github.com/pkg/errors"
)

// ❌ InvalidNotificationMuteRequested error: this scenario should
// never happen, if it does then its an internal issue to be
// addressed here in the filter plugin.

// IsNoSubordinateHybridSchemesDefinedError uses errors.Is to check
// if the err's error tree contains the core error:
// InvalidNotificationMuteRequestedError
func IsNoSubordinateHybridSchemesDefinedError(err error) bool {
return errors.Is(err, ErrNoSubordinateHybridSchemesDefined)
}

var ErrNoSubordinateHybridSchemesDefined = errors.New(
"invalid filter scheme, both primary and child not set",
)
22 changes: 12 additions & 10 deletions internal/feat/filter/filter-plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,13 @@ import (
"github.com/snivilised/traverse/enums"
"github.com/snivilised/traverse/internal/kernel"
"github.com/snivilised/traverse/internal/measure"
"github.com/snivilised/traverse/internal/override"
"github.com/snivilised/traverse/internal/types"
"github.com/snivilised/traverse/pref"
)

func IfActive(o *pref.Options, mediator types.Mediator) types.Plugin {
func IfActive(o *pref.Options, _ *pref.Using, mediator types.Mediator) types.Plugin {
if o.Filter.IsFilteringActive() {
return &Plugin{
return &plugin{
BasePlugin: kernel.BasePlugin{
O: o,
Mediator: mediator,
Expand All @@ -28,28 +27,31 @@ func IfActive(o *pref.Options, mediator types.Mediator) types.Plugin {
return nil
}

// Plugin manages all filtering aspects of navigation
type Plugin struct {
// plugin manages all filtering aspects of navigation
type plugin struct {
kernel.BasePlugin
sink pref.FilteringSink
crate measure.Crate
scheme scheme
}

func (p *Plugin) Name() string {
func (p *plugin) Name() string {
return "filtering"
}

func (p *Plugin) Register(kc types.KernelController) error {
p.Kontroller = kc
func (p *plugin) Register(kc types.KernelController) error {
if err := p.BasePlugin.Register(kc); err != nil {
return err
}

return p.scheme.create()
}

func (p *Plugin) Next(node *core.Node, inspection override.Inspection) (bool, error) {
func (p *plugin) Next(node *core.Node, inspection types.Inspection) (bool, error) {
return p.scheme.next(node, inspection)
}

func (p *Plugin) Init(pi *types.PluginInit) error {
func (p *plugin) Init(pi *types.PluginInit) error {
p.crate.Mums = p.Mediator.Supervisor().Many(
enums.MetricNoFoldersFilteredOut,
enums.MetricNoFilesFilteredOut,
Expand Down
49 changes: 49 additions & 0 deletions internal/feat/filter/scheme-custom.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package filter

import (
"github.com/snivilised/traverse/core"
"github.com/snivilised/traverse/enums"
"github.com/snivilised/traverse/internal/measure"
"github.com/snivilised/traverse/internal/third/lo"
"github.com/snivilised/traverse/internal/types"
"github.com/snivilised/traverse/pref"
)

type customScheme struct {
common
filter core.TraverseFilter
}

func (s *customScheme) create() error {
s.filter = s.o.Filter.Custom

if s.o.Filter.Sink != nil {
s.o.Filter.Sink(pref.FilterReply{
Node: s.filter,
})
}

return s.filter.Validate()
}

func (s *customScheme) next(node *core.Node,
_ types.Inspection,
) (bool, error) {
return matchNext(s.filter, node, s.crate)
}

func matchNext(filter core.TraverseFilter,
node *core.Node, crate *measure.Crate,
) (bool, error) {
matched := filter.IsMatch(node)

if !matched {
filteredOutMetric := lo.Ternary(node.IsFolder(),
enums.MetricNoFoldersFilteredOut,
enums.MetricNoFilesFilteredOut,
)
crate.Mums[filteredOutMetric].Tick()
}

return matched, nil
}
Loading

0 comments on commit 59f3844

Please sign in to comment.