Documentation
¶
Overview ¶
Package bstates implements a parser for Idefix event blobs.
Overview ¶
Each binary blob is an event queue which is composed of one or more state encoded using the same schema. States represent a system state in a point of time. Schemas are json files which define States binary formats. Here there is an example schema which defines a 102bit State composed of 4 fields:
{
"version": "2.0",
"encoderPipeline": "t:z",
"decodedFields":
{
{
"name": "MESSAGE"
"from": "MESSAGE_BUFFER",
"decoder": "BufferToString"
},
{
"name": "STATE",
"decoder": "IntMap",
"params": {
"from": "STATE_CODE",
"mapId": "STATE_MAP"
}
},
"decoderIntMaps":
{
"STATE_MAP": {
"0" : "IDLE",
"1" : "STOPPED",
"2" : "RUNNING"
}
},
"fields": [
{
"name": "3BITS_INT",
"type": "int",
"size": 3
},
{
"name": "STATE_CODE",
"type": "uint",
"size": 2
},
{
"name": "BOOL",
"type": "bool"
},
{
"name": "MESSAGE_BUFFER",
"type": "buffer",
"size": 96
}
]
}
Decoders allow for complex codification of data saving space. In the above example there is a decodedField MESAGE which allows us to read MESSAGE_BUFFER as a string. Decoders work by executing the "decoder" parameter on the "from" field. Currently there are three types of Decoder.
States are the objects which hold data. They are composed by a frame.Frame which holds the data and a StateSchema that specifies a codification. StateField and DecodedStateField both can be retrieved using the State.Get function.
All objects in this library, can be serialized as JSON or as MSI map[string]interface{}
Index ¶
- Constants
- Variables
- func GetDeltaMsiState(from *State, to *State) (map[string]any, error)
- func GetDeltaMsiStates(states []*State) ([]map[string]any, error)
- func GzipDec(b *buffer.Buffer) (*buffer.Buffer, error)
- func GzipEnc(b *buffer.Buffer) (*buffer.Buffer, error)
- func StatesToMsiStates(states []*State) (out []map[string]any, err error)
- func ZstdDec(b *buffer.Buffer) (*buffer.Buffer, error)
- func ZstdEnc(b *buffer.Buffer) (*buffer.Buffer, error)
- type BufferToStringDecoder
- type DecodedStateField
- type Decoder
- type FieldDecoderType
- type FlagsDecoder
- type IntMapDecoder
- type NumberToUnixTsMsDecoder
- type State
- func (f *State) Get(fieldName string) (value any, err error)
- func (e *State) GetCopy() *State
- func (e *State) GetSchema() *StateSchema
- func (f *State) Same(fieldName string, newValue any) (same bool, err error)
- func (f *State) Set(fieldName string, newValue any) error
- func (e *State) ToMsi() (map[string]interface{}, error)
- type StateField
- func (e *StateField) FromMsi(rawField map[string]any) (err error)
- func (e *StateField) GetRange() (min, max any, err error)
- func (e *StateField) MarshalJSON() (res []byte, err error)
- func (e *StateField) ToMsi() (msiData map[string]any, err error)
- func (e *StateField) UnmarshalJSON(b []byte) error
- func (e *StateField) Validate(value any) error
- type StateFieldType
- type StateQueue
- func (s *StateQueue) Clear()
- func (s *StateQueue) Decode(data []byte) (err error)
- func (s *StateQueue) Encode() (dataOut []byte, err error)
- func (s *StateQueue) FromMsi(msg map[string]interface{}) error
- func (s *StateQueue) GetBitSize() int
- func (s *StateQueue) GetByteSize() int
- func (s *StateQueue) GetNumStates() (num int)
- func (s *StateQueue) GetStateAt(index int) (*State, error)
- func (s *StateQueue) GetStates() ([]*State, error)
- func (s *StateQueue) Pop() (*State, error)
- func (s *StateQueue) Push(state *State) error
- func (s *StateQueue) PushAll(states []*State) error
- func (s *StateQueue) StateBufferIter(iterFunc func(stateBuffer []byte) (end bool))
- func (s *StateQueue) StateBufferIterFrom(from int, iterFunc func(stateBuffer []byte) (end bool))
- func (s *StateQueue) ToMsi() (msg map[string]interface{}, err error)
- type StateSchema
- func (s *StateSchema) CreateState() (*State, error)
- func (s *StateSchema) GetBitSize() int
- func (s *StateSchema) GetByteSize() int
- func (s *StateSchema) GetDecodedFields() []*DecodedStateField
- func (s *StateSchema) GetDecoderPipeline() []string
- func (s *StateSchema) GetEncoderPipeline() []string
- func (s *StateSchema) GetFields() []*StateField
- func (s *StateSchema) GetHashString() string
- func (s *StateSchema) GetMeta() map[string]any
- func (s *StateSchema) GetSHA256() [32]byte
- func (s *StateSchema) MarshalJSON() (res []byte, err error)
- func (s *StateSchema) ToMsi() map[string]any
- func (s *StateSchema) UnmarshalJSON(b []byte) error
- type StateSchemaParams
Constants ¶
const ( MOD_GZIP = "z" // run gzip compression MOD_ZSTD = "zstd" // run zstd compression MOD_BITTRANS = "t" // transpose the event matrix, for better compression )
encoderPipeline options
const ( SCHEMA_VERSION_1_0 = "1.0" SCHEMA_VERSION_2_0 = "2.0" )
Variables ¶
var ErrInvalidType = errors.New("invalid type")
ErrInvalidType represents a type validation error
var ErrOutOfRange = errors.New("out of range")
ErrOutOfRange represents a range validation error
Functions ¶
func GetDeltaMsiState ¶
GetDeltaMsiState compares two State objects and returns a map containing the values that have changed between them. Includes aliases for backward compatibility, similar to State.ToMsi().
func GetDeltaMsiStates ¶
GetDeltaMsiStates returns a slice of maps that represent the changes between each successive pair of State objects in the provided slice.
The first State is converted to its MSI representation, and subsequent States are compared to the last seen State using GetDeltaMsiState().
func GzipDec ¶
GzipDec decompresses the provided buffer which is expected to be in Gzip format and returns a new buffer containing the decompressed data.
func GzipEnc ¶
GzipEnc compresses the provided buffer using Gzip compression and returns a new buffer containing the compressed data.
func StatesToMsiStates ¶
StatesToMsiStates converts a slice of State pointers into a slice of maps containing the corresponding MSI states.
Each State is transformed into a map using the ToMsi() method.
Types ¶
type BufferToStringDecoder ¶
type BufferToStringDecoder struct {
From string // "from" parameter: name of the encoded field as defined in StateSchema.Fields
}
BufferToString implements a Decoder which returns a string from a buffer. This means that the original buffer will be returned as a [string] object stopping at the first null character.
func NewBufferToStringDecoder ¶
func NewBufferToStringDecoder(params map[string]any) (d *BufferToStringDecoder, err error)
func (*BufferToStringDecoder) Decode ¶
func (d *BufferToStringDecoder) Decode(s *State) (any, error)
func (*BufferToStringDecoder) Encode ¶ added in v0.8.0
func (d *BufferToStringDecoder) Encode(s *State, v any) error
func (*BufferToStringDecoder) GetParams ¶
func (d *BufferToStringDecoder) GetParams() map[string]any
func (*BufferToStringDecoder) Name ¶
func (d *BufferToStringDecoder) Name() FieldDecoderType
type DecodedStateField ¶
type DecodedStateField struct {
Name string // Name used to access this field
Aliases []string // Alternative names for accessing this decoded field (used for backward compatibility with deprecated field names)
Decoder Decoder // Decoder used to access the original [StateField].
}
DecodedStateField represents a view of a StateField decoded by a Decoder.
The Name is used to access the decoded view. The raw encoded StateField is provided on the parameter "from" to the Decoder.
func (*DecodedStateField) FromMsi ¶
func (df *DecodedStateField) FromMsi(m map[string]any) error
FromMsi populates the DecodedStateField from a map representation.
func (*DecodedStateField) MarshalJSON ¶
func (df *DecodedStateField) MarshalJSON() (res []byte, err error)
MarshalJSON serializes the DecodedStateField to JSON format.
func (*DecodedStateField) ToMsi ¶
func (df *DecodedStateField) ToMsi() (map[string]any, error)
ToMsi converts the DecodedStateField to a map representation.
func (*DecodedStateField) UnmarshalJSON ¶
func (df *DecodedStateField) UnmarshalJSON(b []byte) error
UnmarshalJSON deserializes the JSON data into a DecodedStateField.
type Decoder ¶
type Decoder interface {
Name() FieldDecoderType // Decoder type
Decode(s *State) (any, error) // function called to get the decoded value from the state
Encode(s *State, v any) error // function called to encode the value into the state
GetParams() map[string]any // returns a MSI
}
Decoder is an interface that defines how to decode or transform state information. They provide a "virtual" field.
While decoders usually use the "from" parameter to specify the name of a StateField to decode, it's not mandatory.
Decoders can:
- Use multiple input fields (similar to having multiple "from" parameters), allowing for operations with several operands.
- Access the entire state, enabling more complex decoding logic that isn't limited to specific fields.
- Define constant fields that do not depend on any state field, although this might have limited practical use.
func NewDecoder ¶
NewDecoder creates a new Decoder instance based on the provided decoder type and parameters.
dtype: Should be one of FieldDecoderType.
type FieldDecoderType ¶
type FieldDecoderType string
FieldDecoderType defines the type for different field decoder names.
const ( BufferToStringDecoderType FieldDecoderType = "BufferToString" NumberToUnixTsMsDecoderType FieldDecoderType = "NumberToUnixTsMs" IntMapDecoderType FieldDecoderType = "IntMap" FlagsDecoderType FieldDecoderType = "Flags" )
Implemented decoders are: BufferToStringDecoder, NumberToUnixTsMsDecoder, IntMapDecoder and FlagsDecoder.
type FlagsDecoder ¶ added in v0.9.0
type FlagsDecoder struct {
From string // "from" parameter: name of the encoded field as defined in StateSchema.Fields
Flags map[string]uint8 // "flags" parameter: map of flag name to bit position
}
func NewFlagsDecoder ¶ added in v0.9.0
func NewFlagsDecoder(params map[string]any) (d *FlagsDecoder, err error)
func (*FlagsDecoder) GetParams ¶ added in v0.9.0
func (d *FlagsDecoder) GetParams() map[string]any
func (*FlagsDecoder) Name ¶ added in v0.9.0
func (d *FlagsDecoder) Name() FieldDecoderType
type IntMapDecoder ¶
type IntMapDecoder struct {
From string // "from" parameter: name of the encoded field as defined in StateSchema.Fields
MapId string // "mapId" parameter: name of the map as defined in the StateSchema.DecoderIntMaps
}
IntMapDecoder implements a Decoder which decodes an integer value into a string based on a mapping defined in the State object.
func NewIntMapDecoder ¶
func NewIntMapDecoder(params map[string]any) (d *IntMapDecoder, err error)
func (*IntMapDecoder) Encode ¶ added in v0.8.0
func (d *IntMapDecoder) Encode(s *State, v any) error
func (*IntMapDecoder) GetParams ¶
func (d *IntMapDecoder) GetParams() map[string]any
func (*IntMapDecoder) Name ¶
func (d *IntMapDecoder) Name() FieldDecoderType
type NumberToUnixTsMsDecoder ¶
type NumberToUnixTsMsDecoder struct {
From string // "from" parameter: name of the encoded field as defined in StateSchema.Fields
Year uint // "year"
Factor float64 // "factor"
}
NumberToUnixTsMsDecoder implements a Decoder which decodes a numeric value using the following formula:
decodedValue = UnixMillis(year) + valueToDecode*factor
func NewNumberToUnixTsMsDecoder ¶
func NewNumberToUnixTsMsDecoder(params map[string]any) (d *NumberToUnixTsMsDecoder, err error)
func (*NumberToUnixTsMsDecoder) Decode ¶
func (d *NumberToUnixTsMsDecoder) Decode(s *State) (any, error)
func (*NumberToUnixTsMsDecoder) Encode ¶ added in v0.8.0
func (d *NumberToUnixTsMsDecoder) Encode(s *State, v any) error
func (*NumberToUnixTsMsDecoder) GetParams ¶
func (d *NumberToUnixTsMsDecoder) GetParams() map[string]any
func (*NumberToUnixTsMsDecoder) Name ¶
func (d *NumberToUnixTsMsDecoder) Name() FieldDecoderType
type State ¶
type State struct {
*frame.Frame // Underlying binary data of the state
// contains filtered or unexported fields
}
State represents a system state in a point of time. It holds data in the frame.Frame as defined by the provided StateSchema.
func CreateState ¶
func CreateState(schema *StateSchema) (*State, error)
CreateState initializes a new empty State based on the provided StateSchema.
func (*State) Get ¶
Get retrieves the value of the specified field from the State.
It first tries to retrieve the raw value from the frame.Frame and, if unsuccessful, attempts to decode the field using the schema's decoding logic.
func (*State) GetCopy ¶
GetCopy returns a deep copy of the current State. This includes a copy of the underlying [Frame] and retains the original StateSchema.
func (*State) GetSchema ¶
func (e *State) GetSchema() *StateSchema
GetSchema returns the StateSchema associated with the current State.
func (*State) Set ¶ added in v0.8.0
Set updates the value of the specified field in the State.
It first checks if the field is a decoded field and, if so, uses the schema's encoding logic. Otherwise, it validates the value and updates the field using default encoding logic for the type of the field.
For T_BUFFER fields with range errors (oversized data), the value is still written to allow truncation during encode/decode, but an error is returned to notify about potential data loss.
type StateField ¶
type StateField struct {
Name string // Name of the field, used for retrieval
Aliases []string // Alternative names for accessing this field (used for backward compatibility with deprecated field names)
Size int // size in bits
DefaultValue any
Type StateFieldType
Decimals uint // Number of decimal places for fixed-point fields, ignored for non-fixed types
// contains filtered or unexported fields
}
StateField defines a field in a StateSchema.
func (*StateField) FromMsi ¶
func (e *StateField) FromMsi(rawField map[string]any) (err error)
FromMsi initializes a StateField from a map[string]interface{}.
func (*StateField) GetRange ¶ added in v0.9.0
func (e *StateField) GetRange() (min, max any, err error)
GetRange returns the valid range for this field type and size.
func (*StateField) MarshalJSON ¶
func (e *StateField) MarshalJSON() (res []byte, err error)
MarshalJSON serializes the StateField to JSON format.
func (*StateField) ToMsi ¶
func (e *StateField) ToMsi() (msiData map[string]any, err error)
ToMsi converts a StateField to a map[string]interface{} for further processing.
func (*StateField) UnmarshalJSON ¶
func (e *StateField) UnmarshalJSON(b []byte) error
UnmarshalJSON deserializes the JSON data into a StateField.
func (*StateField) Validate ¶ added in v0.9.2
func (e *StateField) Validate(value any) error
Validate validates that a value has the correct type and is within the valid range for this field type and size.
type StateFieldType ¶
type StateFieldType int
StateFieldType represents the type of a field in the StateSchema.
const ( T_INT StateFieldType = iota T_UINT T_FLOAT32 T_FLOAT64 T_BOOL T_BUFFER T_FIXED T_UFIXED )
type StateQueue ¶
type StateQueue struct {
StateSchema *StateSchema // Schemas used to encode each of the states in the queue.
// contains filtered or unexported fields
}
StateQueue is a queue of states stored in a buffer one after another.
All elements in the same queue must use the StateSchema of the queue.
func CreateStateQueue ¶
func CreateStateQueue(schema *StateSchema) *StateQueue
Creates a StateQueue of [States] encoded with the StateSchema provided.
func (*StateQueue) Clear ¶
func (s *StateQueue) Clear()
Clear deletes all elements in the queue by creating a new internal buffer.
func (*StateQueue) Decode ¶
func (s *StateQueue) Decode(data []byte) (err error)
Decode [Clear] the queue and then runs the decoderPipeline of the schema populating the queue.
func (*StateQueue) Encode ¶
func (s *StateQueue) Encode() (dataOut []byte, err error)
Encode runs the encoderPipeline of the schema and outputs a binary blob with the queue compressed.
func (*StateQueue) FromMsi ¶
func (s *StateQueue) FromMsi(msg map[string]interface{}) error
FromMsi populates the StateQueue from a map representation.
func (*StateQueue) GetBitSize ¶
func (s *StateQueue) GetBitSize() int
GetBitSize return the number of bits used by the internal buffer.
func (*StateQueue) GetByteSize ¶
func (s *StateQueue) GetByteSize() int
GetByteSize return the number of bytes used by the internal buffer.
func (*StateQueue) GetNumStates ¶
func (s *StateQueue) GetNumStates() (num int)
GetNumStates returns the number of states in the queue.
func (*StateQueue) GetStateAt ¶
func (s *StateQueue) GetStateAt(index int) (*State, error)
GetStateAt returns the state at an index.
func (*StateQueue) GetStates ¶
func (s *StateQueue) GetStates() ([]*State, error)
GetStates returns a slice with all the events on the queue.
func (*StateQueue) Pop ¶
func (s *StateQueue) Pop() (*State, error)
Pop the first State in the queue removing it from the queue.
func (*StateQueue) Push ¶
func (s *StateQueue) Push(state *State) error
Push the State object provided into the end of the queue.
func (*StateQueue) PushAll ¶
func (s *StateQueue) PushAll(states []*State) error
PushAll pushes all the State objects provided at the end of the queue.
func (*StateQueue) StateBufferIter ¶
func (s *StateQueue) StateBufferIter(iterFunc func(stateBuffer []byte) (end bool))
StateBufferIter iterates trough the queue executing the callback for each State. If the callback returns true the iterations ends early.
func (*StateQueue) StateBufferIterFrom ¶
func (s *StateQueue) StateBufferIterFrom(from int, iterFunc func(stateBuffer []byte) (end bool))
StateBufferIterFrom iterates the queue as [StateBufferIter] but starting from the state index provided.
func (*StateQueue) ToMsi ¶
func (s *StateQueue) ToMsi() (msg map[string]interface{}, err error)
ToMsi converts the StateQueue into a map[string]interface{} representation.
type StateSchema ¶
type StateSchema struct {
// contains filtered or unexported fields
}
StateSchema represents the schema used for encoding/decoding states. Fields within an schema can be plain or encoded.
func CreateStateSchema ¶
func CreateStateSchema(params *StateSchemaParams) (e *StateSchema, err error)
CreateStateSchema initializes a StateSchema from the provided parameters.
func (*StateSchema) CreateState ¶
func (s *StateSchema) CreateState() (*State, error)
CreateState initializes a new State object using the StateSchema.
func (*StateSchema) GetBitSize ¶
func (s *StateSchema) GetBitSize() int
GetBitSize returns the total bit size of the fields in the StateSchema.
func (*StateSchema) GetByteSize ¶
func (s *StateSchema) GetByteSize() int
GetByteSize returns the total byte size of the fields in the StateSchema.
func (*StateSchema) GetDecodedFields ¶
func (s *StateSchema) GetDecodedFields() []*DecodedStateField
GetDecodedFields returns a copy of the list of DecodedStateField in the schema.
func (*StateSchema) GetDecoderPipeline ¶
func (s *StateSchema) GetDecoderPipeline() []string
GetDecoderPipeline returns the decoder pipeline steps as a list of strings.
func (*StateSchema) GetEncoderPipeline ¶
func (s *StateSchema) GetEncoderPipeline() []string
GetEncoderPipeline returns the encoder pipeline steps as a list of strings.
func (*StateSchema) GetFields ¶
func (s *StateSchema) GetFields() []*StateField
GetFields returns a copy of the list of StateField in the schema.
func (*StateSchema) GetHashString ¶
func (s *StateSchema) GetHashString() string
GetHashString returns the SHA256 hash of the JSON representation of the StateSchema as a base64 encoded string.
func (*StateSchema) GetMeta ¶
func (s *StateSchema) GetMeta() map[string]any
GetMeta returns the meta data associated with the StateSchema.
func (*StateSchema) GetSHA256 ¶
func (s *StateSchema) GetSHA256() [32]byte
GetSHA256 generates and returns the SHA256 hash of the JSON representation of the StateSchema.
func (*StateSchema) MarshalJSON ¶
func (s *StateSchema) MarshalJSON() (res []byte, err error)
MarshalJSON serializes the StateSchema into JSON format.
func (*StateSchema) ToMsi ¶
func (s *StateSchema) ToMsi() map[string]any
ToMsi converts the StateSchema into a map[string]interface{} for serialization.
func (*StateSchema) UnmarshalJSON ¶
func (s *StateSchema) UnmarshalJSON(b []byte) error
UnmarshalJSON deserializes the JSON into a StateSchema.
type StateSchemaParams ¶
type StateSchemaParams struct {
Meta map[string]any // Meta data to associate with the schema
Fields []StateField // List of fields to define in the schema
DecodedFields []DecodedStateField // List of decoded views to define in the schema
EncoderPipeline string // Encoder pipeline to use to package and unpackage a [StateQueue]
DecoderIntMaps map[string]map[int64]any // Integer mappings used for decoding encoded integer fields
}
StateSchemaParams represents the parameters for constructing a StateSchema.