-
Notifications
You must be signed in to change notification settings - Fork 45
/
snapshots.go
96 lines (82 loc) · 2.21 KB
/
snapshots.go
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
96
package orchestrator
import (
"context"
"fmt"
"sort"
"strings"
"github.com/streamingfast/derr"
"github.com/streamingfast/dstore"
"github.com/streamingfast/substreams/block"
"github.com/streamingfast/substreams/state"
)
type Snapshots struct {
Completes block.Ranges // Shortest completes first, largest last.
Partials block.Ranges // First partials first, last last
}
func (s *Snapshots) Sort() {
sort.Slice(s.Completes, func(i, j int) bool {
return s.Completes[i].ExclusiveEndBlock < s.Completes[j].ExclusiveEndBlock
})
sort.Slice(s.Partials, func(i, j int) bool {
return s.Partials[i].StartBlock < s.Partials[j].StartBlock
})
}
func (s *Snapshots) String() string {
return fmt.Sprintf("completes=%s, partials=%s", s.Completes, s.Partials)
}
func (s *Snapshots) LastCompletedBlock() uint64 {
if len(s.Completes) == 0 {
return 0
}
return s.Completes[len(s.Completes)-1].ExclusiveEndBlock
}
func (s *Snapshots) LastCompleteSnapshotBefore(blockNum uint64) *block.Range {
for i := len(s.Completes); i > 0; i-- {
comp := s.Completes[i-1]
if comp.ExclusiveEndBlock > blockNum {
continue
}
return comp
}
return nil
}
func (s *Snapshots) ContainsPartial(r *block.Range) bool {
for _, file := range s.Partials {
if file.StartBlock == r.StartBlock && file.ExclusiveEndBlock == r.ExclusiveEndBlock {
return true
}
}
return false
}
type Snapshot struct {
block.Range
Path string
}
func listSnapshots(ctx context.Context, store dstore.Store) (*Snapshots, error) {
out := &Snapshots{}
err := derr.RetryContext(ctx, 3, func(ctx context.Context) error {
if err := store.Walk(ctx, "", func(filename string) (err error) {
if filename == "___store-metadata.json" || strings.HasPrefix(filename, "__") {
return nil
}
fileInfo, ok := state.ParseFileName(filename)
if !ok {
return nil
}
if fileInfo.Partial {
out.Partials = append(out.Partials, block.NewRange(fileInfo.StartBlock, fileInfo.EndBlock))
} else {
out.Completes = append(out.Completes, block.NewRange(fileInfo.StartBlock, fileInfo.EndBlock))
}
return nil
}); err != nil {
return fmt.Errorf("walking snapshots: %w", err)
}
return nil
})
if err != nil {
return nil, err
}
out.Sort()
return out, nil
}