You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
boundary/internal/bsr/chunk.go

117 lines
2.9 KiB

// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package bsr
import (
"context"
"fmt"
)
// sizes
const (
lengthSize = 4
protocolSize = 4
chunkTypeSize = 4
directionSize = 1
crcDataSize = protocolSize + chunkTypeSize + directionSize + timestampSize
chunkBaseSize = lengthSize + crcDataSize
crcSize = 4
// MaxChunkDataLength sets an upper bound on BSR chunk lengths
// Default to 64MB, as this is the limit for protobufs, which back our chunks
// TODO: Should this be configurable as an option?
MaxChunkDataLength = 64 * 100 * 1000
)
// Chunk Types
const (
ChunkHeader ChunkType = "HEAD"
ChunkEnd ChunkType = "DONE"
)
// ChunkType identifies the type of a chunk.
type ChunkType string
// ValidChunkType checks ifa given ChunkType is valid.
func ValidChunkType(c ChunkType) bool {
return len(c) <= chunkTypeSize
}
// Chunk is a section of a bsr data file.
type Chunk interface {
// GetLength returns the length of the chunk data.
GetLength() uint32
// GetProtocol returns the protocol of the recorded data.
GetProtocol() Protocol
// GetType returns the chunk type.
GetType() ChunkType
// GetDirection returns the direction of the data in the chunk.
GetDirection() Direction
// GetTimestamp returns the timestamp of a Chunk.
GetTimestamp() *Timestamp
// MarshalData serializes the data portion of a chunk.
MarshalData(context.Context) ([]byte, error)
}
// BaseChunk contains the common fields of all chunk types.
type BaseChunk struct {
Protocol Protocol
Direction Direction
Timestamp *Timestamp
Type ChunkType
length uint32
}
// NewBaseChunk creates a BaseChunk.
func NewBaseChunk(ctx context.Context, p Protocol, d Direction, t *Timestamp, typ ChunkType) (*BaseChunk, error) {
const op = "bsr.NewBaseChunk"
if !ValidProtocol(p) {
return nil, fmt.Errorf("%s: protocol name cannot be greater than 4 characters: %w", op, ErrInvalidParameter)
}
if !ValidDirection(d) {
return nil, fmt.Errorf("%s: invalid direction: %w", op, ErrInvalidParameter)
}
if t == nil {
return nil, fmt.Errorf("%s: timestamp must not be nil: %w", op, ErrInvalidParameter)
}
if !ValidChunkType(typ) {
return nil, fmt.Errorf("%s: chunk type cannot be greater than 4 characters: %w", op, ErrInvalidParameter)
}
return &BaseChunk{
Protocol: p,
Direction: d,
Timestamp: t,
Type: typ,
}, nil
}
// GetLength returns the length of the chunk data.
func (b *BaseChunk) GetLength() uint32 {
return b.length
}
// GetProtocol returns the protocol of the recorded data.
func (b *BaseChunk) GetProtocol() Protocol {
return b.Protocol
}
// GetType returns the chunk type.
func (b *BaseChunk) GetType() ChunkType {
return b.Type
}
// GetDirection returns the direction of the data in the chunk.
func (b *BaseChunk) GetDirection() Direction {
return b.Direction
}
// GetTimestamp returns the timestamp of a Chunk.
func (b *BaseChunk) GetTimestamp() *Timestamp {
return b.Timestamp
}