1
2
3
4
5
6
7
8
9 package trace
10
11 import (
12 "bytes"
13 "encoding/binary"
14 "fmt"
15 "io"
16
17 "golang.org/x/exp/trace/internal/event"
18 "golang.org/x/exp/trace/internal/event/go122"
19 )
20
21
22 type timestamp uint64
23
24
25
26 type batch struct {
27 m ThreadID
28 time timestamp
29 data []byte
30 }
31
32 func (b *batch) isStringsBatch() bool {
33 return len(b.data) > 0 && event.Type(b.data[0]) == go122.EvStrings
34 }
35
36 func (b *batch) isStacksBatch() bool {
37 return len(b.data) > 0 && event.Type(b.data[0]) == go122.EvStacks
38 }
39
40 func (b *batch) isCPUSamplesBatch() bool {
41 return len(b.data) > 0 && event.Type(b.data[0]) == go122.EvCPUSamples
42 }
43
44 func (b *batch) isFreqBatch() bool {
45 return len(b.data) > 0 && event.Type(b.data[0]) == go122.EvFrequency
46 }
47
48
49 func readBatch(r interface {
50 io.Reader
51 io.ByteReader
52 }) (batch, uint64, error) {
53
54 b, err := r.ReadByte()
55 if err != nil {
56 return batch{}, 0, err
57 }
58 if typ := event.Type(b); typ != go122.EvEventBatch {
59 return batch{}, 0, fmt.Errorf("expected batch event (%s), got %s", go122.EventString(go122.EvEventBatch), go122.EventString(typ))
60 }
61
62
63
64 gen, err := binary.ReadUvarint(r)
65 if err != nil {
66 return batch{}, gen, fmt.Errorf("error reading batch gen: %w", err)
67 }
68 m, err := binary.ReadUvarint(r)
69 if err != nil {
70 return batch{}, gen, fmt.Errorf("error reading batch M ID: %w", err)
71 }
72 ts, err := binary.ReadUvarint(r)
73 if err != nil {
74 return batch{}, gen, fmt.Errorf("error reading batch timestamp: %w", err)
75 }
76
77
78 size, err := binary.ReadUvarint(r)
79 if err != nil {
80 return batch{}, gen, fmt.Errorf("error reading batch size: %w", err)
81 }
82 if size > go122.MaxBatchSize {
83 return batch{}, gen, fmt.Errorf("invalid batch size %d, maximum is %d", size, go122.MaxBatchSize)
84 }
85
86
87 var data bytes.Buffer
88 data.Grow(int(size))
89 n, err := io.CopyN(&data, r, int64(size))
90 if n != int64(size) {
91 return batch{}, gen, fmt.Errorf("failed to read full batch: read %d but wanted %d", n, size)
92 }
93 if err != nil {
94 return batch{}, gen, fmt.Errorf("copying batch data: %w", err)
95 }
96
97
98 return batch{
99 m: ThreadID(m),
100 time: timestamp(ts),
101 data: data.Bytes(),
102 }, gen, nil
103 }
104
View as plain text