Skip to content

Commit

Permalink
Merge pull request #438 from PlakarKorp/op/visit-iterator
Browse files Browse the repository at this point in the history
turn VisitDFS into an iterator
  • Loading branch information
poolpOrg authored Feb 7, 2025
2 parents cc9cbc4 + a1667eb commit 3f7c3c2
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 36 deletions.
10 changes: 7 additions & 3 deletions btree/btree_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -309,14 +309,18 @@ func TestVisitDFS(t *testing.T) {
}

keySaw := []rune{}
tree.VisitDFS(func(ptr int, node *Node[rune, int, int]) error {
it := tree.IterDFS()
for it.Next() {
_, node := it.Current()
if node.isleaf() {
for i := range node.Keys {
keySaw = append(keySaw, node.Keys[i])
}
}
return nil
})
}
if err := it.Err(); err != nil {
t.Fatalf("unexpected error: %s", err)
}

if slices.Compare(alphabet, keySaw) != 0 {
t.Errorf("some keys weren't seen; got %v but want %v",
Expand Down
64 changes: 43 additions & 21 deletions btree/iter.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,8 @@ func (b *BTree[K, P, V]) ScanFrom(key K) (Iterator[K, V], error) {
}

type step[K, P, V any] struct {
ptr P
idx int
ptr P
idx int
}

type backwardIter[K, P, V any] struct {
Expand All @@ -139,8 +139,8 @@ func (bit *backwardIter[K, P, V]) dive(ptr P) error {
}

bit.steps = append(bit.steps, step[K, P, V]{
ptr: ptr,
idx: len(node.Keys),
ptr: ptr,
idx: len(node.Keys),
})

if node.isleaf() {
Expand Down Expand Up @@ -212,27 +212,49 @@ func (b *BTree[K, P, V]) ScanAllReverse() (Iterator[K, V], error) {
return bit, nil
}

func (b *BTree[K, P, V]) VisitDFS(cb func(P, *Node[K, P, V]) error) error {
stack := []step[K, P, V]{{b.Root, -1}}
for len(stack) > 0 {
l := &stack[len(stack)-1]
type dfsIter[K, P, V any] struct {
b *BTree[K, P, V]
stack []step[K, P, V]
ptr P
current *Node[K, P, V]
err error
}

node, err := b.store.Get(l.ptr)
if err != nil {
return err
func (dit *dfsIter[K, P, V]) Next() bool {
for dit.err == nil && len(dit.stack) > 0 {
s := &dit.stack[len(dit.stack)-1]

dit.ptr = s.ptr
dit.current, dit.err = dit.b.store.Get(dit.ptr)
if dit.err != nil {
return false
}
if l.idx == -1 {
if err := cb(l.ptr, node); err != nil {
return err
}
if s.idx == -1 {
s.idx++
return true
}
l.idx++

if l.idx == len(node.Pointers) {
stack = stack[:len(stack)-1]
if s.idx == len(dit.current.Pointers) {
dit.stack = dit.stack[:len(dit.stack)-1]
continue
}
stack = append(stack, step[K, P, V]{node.Pointers[l.idx], -1})

s.idx++
dit.stack = append(dit.stack, step[K, P, V]{dit.current.Pointers[s.idx-1], -1})
}
return false
}

func (dit *dfsIter[K, P, V]) Current() (P, *Node[K, P, V]) {
return dit.ptr, dit.current
}

func (dit *dfsIter[K, P, V]) Err() error {
return dit.err
}

func (b *BTree[K, P, V]) IterDFS() Iterator[P, *Node[K, P, V]] {
return &dfsIter[K, P, V]{
b: b,
stack: []step[K, P, V]{{b.Root, -1}},
}
return nil
}
10 changes: 7 additions & 3 deletions btree/verify.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,14 +159,18 @@ func (b *BTree[K, P, V]) verifyNode(cur, parent *Node[K, P, V], ptrIdx int, stat
}

func (b *BTree[K, P, V]) Dot(w io.Writer, showNextPtrs bool) error {
return b.VisitDFS(func(ptr P, n *Node[K, P, V]) error {
iter := b.IterDFS()
for iter.Next() {
ptr, n := iter.Current()

fmt.Fprintf(w, "%v [label=%q]\n", ptr, fmt.Sprintf("%v %v", ptr, n.Keys))
for _, cptr := range n.Pointers {
fmt.Fprintf(w, "%v -> %v\n", ptr, cptr)
}
if showNextPtrs && n.Next != nil {
fmt.Fprintf(w, "%v -> %v\n", ptr, *n.Next)
}
return nil
})
}

return iter.Err()
}
11 changes: 7 additions & 4 deletions cmd/plakar/subcommands/sync/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import (
"strings"

"github.com/PlakarKorp/plakar/appcontext"
"github.com/PlakarKorp/plakar/btree"
"github.com/PlakarKorp/plakar/cmd/plakar/subcommands"
"github.com/PlakarKorp/plakar/cmd/plakar/utils"
"github.com/PlakarKorp/plakar/encryption"
Expand Down Expand Up @@ -278,16 +277,20 @@ func synchronize(srcRepository *repository.Repository, dstRepository *repository
}
}

fs.VisitNodes(func(csum objects.Checksum, node *btree.Node[string, objects.Checksum, objects.Checksum]) error {
fsiter := fs.IterNodes()
for fsiter.Next() {
csum, node := fsiter.Current()
if !dstRepository.BlobExists(resources.RT_VFS_BTREE, csum) {
bytes, err := msgpack.Marshal(node)
if err != nil {
return err
}
dstSnapshot.PutBlob(resources.RT_VFS_BTREE, csum, bytes)
}
return nil
})
}
if err := fsiter.Err(); err != nil {
return err
}

return dstSnapshot.Commit()
}
6 changes: 3 additions & 3 deletions snapshot/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,11 @@ func (snapshot *Snapshot) Errors(beneath string) (iter.Seq2[*ErrorItem, error],
}, nil
}

func (snapshot *Snapshot) VisitErrorNodes(cb func(objects.Checksum, *btree.Node[string, objects.Checksum, objects.Checksum]) error) error {
func (snapshot *Snapshot) IterErrorNodes() (btree.Iterator[objects.Checksum, *btree.Node[string, objects.Checksum, objects.Checksum]], error) {
tree, err := snapshot.erroridx()
if err != nil {
return err
return nil, err
}

return tree.VisitDFS(cb)
return tree.IterDFS(), nil
}
4 changes: 2 additions & 2 deletions snapshot/vfs/vfs.go
Original file line number Diff line number Diff line change
Expand Up @@ -254,8 +254,8 @@ func (fsc *Filesystem) Children(path string) (iter.Seq2[string, error], error) {
}, nil
}

func (fsc *Filesystem) VisitNodes(cb func(objects.Checksum, *btree.Node[string, objects.Checksum, objects.Checksum]) error) error {
return fsc.tree.VisitDFS(cb)
func (fsc *Filesystem) IterNodes() btree.Iterator[objects.Checksum, *btree.Node[string, objects.Checksum, objects.Checksum]] {
return fsc.tree.IterDFS()
}

func (fsc *Filesystem) FileChecksums() (iter.Seq2[objects.Checksum, error], error) {
Expand Down

0 comments on commit 3f7c3c2

Please sign in to comment.