app/vmselect/promql: use unsafe.Slice instead of deprecated reflect.SliceHeader

This commit is contained in:
Aliaksandr Valialkin 2024-02-29 17:47:29 +02:00
parent 319d21eddf
commit fed04e7f25
No known key found for this signature in database
GPG Key ID: 52C003EE2BCDB9EB
2 changed files with 13 additions and 40 deletions

View File

@ -2,7 +2,6 @@ package promql
import ( import (
"fmt" "fmt"
"reflect"
"sort" "sort"
"strconv" "strconv"
"sync" "sync"
@ -318,60 +317,32 @@ func unmarshalBytesFast(src []byte) ([]byte, []byte, error) {
return src[n:], src[:n], nil return src[n:], src[:n], nil
} }
func float64ToByteSlice(a []float64) (b []byte) { func float64ToByteSlice(a []float64) []byte {
if len(a) == 0 { return unsafe.Slice((*byte)(unsafe.Pointer(unsafe.SliceData(a))), len(a)*8)
return nil
}
sh := (*reflect.SliceHeader)(unsafe.Pointer(&b))
sh.Data = uintptr(unsafe.Pointer(&a[0]))
sh.Len = len(a) * int(unsafe.Sizeof(a[0]))
sh.Cap = sh.Len
return
} }
func int64ToByteSlice(a []int64) (b []byte) { func int64ToByteSlice(a []int64) []byte {
if len(a) == 0 { return unsafe.Slice((*byte)(unsafe.Pointer(unsafe.SliceData(a))), len(a)*8)
return nil
}
sh := (*reflect.SliceHeader)(unsafe.Pointer(&b))
sh.Data = uintptr(unsafe.Pointer(&a[0]))
sh.Len = len(a) * int(unsafe.Sizeof(a[0]))
sh.Cap = sh.Len
return
} }
func byteSliceToInt64(b []byte) (a []int64) { func byteSliceToInt64(b []byte) []int64 {
if len(b) == 0 {
return nil
}
sh := (*reflect.SliceHeader)(unsafe.Pointer(&a))
sh.Data = uintptr(unsafe.Pointer(&b[0]))
sh.Len = len(b) / int(unsafe.Sizeof(a[0]))
sh.Cap = sh.Len
// Make sure that the returned slice is properly aligned to 8 bytes. // Make sure that the returned slice is properly aligned to 8 bytes.
// This prevents from SIGBUS error on arm architectures, which deny unaligned access. // This prevents from SIGBUS error on arm architectures, which deny unaligned access.
// See https://github.com/VictoriaMetrics/VictoriaMetrics/pull/3927 // See https://github.com/VictoriaMetrics/VictoriaMetrics/pull/3927
if sh.Data%8 != 0 { if uintptr(unsafe.Pointer(unsafe.SliceData(b)))%8 != 0 {
logger.Panicf("BUG: the input byte slice b must be aligned to 8 bytes") logger.Panicf("BUG: the input byte slice b must be aligned to 8 bytes")
} }
return return unsafe.Slice((*int64)(unsafe.Pointer(unsafe.SliceData(b))), len(b)/8)
} }
func byteSliceToFloat64(b []byte) (a []float64) { func byteSliceToFloat64(b []byte) []float64 {
if len(b) == 0 {
return nil
}
sh := (*reflect.SliceHeader)(unsafe.Pointer(&a))
sh.Data = uintptr(unsafe.Pointer(&b[0]))
sh.Len = len(b) / int(unsafe.Sizeof(a[0]))
sh.Cap = sh.Len
// Make sure that the returned slice is properly aligned to 8 bytes. // Make sure that the returned slice is properly aligned to 8 bytes.
// This prevents from SIGBUS error on arm architectures, which deny unaligned access. // This prevents from SIGBUS error on arm architectures, which deny unaligned access.
// See https://github.com/VictoriaMetrics/VictoriaMetrics/pull/3927 // See https://github.com/VictoriaMetrics/VictoriaMetrics/pull/3927
if sh.Data%8 != 0 { if uintptr(unsafe.Pointer(unsafe.SliceData(b)))%8 != 0 {
logger.Panicf("BUG: the input byte slice b must be aligned to 8 bytes") logger.Panicf("BUG: the input byte slice b must be aligned to 8 bytes")
} }
return return unsafe.Slice((*float64)(unsafe.Pointer(unsafe.SliceData(b))), len(b)/8)
} }
func stringMetricName(mn *storage.MetricName) string { func stringMetricName(mn *storage.MetricName) string {

View File

@ -52,7 +52,9 @@ func TestMarshalTimeseriesFast(t *testing.T) {
MetricName: storage.MetricName{ MetricName: storage.MetricName{
MetricGroup: []byte{}, MetricGroup: []byte{},
}, },
denyReuse: true, Values: []float64{},
Timestamps: []int64{},
denyReuse: true,
}}) }})
f([]*timeseries{{ f([]*timeseries{{
MetricName: storage.MetricName{ MetricName: storage.MetricName{