mctx: implement BreadthFirstVisit
This commit is contained in:
parent
8e2cffd65b
commit
5bd0790f6e
18
mctx/ctx.go
18
mctx/ctx.go
@ -152,6 +152,24 @@ func ChildOf(ctx Context, name string) Context {
|
|||||||
return childCtx
|
return childCtx
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BreadthFirstVisit visits this Context and all of its children, and their
|
||||||
|
// children, in a breadth-first order. If the callback returns false then the
|
||||||
|
// function returns without visiting any more Contexts.
|
||||||
|
//
|
||||||
|
// The exact order of visitation is non-deterministic.
|
||||||
|
func BreadthFirstVisit(ctx Context, callback func(Context) bool) {
|
||||||
|
queue := []Context{ctx}
|
||||||
|
for len(queue) > 0 {
|
||||||
|
if !callback(queue[0]) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for _, child := range Children(queue[0]) {
|
||||||
|
queue = append(queue, child)
|
||||||
|
}
|
||||||
|
queue = queue[1:]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// code related to mutable values
|
// code related to mutable values
|
||||||
|
|
||||||
|
@ -54,6 +54,44 @@ func TestInheritance(t *T) {
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestBreadFirstVisit(t *T) {
|
||||||
|
ctx := New()
|
||||||
|
ctx1 := ChildOf(ctx, "1")
|
||||||
|
ctx1a := ChildOf(ctx1, "a")
|
||||||
|
ctx1b := ChildOf(ctx1, "b")
|
||||||
|
ctx2 := ChildOf(ctx, "2")
|
||||||
|
|
||||||
|
{
|
||||||
|
got := make([]Context, 0, 5)
|
||||||
|
BreadthFirstVisit(ctx, func(ctx Context) bool {
|
||||||
|
got = append(got, ctx)
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
// since children are stored in a map the exact order is non-deterministic
|
||||||
|
massert.Fatal(t, massert.Any(
|
||||||
|
massert.Equal([]Context{ctx, ctx1, ctx2, ctx1a, ctx1b}, got),
|
||||||
|
massert.Equal([]Context{ctx, ctx1, ctx2, ctx1b, ctx1a}, got),
|
||||||
|
massert.Equal([]Context{ctx, ctx2, ctx1, ctx1a, ctx1b}, got),
|
||||||
|
massert.Equal([]Context{ctx, ctx2, ctx1, ctx1b, ctx1a}, got),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
got := make([]Context, 0, 3)
|
||||||
|
BreadthFirstVisit(ctx, func(ctx Context) bool {
|
||||||
|
if len(Path(ctx)) > 1 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
got = append(got, ctx)
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
massert.Fatal(t, massert.Any(
|
||||||
|
massert.Equal([]Context{ctx, ctx1, ctx2}, got),
|
||||||
|
massert.Equal([]Context{ctx, ctx2, ctx1}, got),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestMutableValues(t *T) {
|
func TestMutableValues(t *T) {
|
||||||
fn := func(v interface{}) interface{} {
|
fn := func(v interface{}) interface{} {
|
||||||
if v == nil {
|
if v == nil {
|
||||||
|
Loading…
Reference in New Issue
Block a user