golang.org/x/exp@v0.0.0-20240506185415-9bf2ced13842/trace/batch.go (about) 1 // Copyright 2023 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Code generated by "gen.bash" from internal/trace/v2; DO NOT EDIT. 6 7 //go:build go1.21 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 // timestamp is an unprocessed timestamp. 22 type timestamp uint64 23 24 // batch represents a batch of trace events. 25 // It is unparsed except for its header. 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 // readBatch reads the next full batch from r. 49 func readBatch(r interface { 50 io.Reader 51 io.ByteReader 52 }) (batch, uint64, error) { 53 // Read batch header byte. 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 // Read the batch header: gen (generation), thread (M) ID, base timestamp 63 // for the batch. 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 // Read in the size of the batch to follow. 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 // Copy out the batch for later processing. 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 // Return the batch. 98 return batch{ 99 m: ThreadID(m), 100 time: timestamp(ts), 101 data: data.Bytes(), 102 }, gen, nil 103 }