diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-16 19:25:22 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-16 19:25:22 +0000 |
commit | f6ad4dcef54c5ce997a4bad5a6d86de229015700 (patch) | |
tree | 7cfa4e31ace5c2bd95c72b154d15af494b2bcbef /src/internal/trace/v2/batch.go | |
parent | Initial commit. (diff) | |
download | golang-1.22-f6ad4dcef54c5ce997a4bad5a6d86de229015700.tar.xz golang-1.22-f6ad4dcef54c5ce997a4bad5a6d86de229015700.zip |
Adding upstream version 1.22.1.upstream/1.22.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/internal/trace/v2/batch.go')
-rw-r--r-- | src/internal/trace/v2/batch.go | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/src/internal/trace/v2/batch.go b/src/internal/trace/v2/batch.go new file mode 100644 index 0000000..899eb0f --- /dev/null +++ b/src/internal/trace/v2/batch.go @@ -0,0 +1,97 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package trace + +import ( + "bufio" + "bytes" + "encoding/binary" + "fmt" + "io" + + "internal/trace/v2/event" + "internal/trace/v2/event/go122" +) + +// timestamp is an unprocessed timestamp. +type timestamp uint64 + +// batch represents a batch of trace events. +// It is unparsed except for its header. +type batch struct { + m ThreadID + time timestamp + data []byte +} + +func (b *batch) isStringsBatch() bool { + return len(b.data) > 0 && event.Type(b.data[0]) == go122.EvStrings +} + +func (b *batch) isStacksBatch() bool { + return len(b.data) > 0 && event.Type(b.data[0]) == go122.EvStacks +} + +func (b *batch) isCPUSamplesBatch() bool { + return len(b.data) > 0 && event.Type(b.data[0]) == go122.EvCPUSamples +} + +func (b *batch) isFreqBatch() bool { + return len(b.data) > 0 && event.Type(b.data[0]) == go122.EvFrequency +} + +// readBatch reads the next full batch from r. +func readBatch(r *bufio.Reader) (batch, uint64, error) { + // Read batch header byte. + b, err := r.ReadByte() + if err != nil { + return batch{}, 0, err + } + if typ := event.Type(b); typ != go122.EvEventBatch { + return batch{}, 0, fmt.Errorf("expected batch event (%s), got %s", go122.EventString(go122.EvEventBatch), go122.EventString(typ)) + } + + // Read the batch header: gen (generation), thread (M) ID, base timestamp + // for the batch. + gen, err := binary.ReadUvarint(r) + if err != nil { + return batch{}, gen, fmt.Errorf("error reading batch gen: %w", err) + } + m, err := binary.ReadUvarint(r) + if err != nil { + return batch{}, gen, fmt.Errorf("error reading batch M ID: %w", err) + } + ts, err := binary.ReadUvarint(r) + if err != nil { + return batch{}, gen, fmt.Errorf("error reading batch timestamp: %w", err) + } + + // Read in the size of the batch to follow. + size, err := binary.ReadUvarint(r) + if err != nil { + return batch{}, gen, fmt.Errorf("error reading batch size: %w", err) + } + if size > go122.MaxBatchSize { + return batch{}, gen, fmt.Errorf("invalid batch size %d, maximum is %d", size, go122.MaxBatchSize) + } + + // Copy out the batch for later processing. + var data bytes.Buffer + data.Grow(int(size)) + n, err := io.CopyN(&data, r, int64(size)) + if n != int64(size) { + return batch{}, gen, fmt.Errorf("failed to read full batch: read %d but wanted %d", n, size) + } + if err != nil { + return batch{}, gen, fmt.Errorf("copying batch data: %w", err) + } + + // Return the batch. + return batch{ + m: ThreadID(m), + time: timestamp(ts), + data: data.Bytes(), + }, gen, nil +} |