added lazy ref closure

This commit is contained in:
Andy Arthur
2021-07-31 11:15:31 -07:00
parent d9b5509e3d
commit 61d09f56a9
3 changed files with 31 additions and 20 deletions
+1 -1
View File
@@ -152,7 +152,7 @@ func FindClosureCommonAncestor(ctx context.Context, cl RefClosure, rf types.Ref,
curr = q.PopRefsOfHeight(q.MaxHeight())
for _, r := range curr {
ok, err = cl.Contains(r)
ok, err = cl.Contains(ctx, r)
if err != nil {
return types.Ref{}, false, err
}
+3 -4
View File
@@ -243,17 +243,15 @@ func toRefList(vrw types.ValueReadWriter, commits ...types.Struct) (types.List,
}
func commonAncWithSetClosure(ctx context.Context, c1, c2 types.Ref, vr1, vr2 types.ValueReader) (a types.Ref, ok bool, err error) {
var closure RefClosure
closure, err = NewSetRefClosure(ctx, vr1, c1)
closure, err := NewSetRefClosure(ctx, vr1, c1)
if err != nil {
return types.Ref{}, false, err
}
return FindClosureCommonAncestor(ctx, closure, c2, vr2)
}
func commonAncWithLazyClosure(ctx context.Context, c1, c2 types.Ref, vr1, vr2 types.ValueReader) (a types.Ref, ok bool, err error) {
closure := NewLazyRefClousure(ctx, c1, vr1)
closure := NewLazyRefClousure(c1, vr1)
return FindClosureCommonAncestor(ctx, closure, c2, vr2)
}
@@ -266,6 +264,7 @@ func assertCommonAncestor(t *testing.T, expected, a, b types.Struct, ldb, rdb Da
methods := map[string]caFinder{
"FindCommonAncestor": FindCommonAncestor,
"SetClosure": commonAncWithSetClosure,
"LazyClosure": commonAncWithLazyClosure,
}
for name, method := range methods {
+27 -15
View File
@@ -23,7 +23,7 @@ import (
// todo comment doc
type RefClosure interface {
Contains(ref types.Ref) (bool, error)
Contains(ctx context.Context, ref types.Ref) (bool, error)
}
// todo comment doc
@@ -42,7 +42,7 @@ type setRefClosure struct {
var _ RefClosure = setRefClosure{}
func (s setRefClosure) Contains(ref types.Ref) (ok bool, err error) {
func (s setRefClosure) Contains(ctx context.Context, ref types.Ref) (ok bool, err error) {
ok = s.HashSet.Has(ref.TargetHash())
return
}
@@ -67,31 +67,43 @@ func transitiveClosure(ctx context.Context, vr types.ValueReader, ref types.Ref)
return s, nil
}
func NewLazyRefClousure(ctx context.Context, ref types.Ref, vr types.ValueReader) lazyRefClosure {
func NewLazyRefClousure(ref types.Ref, vr types.ValueReader) lazyRefClosure {
return lazyRefClosure{
partial: hash.NewHashSet(ref.TargetHash()),
bottom: RefByHeightHeap{ref},
seen: hash.NewHashSet(ref.TargetHash()),
heap: &RefByHeightHeap{ref},
vr: vr,
}
}
type lazyRefClosure struct {
partial hash.HashSet
bottom []types.Ref
depth uint64
seen hash.HashSet
heap *RefByHeightHeap
vr types.ValueReader
}
var _ RefClosure = lazyRefClosure{}
func (l lazyRefClosure) Contains(ref types.Ref) (ok bool, err error) {
if ref.Height() < l.depth {
err = traverseToDepth(ref.Height(), l.bottom, l.partial)
}
func (l lazyRefClosure) Contains(ctx context.Context, ref types.Ref) (ok bool, err error) {
err = l.traverseToDepth(ctx, ref.Height())
if err != nil {
return false, err
}
return l.partial.Has(ref.TargetHash()), nil
return l.seen.Has(ref.TargetHash()), nil
}
func traverseToDepth(depth uint64, roots []types.Ref, visited hash.HashSet) error {
panic("todo")
func (l lazyRefClosure) traverseToDepth(ctx context.Context, depth uint64) (err error) {
var curr types.RefSlice
for !l.heap.Empty() && depth <= l.heap.MaxHeight() {
curr = l.heap.PopRefsOfHeight(l.heap.MaxHeight())
for _, r := range curr {
l.seen.Insert(r.TargetHash())
}
err = parentsToQueue(ctx, curr, l.heap, l.vr)
if err != nil {
return err
}
}
return nil
}