1
0
mirror of https://github.com/osmarks/mycorrhiza.git synced 2024-12-04 18:19:54 +00:00

Move hyphae.Iteration to a separate package

This commit is contained in:
Timur Ismagilov 2022-02-20 12:40:16 +03:00
parent b41a2f10d4
commit dea370c71d
2 changed files with 21 additions and 18 deletions

View File

@ -1,26 +1,26 @@
package hyphae
// Package iteration provides a handy API for making multiple checks on all hyphae in one go.
package iteration
import (
"github.com/bouncepaw/mycorrhiza/hyphae"
"sync"
)
// Iteration represents an iteration over all hyphae in the storage. You may use it instead of directly iterating using hyphae.YieldExistingHyphae when you want to do n checks at once instead of iterating n times.
// Iteration represents an iteration over all existing hyphae in the storage. Iteration is done on all existing hyphae. The order of hyphae is not specified. For all hyphae, checks are made.
type Iteration struct {
sync.Mutex
iterator func() chan ExistingHypha
checks []func(h Hypha) CheckResult
checks []func(h hyphae.Hypha) CheckResult
}
// NewIteration constructs an iteration without checks.
func NewIteration() *Iteration {
return &Iteration{
iterator: YieldExistingHyphae,
checks: make([]func(h Hypha) CheckResult, 0),
checks: make([]func(h hyphae.Hypha) CheckResult, 0),
}
}
// AddCheck adds the check to the iteration. It is concurrent-safe.
func (i7n *Iteration) AddCheck(check func(h Hypha) CheckResult) {
// AddCheck adds the check to the iteration. It is concurrent-safe. Checks are meant to have side-effects.
func (i7n *Iteration) AddCheck(check func(h hyphae.Hypha) CheckResult) {
i7n.Lock()
i7n.checks = append(i7n.checks, check)
i7n.Unlock()
@ -32,8 +32,10 @@ func (i7n *Iteration) removeCheck(i int) {
}
// Ignite does the iteration by walking over all hyphae yielded by the iterator used and calling all checks on the hypha. Ignited iterations are not concurrent-safe.
//
// After ignition, you should not use the same Iteration again.
func (i7n *Iteration) Ignite() {
for h := range i7n.iterator() {
for h := range hyphae.YieldExistingHyphae() {
for i, check := range i7n.checks {
if res := check(h); res == CheckForgetMe {
i7n.removeCheck(i)

View File

@ -2,6 +2,7 @@ package tree
import (
"fmt"
"github.com/bouncepaw/mycorrhiza/hyphae/iteration"
"path"
"sort"
"strings"
@ -18,11 +19,11 @@ func findSiblings(hyphaName string) []*sibling {
}
var (
siblingsMap = make(map[string]bool)
siblingCheck = func(h hyphae.Hypha) hyphae.CheckResult {
siblingCheck = func(h hyphae.Hypha) iteration.CheckResult {
switch {
case h.CanonicalName() == hyphaName, // NonEmptyHypha is no sibling of itself
h.CanonicalName() == parentHyphaName: // Parent hypha is no sibling of its child
return hyphae.CheckContinue
return iteration.CheckContinue
}
if (parentHyphaName != "" && strings.HasPrefix(h.CanonicalName(), parentHyphaName+"/")) ||
(parentHyphaName == "") {
@ -39,10 +40,10 @@ func findSiblings(hyphaName string) []*sibling {
siblingsMap[h.CanonicalName()] = true
}
}
return hyphae.CheckContinue
return iteration.CheckContinue
}
i7n = hyphae.NewIteration()
i7n = iteration.NewIteration()
)
siblingsMap[hyphaName] = true
@ -63,19 +64,19 @@ func findSiblings(hyphaName string) []*sibling {
func countSubhyphae(siblings []*sibling) {
var (
subhyphaCheck = func(h hyphae.Hypha) hyphae.CheckResult {
subhyphaCheck = func(h hyphae.Hypha) iteration.CheckResult {
for _, s := range siblings {
if path.Dir(h.CanonicalName()) == s.name {
s.directSubhyphaeCount++
return hyphae.CheckContinue
return iteration.CheckContinue
} else if strings.HasPrefix(h.CanonicalName(), s.name+"/") {
s.indirectSubhyphaeCount++
return hyphae.CheckContinue
return iteration.CheckContinue
}
}
return hyphae.CheckContinue
return iteration.CheckContinue
}
i7n = hyphae.NewIteration()
i7n = iteration.NewIteration()
)
i7n.AddCheck(subhyphaCheck)
i7n.Ignite()