1
0
mirror of https://github.com/osmarks/mycorrhiza.git synced 2024-12-12 05:20:26 +00:00
mycorrhiza/hyphae/iteration.go

54 lines
1.5 KiB
Go
Raw Normal View History

package hyphae
import (
"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.
type Iteration struct {
sync.Mutex
iterator func() chan *Hypha
checks []func(h *Hypha) CheckResult
}
// NewIteration constructs an iteration without checks.
func NewIteration() *Iteration {
return &Iteration{
iterator: YieldExistingHyphae,
checks: make([]func(h *Hypha) CheckResult, 0),
}
}
// AddCheck adds the check to the iteration. It is concurrent-safe.
func (i7n *Iteration) AddCheck(check func(h *Hypha) CheckResult) {
i7n.Lock()
i7n.checks = append(i7n.checks, check)
i7n.Unlock()
}
func (i7n *Iteration) removeCheck(i int) {
i7n.checks[i] = i7n.checks[len(i7n.checks)-1]
i7n.checks = i7n.checks[:len(i7n.checks)-1]
}
// 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.
func (i7n *Iteration) Ignite() {
for h := range i7n.iterator() {
for i, check := range i7n.checks {
if res := check(h); res == CheckForgetMe {
i7n.removeCheck(i)
}
}
}
}
// CheckResult is a result of an iteration check.
type CheckResult int
const (
// CheckContinue is returned when the check wants to be used next time too.
CheckContinue CheckResult = iota
// CheckForgetMe is returned when the check wants to be forgotten and not used anymore.
CheckForgetMe
)