Skip to content

Commit

Permalink
convert mimir.proto references to LabelAdapter & all members of TimeS…
Browse files Browse the repository at this point in the history
…eries to non-nullable
  • Loading branch information
francoposa committed Jan 29, 2025
1 parent 7d16848 commit b0404a6
Show file tree
Hide file tree
Showing 10 changed files with 315 additions and 330 deletions.
14 changes: 7 additions & 7 deletions pkg/mimirpb/compat.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import (
// method implies that only a single sample and optionally exemplar can be set for each series.
//
// For histograms use NewWriteRequest and Add* functions to build write request with Floats and Histograms
func ToWriteRequest(lbls [][]mimirpb_custom.LabelAdapter, samples []Sample, exemplars []*Exemplar, metadata []*MetricMetadata, source WriteRequest_SourceEnum) *WriteRequest {
func ToWriteRequest(lbls [][]*mimirpb_custom.LabelAdapter, samples []*Sample, exemplars []*Exemplar, metadata []*MetricMetadata, source WriteRequest_SourceEnum) *WriteRequest {
return NewWriteRequest(metadata, source).AddFloatSeries(lbls, samples, exemplars)
}

Expand All @@ -46,7 +46,7 @@ func NewWriteRequest(metadata []*MetricMetadata, source WriteRequest_SourceEnum)
// AddFloatSeries converts matched slices of Labels, Samples, Exemplars into a WriteRequest
// proto. It gets timeseries from the pool, so ReuseSlice() should be called when done. Note that this
// method implies that only a single sample and optionally exemplar can be set for each series.
func (req *WriteRequest) AddFloatSeries(lbls [][]mimirpb_custom.LabelAdapter, samples []Sample, exemplars []*Exemplar) *WriteRequest {
func (req *WriteRequest) AddFloatSeries(lbls [][]*mimirpb_custom.LabelAdapter, samples []*Sample, exemplars []*Exemplar) *WriteRequest {
for i, s := range samples {
ts := TimeseriesFromPool()
ts.Labels = append(ts.Labels, lbls[i]...)
Expand All @@ -56,7 +56,7 @@ func (req *WriteRequest) AddFloatSeries(lbls [][]mimirpb_custom.LabelAdapter, sa
// If provided, we expect a matched entry for exemplars (like labels and samples) but the
// entry may be nil since not every timeseries is guaranteed to have an exemplar.
if e := exemplars[i]; e != nil {
ts.Exemplars = append(ts.Exemplars, *e)
ts.Exemplars = append(ts.Exemplars, e)
}
}

Expand All @@ -68,7 +68,7 @@ func (req *WriteRequest) AddFloatSeries(lbls [][]mimirpb_custom.LabelAdapter, sa
// AddHistogramSeries converts matched slices of Labels, Histograms, Exemplars into a WriteRequest
// proto. It gets timeseries from the pool, so ReuseSlice() should be called when done. Note that this
// method implies that only a single sample and optionally exemplar can be set for each series.
func (req *WriteRequest) AddHistogramSeries(lbls [][]mimirpb_custom.LabelAdapter, histograms []Histogram, exemplars []*Exemplar) *WriteRequest {
func (req *WriteRequest) AddHistogramSeries(lbls [][]*mimirpb_custom.LabelAdapter, histograms []*Histogram, exemplars []*Exemplar) *WriteRequest {
for i, s := range histograms {
ts := TimeseriesFromPool()
ts.Labels = append(ts.Labels, lbls[i]...)
Expand All @@ -78,7 +78,7 @@ func (req *WriteRequest) AddHistogramSeries(lbls [][]mimirpb_custom.LabelAdapter
// If provided, we expect a matched entry for exemplars (like labels and samples) but the
// entry may be nil since not every timeseries is guaranteed to have an exemplar.
if e := exemplars[i]; e != nil {
ts.Exemplars = append(ts.Exemplars, *e)
ts.Exemplars = append(ts.Exemplars, e)
}
}

Expand All @@ -93,7 +93,7 @@ func (req *WriteRequest) AddHistogramSeries(lbls [][]mimirpb_custom.LabelAdapter
// to be added per time series for simplicity.
func (req *WriteRequest) AddExemplarsAt(i int, exemplars []*Exemplar) *WriteRequest {
for _, e := range exemplars {
req.Timeseries[i].Exemplars = append(req.Timeseries[i].Exemplars, *e)
req.Timeseries[i].Exemplars = append(req.Timeseries[i].Exemplars, e)
}
return req
}
Expand Down Expand Up @@ -598,7 +598,7 @@ type PreallocatingMetric struct {
func (m *PreallocatingMetric) Unmarshal(dAtA []byte) error {
numLabels, ok := m.labelsCount(dAtA)
if ok && numLabels > 0 {
m.Labels = make([]mimirpb_custom.LabelAdapter, 0, numLabels)
m.Labels = make([]*mimirpb_custom.LabelAdapter, 0, numLabels)
}

return m.Metric.Unmarshal(dAtA)
Expand Down
32 changes: 20 additions & 12 deletions pkg/mimirpb/compat_slice.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,23 @@ import (
//
// Note: while resulting labels.Labels is supposedly sorted, this function
// doesn't enforce that. If input is not sorted, output will be wrong.
func FromLabelAdaptersToLabels(ls []mimirpb_custom.LabelAdapter) labels.Labels {
return *(*labels.Labels)(unsafe.Pointer(&ls))
func FromLabelAdaptersToLabels(ls []*mimirpb_custom.LabelAdapter) labels.Labels {
out := make(labels.Labels, len(ls))
for i := range ls {
out[i] = *(*labels.Label)(unsafe.Pointer(ls[i])) // Dereferencing and converting safely
}
return out
}

// This is like FromLabelAdaptersToLabels but easier for stringlabels to implement.
func FromLabelAdaptersOverwriteLabels(_ *labels.ScratchBuilder, ls []mimirpb_custom.LabelAdapter, dest *labels.Labels) {
func FromLabelAdaptersOverwriteLabels(_ *labels.ScratchBuilder, ls []*mimirpb_custom.LabelAdapter, dest *labels.Labels) {
*dest = FromLabelAdaptersToLabels(ls)
}

// FromLabelAdaptersToLabelsWithCopy converts []LabelAdapter to labels.Labels.
// Do NOT use unsafe to convert between data types because this function may
// get in input labels whose data structure is reused.
func FromLabelAdaptersToLabelsWithCopy(input []mimirpb_custom.LabelAdapter) labels.Labels {
func FromLabelAdaptersToLabelsWithCopy(input []*mimirpb_custom.LabelAdapter) labels.Labels {
return CopyLabels(FromLabelAdaptersToLabels(input))
}

Expand Down Expand Up @@ -72,23 +76,27 @@ func copyStringToBuffer(in string, buf []byte) (string, []byte) {
}

// FromLabelAdaptersToBuilder converts []LabelAdapter to labels.Builder.
func FromLabelAdaptersToBuilder(ls []mimirpb_custom.LabelAdapter, builder *labels.Builder) {
func FromLabelAdaptersToBuilder(ls []*mimirpb_custom.LabelAdapter, builder *labels.Builder) {
builder.Reset(FromLabelAdaptersToLabels(ls))
}

// FromBuilderToLabelAdapters converts labels.Builder to []LabelAdapter.
func FromBuilderToLabelAdapters(builder *labels.Builder, _ []mimirpb_custom.LabelAdapter) []mimirpb_custom.LabelAdapter {
func FromBuilderToLabelAdapters(builder *labels.Builder, _ []*mimirpb_custom.LabelAdapter) []*mimirpb_custom.LabelAdapter {
return FromLabelsToLabelAdapters(builder.Labels())
}

// FromLabelsToLabelAdapters casts labels.Labels to []LabelAdapter.
// It uses unsafe, but as LabelAdapter == labels.Label this should be safe.
// This allows us to use labels.Labels directly in protos.
func FromLabelsToLabelAdapters(ls labels.Labels) []mimirpb_custom.LabelAdapter {
return *(*[]mimirpb_custom.LabelAdapter)(unsafe.Pointer(&ls))
// FromLabelsToLabelAdapters converts labels.Labels to []*LabelAdapter.
// This avoids unsafe operations and ensures correctness.
func FromLabelsToLabelAdapters(ls labels.Labels) []*mimirpb_custom.LabelAdapter {
adapters := make([]*mimirpb_custom.LabelAdapter, len(ls))
for i := range ls {
// Cast each Label to LabelAdapter and take the address
adapters[i] = (*mimirpb_custom.LabelAdapter)(unsafe.Pointer(&ls[i]))
}
return adapters
}

// CompareLabelAdapters returns 0 if a==b, <0 if a < b, and >0 if a > b.
func CompareLabelAdapters(a, b []mimirpb_custom.LabelAdapter) int {
func CompareLabelAdapters(a, b []*mimirpb_custom.LabelAdapter) int {
return labels.Compare(FromLabelAdaptersToLabels(a), FromLabelAdaptersToLabels(b))
}
40 changes: 20 additions & 20 deletions pkg/mimirpb/compat_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,15 +180,15 @@ func TestMetricMetadataToMetricTypeToMetricType(t *testing.T) {
}

func TestFromLabelAdaptersToLabels(t *testing.T) {
input := []mimirpb_custom.LabelAdapter{{Name: "hello", Value: "world"}}
input := []*mimirpb_custom.LabelAdapter{{Name: "hello", Value: "world"}}
expected := labels.FromStrings("hello", "world")
actual := FromLabelAdaptersToLabels(input)

assert.Equal(t, expected, actual)
}

func TestFromLabelAdaptersToLabelsWithCopy(t *testing.T) {
input := []mimirpb_custom.LabelAdapter{{Name: "hello", Value: "world"}}
input := []*mimirpb_custom.LabelAdapter{{Name: "hello", Value: "world"}}
expected := labels.FromStrings("hello", "world")
actual := FromLabelAdaptersToLabelsWithCopy(input)

Expand All @@ -200,7 +200,7 @@ func TestFromLabelAdaptersToLabelsWithCopy(t *testing.T) {
}

func BenchmarkFromLabelAdaptersToLabelsWithCopy(b *testing.B) {
input := []mimirpb_custom.LabelAdapter{
input := []*mimirpb_custom.LabelAdapter{
{Name: "hello", Value: "world"},
{Name: "some label", Value: "and its value"},
{Name: "long long long long long label name", Value: "perhaps even longer label value, but who's counting anyway?"}}
Expand Down Expand Up @@ -266,7 +266,7 @@ func BenchmarkFromHPointsToHistograms(b *testing.B) {
func TestPreallocatingMetric(t *testing.T) {
t.Run("should be unmarshallable from the bytes of a default Metric", func(t *testing.T) {
metric := Metric{
Labels: []mimirpb_custom.LabelAdapter{
Labels: []*mimirpb_custom.LabelAdapter{
{Name: "l1", Value: "v1"},
{Name: "l2", Value: "v2"},
{Name: "l3", Value: "v3"},
Expand All @@ -290,7 +290,7 @@ func TestPreallocatingMetric(t *testing.T) {

t.Run("should correctly preallocate Labels slice", func(t *testing.T) {
metric := Metric{
Labels: []mimirpb_custom.LabelAdapter{
Labels: []*mimirpb_custom.LabelAdapter{
{Name: "l1", Value: "v1"},
{Name: "l2", Value: "v2"},
{Name: "l3", Value: "v3"},
Expand All @@ -311,7 +311,7 @@ func TestPreallocatingMetric(t *testing.T) {

t.Run("should not allocate a slice when there are 0 Labels (same as Metric's behaviour)", func(t *testing.T) {
metric := Metric{
Labels: []mimirpb_custom.LabelAdapter{},
Labels: []*mimirpb_custom.LabelAdapter{},
}

metricBytes, err := metric.Marshal()
Expand All @@ -325,7 +325,7 @@ func TestPreallocatingMetric(t *testing.T) {

t.Run("should marshal to the same bytes as Metric", func(t *testing.T) {
preallocMetric := &PreallocatingMetric{Metric{
Labels: []mimirpb_custom.LabelAdapter{
Labels: []*mimirpb_custom.LabelAdapter{
{Name: "l1", Value: "v1"},
{Name: "l2", Value: "v2"},
{Name: "l3", Value: "v3"},
Expand All @@ -335,7 +335,7 @@ func TestPreallocatingMetric(t *testing.T) {
}}

metric := Metric{
Labels: []mimirpb_custom.LabelAdapter{
Labels: []*mimirpb_custom.LabelAdapter{
{Name: "l1", Value: "v1"},
{Name: "l2", Value: "v2"},
{Name: "l3", Value: "v3"},
Expand Down Expand Up @@ -643,65 +643,65 @@ func TestPrometheusHistogramSpanInSyncWithMimirPbBucketSpan(_ *testing.T) {
}

func TestCompareLabelAdapters(t *testing.T) {
labels := []mimirpb_custom.LabelAdapter{
labels := []*mimirpb_custom.LabelAdapter{
{Name: "aaa", Value: "111"},
{Name: "bbb", Value: "222"},
}

tests := []struct {
compared []mimirpb_custom.LabelAdapter
compared []*mimirpb_custom.LabelAdapter
expected int
}{
{
compared: []mimirpb_custom.LabelAdapter{
compared: []*mimirpb_custom.LabelAdapter{
{Name: "aaa", Value: "110"},
{Name: "bbb", Value: "222"},
},
expected: 1,
},
{
compared: []mimirpb_custom.LabelAdapter{
compared: []*mimirpb_custom.LabelAdapter{
{Name: "aaa", Value: "111"},
{Name: "bbb", Value: "233"},
},
expected: -1,
},
{
compared: []mimirpb_custom.LabelAdapter{
compared: []*mimirpb_custom.LabelAdapter{
{Name: "aaa", Value: "111"},
{Name: "bar", Value: "222"},
},
expected: 1,
},
{
compared: []mimirpb_custom.LabelAdapter{
compared: []*mimirpb_custom.LabelAdapter{
{Name: "aaa", Value: "111"},
{Name: "bbc", Value: "222"},
},
expected: -1,
},
{
compared: []mimirpb_custom.LabelAdapter{
compared: []*mimirpb_custom.LabelAdapter{
{Name: "aaa", Value: "111"},
{Name: "bb", Value: "222"},
},
expected: 1,
},
{
compared: []mimirpb_custom.LabelAdapter{
compared: []*mimirpb_custom.LabelAdapter{
{Name: "aaa", Value: "111"},
{Name: "bbbb", Value: "222"},
},
expected: -1,
},
{
compared: []mimirpb_custom.LabelAdapter{
compared: []*mimirpb_custom.LabelAdapter{
{Name: "aaa", Value: "111"},
},
expected: 1,
},
{
compared: []mimirpb_custom.LabelAdapter{
compared: []*mimirpb_custom.LabelAdapter{
{Name: "aaa", Value: "111"},
{Name: "bbb", Value: "222"},
{Name: "ccc", Value: "333"},
Expand All @@ -710,14 +710,14 @@ func TestCompareLabelAdapters(t *testing.T) {
expected: -2,
},
{
compared: []mimirpb_custom.LabelAdapter{
compared: []*mimirpb_custom.LabelAdapter{
{Name: "aaa", Value: "111"},
{Name: "bbb", Value: "222"},
},
expected: 0,
},
{
compared: []mimirpb_custom.LabelAdapter{},
compared: []*mimirpb_custom.LabelAdapter{},
expected: 1,
},
}
Expand Down
28 changes: 14 additions & 14 deletions pkg/mimirpb/custom_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,27 +16,27 @@ import (
func TestWriteRequest_MinTimestamp(t *testing.T) {
req := &WriteRequest{
Timeseries: []PreallocTimeseries{{TimeSeries: &TimeSeries{
Samples: []Sample{{TimestampMs: 10}},
Exemplars: []Exemplar{{TimestampMs: 20}},
Histograms: []Histogram{{Timestamp: 30}},
Samples: []*Sample{{TimestampMs: 10}},
Exemplars: []*Exemplar{{TimestampMs: 20}},
Histograms: []*Histogram{{Timestamp: 30}},
}}},
}
assert.Equal(t, int64(10), req.MinTimestamp())

req = &WriteRequest{
Timeseries: []PreallocTimeseries{{TimeSeries: &TimeSeries{
Samples: []Sample{{TimestampMs: 20}},
Exemplars: []Exemplar{{TimestampMs: 10}},
Histograms: []Histogram{{Timestamp: 30}},
Samples: []*Sample{{TimestampMs: 20}},
Exemplars: []*Exemplar{{TimestampMs: 10}},
Histograms: []*Histogram{{Timestamp: 30}},
}}},
}
assert.Equal(t, int64(10), req.MinTimestamp())

req = &WriteRequest{
Timeseries: []PreallocTimeseries{{TimeSeries: &TimeSeries{
Samples: []Sample{{TimestampMs: 20}},
Exemplars: []Exemplar{{TimestampMs: 30}},
Histograms: []Histogram{{Timestamp: 10}},
Samples: []*Sample{{TimestampMs: 20}},
Exemplars: []*Exemplar{{TimestampMs: 30}},
Histograms: []*Histogram{{Timestamp: 10}},
}}},
}
assert.Equal(t, int64(10), req.MinTimestamp())
Expand All @@ -46,7 +46,7 @@ func TestWriteRequest_IsEmpty(t *testing.T) {
t.Run("should return false if a WriteRequest has both Timeseries and Metadata", func(t *testing.T) {
req := &WriteRequest{
Timeseries: []PreallocTimeseries{{TimeSeries: &TimeSeries{
Samples: []Sample{{TimestampMs: 20}},
Samples: []*Sample{{TimestampMs: 20}},
}}},
Metadata: []*MetricMetadata{
{Type: COUNTER, MetricFamilyName: "test_metric", Help: "This is a test metric."},
Expand All @@ -59,7 +59,7 @@ func TestWriteRequest_IsEmpty(t *testing.T) {
t.Run("should return false if a WriteRequest has only Timeseries", func(t *testing.T) {
req := &WriteRequest{
Timeseries: []PreallocTimeseries{{TimeSeries: &TimeSeries{
Samples: []Sample{{TimestampMs: 20}},
Samples: []*Sample{{TimestampMs: 20}},
}}},
}

Expand Down Expand Up @@ -89,9 +89,9 @@ func TestWriteRequest_IsEmpty(t *testing.T) {
func TestWriteRequest_MetadataSize_TimeseriesSize(t *testing.T) {
req := &WriteRequest{
Timeseries: []PreallocTimeseries{{TimeSeries: &TimeSeries{
Samples: []Sample{{TimestampMs: 20}},
Exemplars: []Exemplar{{TimestampMs: 30}},
Histograms: []Histogram{{Timestamp: 10}},
Samples: []*Sample{{TimestampMs: 20}},
Exemplars: []*Exemplar{{TimestampMs: 30}},
Histograms: []*Histogram{{Timestamp: 10}},
}}},
Metadata: []*MetricMetadata{
{Type: COUNTER, MetricFamilyName: "test_metric", Help: "This is a test metric."},
Expand Down
Loading

0 comments on commit b0404a6

Please sign in to comment.