Skip to content

Commit b4b39f5

Browse files
committed
tlogclient: batch 50 tile fetches in parallel
1 parent bbc300b commit b4b39f5

File tree

5 files changed

+134
-41
lines changed

5 files changed

+134
-41
lines changed

cmd/tlogclient-warmup/main.go

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package main
2+
3+
import (
4+
"io"
5+
"os"
6+
"path/filepath"
7+
8+
"filippo.io/litetlog/tlogclient"
9+
"github.com/cheggaaa/pb/v3"
10+
"golang.org/x/mod/sumdb/tlog"
11+
)
12+
13+
func main() {
14+
latest, err := io.ReadAll(os.Stdin)
15+
if err != nil {
16+
panic(err)
17+
}
18+
tree, err := tlog.ParseTree(latest)
19+
if err != nil {
20+
panic(err)
21+
}
22+
23+
cacheDir, err := os.UserCacheDir()
24+
if err != nil {
25+
panic(err)
26+
}
27+
cacheDir = filepath.Join(cacheDir, "tlogclient-warmup")
28+
29+
fetcher := tlogclient.NewSumDBFetcher("https://sum.golang.org/")
30+
dirCache := tlogclient.NewPermanentCache(fetcher, cacheDir)
31+
client := tlogclient.NewClient(dirCache)
32+
33+
bar := pb.Start64(tree.N)
34+
for range client.EntriesSumDB(tree, 0) {
35+
bar.Increment()
36+
}
37+
bar.Finish()
38+
if err := client.Error(); err != nil {
39+
panic(err)
40+
}
41+
}

go.mod

+8-1
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,22 @@ go 1.23.0
44

55
require (
66
crawshaw.io/sqlite v0.3.3-0.20220618202545-d1964889ea3c
7+
github.com/cheggaaa/pb/v3 v3.1.5
78
github.com/rogpeppe/go-internal v1.11.0
89
golang.org/x/crypto v0.15.0
910
golang.org/x/mod v0.14.0
1011
golang.org/x/net v0.18.0
12+
golang.org/x/sync v0.5.0
1113
sigsum.org/sigsum-go v0.6.1
1214
)
1315

1416
require (
15-
golang.org/x/sync v0.5.0
17+
github.com/VividCortex/ewma v1.2.0 // indirect
18+
github.com/fatih/color v1.15.0 // indirect
19+
github.com/mattn/go-colorable v0.1.13 // indirect
20+
github.com/mattn/go-isatty v0.0.19 // indirect
21+
github.com/mattn/go-runewidth v0.0.15 // indirect
22+
github.com/rivo/uniseg v0.2.0 // indirect
1623
golang.org/x/sys v0.14.0 // indirect
1724
golang.org/x/text v0.14.0 // indirect
1825
golang.org/x/tools v0.15.0 // indirect

go.sum

+17
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,21 @@ crawshaw.io/iox v0.0.0-20181124134642-c51c3df30797 h1:yDf7ARQc637HoxDho7xjqdvO5Z
22
crawshaw.io/iox v0.0.0-20181124134642-c51c3df30797/go.mod h1:sXBiorCo8c46JlQV3oXPKINnZ8mcqnye1EkVkqsectk=
33
crawshaw.io/sqlite v0.3.3-0.20220618202545-d1964889ea3c h1:wvzox0eLO6CKQAMcOqz7oH3UFqMpMmK7kwmwV+22HIs=
44
crawshaw.io/sqlite v0.3.3-0.20220618202545-d1964889ea3c/go.mod h1:igAO5JulrQ1DbdZdtVq48mnZUBAPOeFzer7VhDWNtW4=
5+
github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow=
6+
github.com/VividCortex/ewma v1.2.0/go.mod h1:nz4BbCtbLyFDeC9SUHbtcT5644juEuWfUAUnGx7j5l4=
7+
github.com/cheggaaa/pb/v3 v3.1.5 h1:QuuUzeM2WsAqG2gMqtzaWithDJv0i+i6UlnwSCI4QLk=
8+
github.com/cheggaaa/pb/v3 v3.1.5/go.mod h1:CrxkeghYTXi1lQBEI7jSn+3svI3cuc19haAj6jM60XI=
9+
github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
10+
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
11+
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
12+
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
13+
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
14+
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
15+
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
16+
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
17+
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
18+
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
19+
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
520
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
621
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
722
golang.org/x/crypto v0.15.0 h1:frVn1TEaCEaZcn3Tmd7Y2b5KKPaZ+I32Q2OA3kYp5TA=
@@ -12,6 +27,8 @@ golang.org/x/net v0.18.0 h1:mIYleuAkSbHh0tCv7RvjL3F6ZVbLjq4+R7zbOn3Kokg=
1227
golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ=
1328
golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE=
1429
golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
30+
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
31+
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
1532
golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
1633
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
1734
golang.org/x/term v0.14.0 h1:LGK9IlZ8T9jvdy6cTdfKUCltatMFOehAQo9SRC46UQ8=

tlogclient/tlogclient.go

+53-38
Original file line numberDiff line numberDiff line change
@@ -40,64 +40,76 @@ func (c *Client) Error() error {
4040

4141
func (c *Client) EntriesSumDB(tree tlog.Tree, start int64) iter.Seq2[int64, []byte] {
4242
return func(yield func(int64, []byte) bool) {
43+
if c.err != nil {
44+
return
45+
}
4346
for {
44-
t := tlog.TileForIndex(tileHeight, tlog.StoredHashIndex(0, start))
45-
tileStart := t.N * tileWidth
46-
tileEnd := tileStart + tileWidth
47-
if tileEnd > tree.N {
47+
base := start / tileWidth * tileWidth
48+
tiles := make([]tlog.Tile, 0, 16)
49+
for i := 0; i < 50; i++ {
50+
tileStart := base + int64(i)*tileWidth
51+
tileEnd := tileStart + tileWidth
52+
if tileEnd > tree.N {
53+
break
54+
}
55+
tiles = append(tiles, tlog.Tile{H: tileHeight, L: -1,
56+
N: tileStart / tileWidth, W: tileWidth})
57+
}
58+
if len(tiles) == 0 {
4859
// TODO: document and support partial tile optimization.
4960
return
5061
}
51-
52-
t.L = -1
53-
t.W = tileWidth
54-
tt, err := c.tr.ReadTiles([]tlog.Tile{t})
62+
tdata, err := c.tr.ReadTiles(tiles)
5563
if err != nil {
5664
c.err = err
5765
return
5866
}
59-
data := tt[0]
6067

6168
// TODO: hash data tile directly against level 8 hash.
62-
indexes := make([]int64, tileWidth)
69+
indexes := make([]int64, tileWidth*len(tiles))
6370
for i := range indexes {
64-
indexes[i] = tlog.StoredHashIndex(0, tileStart+int64(i))
71+
indexes[i] = tlog.StoredHashIndex(0, base+int64(i))
6572
}
6673
hashes, err := tlog.TileHashReader(tree, c.tr).ReadHashes(indexes)
6774
if err != nil {
6875
c.err = err
6976
return
7077
}
7178

72-
for i := tileStart; i < tileEnd; i++ {
73-
if len(data) == 0 {
74-
c.err = fmt.Errorf("unexpected end of tile data")
75-
return
76-
}
77-
78-
var entry []byte
79-
if idx := bytes.Index(data, []byte("\n\n")); idx >= 0 {
80-
// Add back one of the newlines.
81-
entry, data = data[:idx+1], data[idx+2:]
82-
} else {
83-
entry, data = data, nil
84-
}
85-
86-
if tlog.RecordHash(entry) != hashes[i-tileStart] {
87-
c.err = fmt.Errorf("hash mismatch for entry %d", i)
88-
return
89-
}
90-
91-
if i < start {
92-
continue
93-
}
94-
if !yield(i, entry) {
95-
return
79+
for ti, t := range tiles {
80+
tileStart := t.N * tileWidth
81+
tileEnd := tileStart + tileWidth
82+
data := tdata[ti]
83+
for i := tileStart; i < tileEnd; i++ {
84+
if len(data) == 0 {
85+
c.err = fmt.Errorf("unexpected end of tile data")
86+
return
87+
}
88+
89+
var entry []byte
90+
if idx := bytes.Index(data, []byte("\n\n")); idx >= 0 {
91+
// Add back one of the newlines.
92+
entry, data = data[:idx+1], data[idx+2:]
93+
} else {
94+
entry, data = data, nil
95+
}
96+
97+
if tlog.RecordHash(entry) != hashes[i-base] {
98+
c.err = fmt.Errorf("hash mismatch for entry %d", i)
99+
return
100+
}
101+
102+
if i < start {
103+
continue
104+
}
105+
if !yield(i, entry) {
106+
return
107+
}
96108
}
109+
start = tileEnd
97110
}
98111

99-
c.tr.SaveTiles([]tlog.Tile{t}, tt)
100-
start = tileEnd
112+
c.tr.SaveTiles(tiles, tdata)
101113
}
102114
}
103115
}
@@ -285,7 +297,7 @@ func (c *PermanentCache) ReadTiles(tiles []tlog.Tile) (data [][]byte, err error)
285297
} else if err != nil {
286298
return nil, err
287299
} else {
288-
c.log.Info("loaded tile from cache", "path", path, "size", len(d))
300+
c.log.Info("loaded tile from cache", "path", t.Path(), "size", len(d))
289301
data[i] = d
290302
}
291303
}
@@ -311,6 +323,9 @@ func (c *PermanentCache) SaveTiles(tiles []tlog.Tile, data [][]byte) {
311323
continue // skip partial tiles
312324
}
313325
path := filepath.Join(c.dir, t.Path())
326+
if _, err := os.Stat(path); err == nil {
327+
continue
328+
}
314329
if err := os.MkdirAll(filepath.Dir(path), 0700); err != nil {
315330
c.log.Error("failed to create directory", "path", path, "error", err)
316331
return

tlogclient/tlogclient_test.go

+15-2
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ InZSsRXdXKTMF3W5wEcd9T6ro5zyOiRMGQsEPSTco6U=
2626
t.Run(fmt.Sprintf("Start%d", start), func(t *testing.T) {
2727
t.Run("NoCache", func(t *testing.T) {
2828
fetcher := tlogclient.NewSumDBFetcher("https://sum.golang.org/")
29-
fetcher.SetLimit(1)
3029
fetcher.SetLogger(slog.New(handler))
3130
client := tlogclient.NewClient(fetcher)
3231

@@ -47,7 +46,6 @@ InZSsRXdXKTMF3W5wEcd9T6ro5zyOiRMGQsEPSTco6U=
4746

4847
t.Run("DirCache", func(t *testing.T) {
4948
fetcher := tlogclient.NewSumDBFetcher("https://sum.golang.org/")
50-
fetcher.SetLimit(1)
5149
fetcher.SetLogger(slog.New(handler))
5250
dirCache := tlogclient.NewPermanentCache(fetcher, t.TempDir())
5351
dirCache.SetLogger(slog.New(handler))
@@ -66,6 +64,21 @@ InZSsRXdXKTMF3W5wEcd9T6ro5zyOiRMGQsEPSTco6U=
6664
if !ok {
6765
t.Error("did not reach 1000 entries")
6866
}
67+
68+
client = tlogclient.NewClient(dirCache)
69+
ok = false
70+
for i := range client.EntriesSumDB(tree, start) {
71+
if i >= start+1000 {
72+
ok = true
73+
break
74+
}
75+
}
76+
if err := client.Error(); err != nil {
77+
t.Fatal(err)
78+
}
79+
if !ok {
80+
t.Error("did not reach 1000 entries")
81+
}
6982
})
7083
})
7184
}

0 commit comments

Comments
 (0)