Neater string vs byte-slice conversions

unsafe.Slice and unsafe.StringData were added in Go 1.20

Signed-off-by: Bryan Boreham <bjboreham@gmail.com>
This commit is contained in:
Bryan Boreham 2024-07-05 15:17:46 +01:00
parent c94c5b64c3
commit d20668fe71
5 changed files with 8 additions and 13 deletions

View file

@ -218,5 +218,5 @@ func contains(s []Label, n string) bool {
} }
func yoloString(b []byte) string { func yoloString(b []byte) string {
return *((*string)(unsafe.Pointer(&b))) return unsafe.String(unsafe.SliceData(b), len(b))
} }

View file

@ -16,7 +16,6 @@
package labels package labels
import ( import (
"reflect"
"slices" "slices"
"strings" "strings"
"unsafe" "unsafe"
@ -299,10 +298,8 @@ func Equal(ls, o Labels) bool {
func EmptyLabels() Labels { func EmptyLabels() Labels {
return Labels{} return Labels{}
} }
func yoloBytes(s string) (b []byte) { func yoloBytes(s string) []byte {
*(*string)(unsafe.Pointer(&b)) = s return unsafe.Slice(unsafe.StringData(s), len(s))
(*reflect.SliceHeader)(unsafe.Pointer(&b)).Cap = len(s)
return
} }
// New returns a sorted Labels from the given labels. // New returns a sorted Labels from the given labels.
@ -338,8 +335,8 @@ func Compare(a, b Labels) int {
} }
i := 0 i := 0
// First, go 8 bytes at a time. Data strings are expected to be 8-byte aligned. // First, go 8 bytes at a time. Data strings are expected to be 8-byte aligned.
sp := unsafe.Pointer((*reflect.StringHeader)(unsafe.Pointer(&shorter)).Data) sp := unsafe.Pointer(unsafe.StringData(shorter))
lp := unsafe.Pointer((*reflect.StringHeader)(unsafe.Pointer(&longer)).Data) lp := unsafe.Pointer(unsafe.StringData(longer))
for ; i < len(shorter)-8; i += 8 { for ; i < len(shorter)-8; i += 8 {
if *(*uint64)(unsafe.Add(sp, i)) != *(*uint64)(unsafe.Add(lp, i)) { if *(*uint64)(unsafe.Add(sp, i)) != *(*uint64)(unsafe.Add(lp, i)) {
break break

View file

@ -502,7 +502,7 @@ func unreplace(s string) string {
} }
func yoloString(b []byte) string { func yoloString(b []byte) string {
return *((*string)(unsafe.Pointer(&b))) return unsafe.String(unsafe.SliceData(b), len(b))
} }
func parseFloat(s string) (float64, error) { func parseFloat(s string) (float64, error) {

View file

@ -20,7 +20,6 @@ import (
"hash" "hash"
"hash/crc32" "hash/crc32"
"math" "math"
"unsafe"
"github.com/dennwc/varint" "github.com/dennwc/varint"
) )
@ -75,8 +74,7 @@ func (e *Encbuf) PutVarint64(x int64) {
// PutUvarintStr writes a string to the buffer prefixed by its varint length (in bytes!). // PutUvarintStr writes a string to the buffer prefixed by its varint length (in bytes!).
func (e *Encbuf) PutUvarintStr(s string) { func (e *Encbuf) PutUvarintStr(s string) {
b := *(*[]byte)(unsafe.Pointer(&s)) e.PutUvarint(len(s))
e.PutUvarint(len(b))
e.PutString(s) e.PutString(s)
} }

View file

@ -2062,5 +2062,5 @@ func (dec *Decoder) Series(b []byte, builder *labels.ScratchBuilder, chks *[]chu
} }
func yoloString(b []byte) string { func yoloString(b []byte) string {
return *((*string)(unsafe.Pointer(&b))) return unsafe.String(unsafe.SliceData(b), len(b))
} }