-
Notifications
You must be signed in to change notification settings - Fork 13
Expand file tree
/
Copy pathwalk.go
More file actions
95 lines (85 loc) · 2.35 KB
/
Copy pathwalk.go
File metadata and controls
95 lines (85 loc) · 2.35 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
package docbank
import (
"context"
"errors"
"io"
"sync"
"go.kenn.io/docbank/internal/store"
)
const (
// DefaultWalkPageSize is the finite page size used when WalkOptions.PageSize is zero.
DefaultWalkPageSize = 500
// MaxWalkPageSize is the largest page one Walker may materialize.
MaxWalkPageSize = store.MaxWalkPageSize
// MaxWalkDepth is the greatest absolute tree depth one Walker traverses.
MaxWalkDepth = store.MaxWalkDepth
// MaxWalkPathBytes is the largest canonical path one Walker materializes.
MaxWalkPathBytes = store.MaxWalkPathBytes
)
// WalkOptions controls one stable snapshot traversal.
type WalkOptions struct {
PageSize int
IncludeTrashed bool
}
// WalkEntry is one node and its canonical path in the traversal snapshot.
type WalkEntry struct {
Path string
Node Node
}
// Walker returns bounded pages from one stable tree snapshot until closed.
type Walker struct {
inner *store.Walker
release func()
closeOnce sync.Once
closeErr error
}
// Walk begins a stable snapshot traversal rooted at rootPath.
func (v *Vault) Walk(ctx context.Context, rootPath string, opts WalkOptions) (*Walker, error) {
if err := v.begin(); err != nil {
return nil, err
}
pageSize := opts.PageSize
if pageSize == 0 {
pageSize = DefaultWalkPageSize
}
if pageSize < 1 || pageSize > MaxWalkPageSize {
v.lifecycle.RUnlock()
return nil, errors.New("docbank walk page size must be between 1 and 5000")
}
walker, err := v.metadata.BeginWalk(ctx, rootPath, pageSize, opts.IncludeTrashed)
if err != nil {
v.lifecycle.RUnlock()
return nil, err
}
return &Walker{inner: walker, release: v.lifecycle.RUnlock}, nil
}
// Next returns the next bounded snapshot page. io.EOF follows the last page.
func (w *Walker) Next(ctx context.Context) ([]WalkEntry, error) {
if w == nil || w.inner == nil {
return nil, io.EOF
}
entries, err := w.inner.Next(ctx)
if err != nil {
return nil, err
}
page := make([]WalkEntry, 0, len(entries))
for _, entry := range entries {
page = append(page, WalkEntry{Path: entry.Path, Node: fromStoreNode(entry.Node)})
}
return page, nil
}
// Close releases the snapshot and vault lifecycle lease. It is idempotent.
func (w *Walker) Close() error {
if w == nil {
return nil
}
w.closeOnce.Do(func() {
if w.inner != nil {
w.closeErr = w.inner.Close()
}
if w.release != nil {
w.release()
}
})
return w.closeErr
}