mirror of
https://github.com/hanzoai/metrics.git
synced 2026-10-30 20:03:39 +00:00
Also rename MetricMetadata* constants to MetricType* constants.
This makes the code a bit more readable.
This is a follow-up for the commit 1670b10d44
Updates https://github.com/VictoriaMetrics/VictoriaMetrics/issues/2974
Updates https://github.com/VictoriaMetrics/VictoriaMetrics/pull/9306
134 lines
3.6 KiB
Go
134 lines
3.6 KiB
Go
package metricsmetadata
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/bytesutil"
|
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/encoding"
|
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/prompb"
|
|
)
|
|
|
|
// Row represents time series metadata record
|
|
type Row struct {
|
|
lastWriteTime uint64
|
|
heapIdx int
|
|
|
|
MetricFamilyName []byte
|
|
Help []byte
|
|
Unit []byte
|
|
|
|
AccountID uint32
|
|
ProjectID uint32
|
|
|
|
Type prompb.MetricType
|
|
}
|
|
|
|
// MarshalTo serializes Row into provided buffer and returns result
|
|
func (mr *Row) MarshalTo(dst []byte) []byte {
|
|
dstLen := len(dst)
|
|
// tenant information (accountID and projectID)
|
|
dstSize := dstLen + 8
|
|
// 2 bytes per string + 4 bytes for type
|
|
dstSize += 10
|
|
dstSize += len(mr.MetricFamilyName) + len(mr.Help) + len(mr.Unit)
|
|
|
|
dst = bytesutil.ResizeWithCopyMayOverallocate(dst, dstSize)[:dstLen]
|
|
|
|
dst = encoding.MarshalUint32(dst, mr.AccountID)
|
|
dst = encoding.MarshalUint32(dst, mr.ProjectID)
|
|
dst = encoding.MarshalUint32(dst, uint32(mr.Type))
|
|
dst = marshalBytesFast(dst, mr.MetricFamilyName)
|
|
dst = marshalBytesFast(dst, mr.Help)
|
|
dst = marshalBytesFast(dst, mr.Unit)
|
|
return dst
|
|
}
|
|
|
|
// Unmarshal parses Row from provided buffer and returns tail buffer
|
|
func (mr *Row) Unmarshal(data []byte) ([]byte, error) {
|
|
// accountID + projectID + type + metricFamilyName + help + unit
|
|
// 4 + 4 + 4 + 2 + len(metricFamilyName) + 2 + len(help) + 2 + len(unit)
|
|
if len(data) < 18 {
|
|
return data, fmt.Errorf("data too short for unmarshaling metadata; got %d bytes; want at least 18 bytes", len(data))
|
|
}
|
|
accountID := encoding.UnmarshalUint32(data)
|
|
projectID := encoding.UnmarshalUint32(data[4:])
|
|
data = data[8:]
|
|
mr.AccountID = accountID
|
|
mr.ProjectID = projectID
|
|
|
|
typ := encoding.UnmarshalUint32(data)
|
|
mr.Type = prompb.MetricType(typ)
|
|
data = data[4:]
|
|
|
|
nextString := func() ([]byte, error) {
|
|
size := encoding.UnmarshalUint16(data)
|
|
data = data[2:]
|
|
if len(data) < int(size) {
|
|
return nil, fmt.Errorf("string data too short; got %d bytes; want %d bytes", len(data), size)
|
|
}
|
|
val := data[:size]
|
|
data = data[size:]
|
|
return val, nil
|
|
}
|
|
var err error
|
|
mr.MetricFamilyName, err = nextString()
|
|
if err != nil {
|
|
return data, fmt.Errorf("cannot unmarshal metric family name: %w", err)
|
|
}
|
|
mr.Help, err = nextString()
|
|
if err != nil {
|
|
return data, fmt.Errorf("cannot unmarshal help: %w", err)
|
|
}
|
|
mr.Unit, err = nextString()
|
|
if err != nil {
|
|
return data, fmt.Errorf("cannot unmarshal unit: %w", err)
|
|
}
|
|
|
|
return data, nil
|
|
}
|
|
|
|
// Reset resets Row
|
|
func (mr *Row) Reset() {
|
|
mr.AccountID = 0
|
|
mr.ProjectID = 0
|
|
mr.Type = 0
|
|
mr.MetricFamilyName = mr.MetricFamilyName[:0]
|
|
mr.Help = mr.Help[:0]
|
|
mr.Unit = mr.Unit[:0]
|
|
mr.heapIdx = 0
|
|
mr.lastWriteTime = 0
|
|
}
|
|
|
|
// String implements Stringer interface
|
|
func (mr *Row) String() string {
|
|
return fmt.Sprintf("AccountID: %d, ProjectID: %d, Type: %d, MetricFamilyName: %q, Help: %q, Unit: %q",
|
|
mr.AccountID, mr.ProjectID, mr.Type, mr.MetricFamilyName, mr.Help, mr.Unit)
|
|
}
|
|
|
|
// UnmarshalRows parses Rows from provided buffer according to the maxRows
|
|
//
|
|
// returns parsed Rows and tails buffer if maxRows value was reached
|
|
func UnmarshalRows(dst []Row, src []byte, maxRows int) ([]Row, []byte, error) {
|
|
for len(src) > 0 && maxRows > 0 {
|
|
if len(dst) < cap(dst) {
|
|
dst = dst[:len(dst)+1]
|
|
} else {
|
|
dst = append(dst, Row{})
|
|
}
|
|
mr := &dst[len(dst)-1]
|
|
tail, err := mr.Unmarshal(src)
|
|
if err != nil {
|
|
return dst, tail, err
|
|
}
|
|
src = tail
|
|
maxRows--
|
|
}
|
|
return dst, src, nil
|
|
}
|
|
|
|
func marshalBytesFast(dst []byte, s []byte) []byte {
|
|
dst = encoding.MarshalUint16(dst, uint16(len(s)))
|
|
dst = append(dst, s...)
|
|
return dst
|
|
}
|