Makefile: add build and test rules with enabled race detector. These rules have -race suffix

Fix also `unsafe pointer conversion` errors detected by Go1.14. See https://golang.org/doc/go1.14#compiler .
This commit is contained in:
Aliaksandr Valialkin 2020-03-05 12:02:06 +02:00
parent 197d2916ab
commit 0d893eff36
7 changed files with 72 additions and 19 deletions

View File

@ -106,6 +106,9 @@ check-all: fmt vet lint errcheck golangci-lint
test: test:
GO111MODULE=on go test -mod=vendor ./lib/... ./app/... GO111MODULE=on go test -mod=vendor ./lib/... ./app/...
test-race:
GO111MODULE=on go test -mod=vendor -race ./lib/... ./app/...
test-pure: test-pure:
GO111MODULE=on CGO_ENABLED=0 go test -mod=vendor ./lib/... ./app/... GO111MODULE=on CGO_ENABLED=0 go test -mod=vendor ./lib/... ./app/...

View File

@ -3,6 +3,9 @@
vmagent: vmagent:
APP_NAME=vmagent $(MAKE) app-local APP_NAME=vmagent $(MAKE) app-local
vmagent-race:
APP_NAME=vmagent RACE=-race $(MAKE) app-local
vmagent-prod: vmagent-prod:
APP_NAME=vmagent $(MAKE) app-via-docker APP_NAME=vmagent $(MAKE) app-via-docker

View File

@ -3,6 +3,9 @@
vmbackup: vmbackup:
APP_NAME=vmbackup $(MAKE) app-local APP_NAME=vmbackup $(MAKE) app-local
vmbackup-race:
APP_NAME=vmbackup RACE=-race $(MAKE) app-local
vmbackup-prod: vmbackup-prod:
APP_NAME=vmbackup $(MAKE) app-via-docker APP_NAME=vmbackup $(MAKE) app-via-docker

View File

@ -3,6 +3,9 @@
vmrestore: vmrestore:
APP_NAME=vmrestore $(MAKE) app-local APP_NAME=vmrestore $(MAKE) app-local
vmrestore-race:
APP_NAME=vmrestore RACE=-race $(MAKE) app-local
vmrestore-prod: vmrestore-prod:
APP_NAME=vmrestore $(MAKE) app-via-docker APP_NAME=vmrestore $(MAKE) app-via-docker

View File

@ -1,5 +0,0 @@
package promql
import "unsafe"
const maxByteSliceLen = 1<<(31+9*(unsafe.Sizeof(int(0))/8)) - 1

View File

@ -2,6 +2,7 @@ package promql
import ( import (
"fmt" "fmt"
"reflect"
"sort" "sort"
"strconv" "strconv"
"sync" "sync"
@ -168,7 +169,7 @@ func (ts *timeseries) marshalFastNoTimestamps(dst []byte) []byte {
// during marshalFastTimestamps. // during marshalFastTimestamps.
var valuesBuf []byte var valuesBuf []byte
if len(ts.Values) > 0 { if len(ts.Values) > 0 {
valuesBuf = (*[maxByteSliceLen]byte)(unsafe.Pointer(&ts.Values[0]))[:len(ts.Values)*8] valuesBuf = float64ToByteSlice(ts.Values)
} }
dst = append(dst, valuesBuf...) dst = append(dst, valuesBuf...)
return dst return dst
@ -178,7 +179,7 @@ func marshalFastTimestamps(dst []byte, timestamps []int64) []byte {
dst = encoding.MarshalUint32(dst, uint32(len(timestamps))) dst = encoding.MarshalUint32(dst, uint32(len(timestamps)))
var timestampsBuf []byte var timestampsBuf []byte
if len(timestamps) > 0 { if len(timestamps) > 0 {
timestampsBuf = (*[maxByteSliceLen]byte)(unsafe.Pointer(&timestamps[0]))[:len(timestamps)*8] timestampsBuf = int64ToByteSlice(timestamps)
} }
dst = append(dst, timestampsBuf...) dst = append(dst, timestampsBuf...)
return dst return dst
@ -199,8 +200,7 @@ func unmarshalFastTimestamps(src []byte) ([]byte, []int64, error) {
if len(src) < bufSize { if len(src) < bufSize {
return src, nil, fmt.Errorf("cannot unmarshal timestamps; got %d bytes; want at least %d bytes", len(src), bufSize) return src, nil, fmt.Errorf("cannot unmarshal timestamps; got %d bytes; want at least %d bytes", len(src), bufSize)
} }
timestamps := (*[maxByteSliceLen / 8]int64)(unsafe.Pointer(&src[0]))[:timestampsCount] timestamps := byteSliceToInt64(src[:bufSize])
timestamps = timestamps[:len(timestamps):len(timestamps)]
src = src[bufSize:] src = src[bufSize:]
return src, timestamps, nil return src, timestamps, nil
@ -229,12 +229,43 @@ func (ts *timeseries) unmarshalFastNoTimestamps(src []byte) ([]byte, error) {
if len(src) < bufSize { if len(src) < bufSize {
return src, fmt.Errorf("cannot unmarshal values; got %d bytes; want at least %d bytes", len(src), bufSize) return src, fmt.Errorf("cannot unmarshal values; got %d bytes; want at least %d bytes", len(src), bufSize)
} }
values := (*[maxByteSliceLen / 8]float64)(unsafe.Pointer(&src[0]))[:valuesCount] ts.Values = byteSliceToFloat64(src[:bufSize])
ts.Values = values[:len(values):len(values)]
return src[bufSize:], nil return src[bufSize:], nil
} }
func float64ToByteSlice(a []float64) (b []byte) {
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) {
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) {
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
return
}
func byteSliceToFloat64(b []byte) (a []float64) {
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
return
}
// unmarshalMetricNameFast unmarshals mn from src, so mn members // unmarshalMetricNameFast unmarshals mn from src, so mn members
// hold references to src. // hold references to src.
// //

View File

@ -2,6 +2,7 @@ package fastnum
import ( import (
"bytes" "bytes"
"reflect"
"unsafe" "unsafe"
) )
@ -84,7 +85,7 @@ func isInt64Data(a, data []int64) bool {
if len(data) != 8*1024 { if len(data) != 8*1024 {
panic("len(data) must equal to 8*1024") panic("len(data) must equal to 8*1024")
} }
b := (*[64 * 1024]byte)(unsafe.Pointer(&data[0])) b := int64ToByteSlice(data)
for len(a) > 0 { for len(a) > 0 {
n := len(data) n := len(data)
if n > len(a) { if n > len(a) {
@ -92,9 +93,8 @@ func isInt64Data(a, data []int64) bool {
} }
x := a[:n] x := a[:n]
a = a[n:] a = a[n:]
xb := (*[64 * 1024]byte)(unsafe.Pointer(&x[0])) xb := int64ToByteSlice(x)
xbLen := len(x) * 8 if !bytes.Equal(xb, b[:len(xb)]) {
if !bytes.Equal(xb[:xbLen], b[:xbLen]) {
return false return false
} }
} }
@ -108,7 +108,7 @@ func isFloat64Data(a, data []float64) bool {
if len(data) != 8*1024 { if len(data) != 8*1024 {
panic("len(data) must equal to 8*1024") panic("len(data) must equal to 8*1024")
} }
b := (*[64 * 1024]byte)(unsafe.Pointer(&data[0])) b := float64ToByteSlice(data)
for len(a) > 0 { for len(a) > 0 {
n := len(data) n := len(data)
if n > len(a) { if n > len(a) {
@ -116,15 +116,30 @@ func isFloat64Data(a, data []float64) bool {
} }
x := a[:n] x := a[:n]
a = a[n:] a = a[n:]
xb := (*[64 * 1024]byte)(unsafe.Pointer(&x[0])) xb := float64ToByteSlice(x)
xbLen := len(x) * 8 if !bytes.Equal(xb, b[:len(xb)]) {
if !bytes.Equal(xb[:xbLen], b[:xbLen]) {
return false return false
} }
} }
return true return true
} }
func int64ToByteSlice(a []int64) (b []byte) {
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 float64ToByteSlice(a []float64) (b []byte) {
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
}
var ( var (
int64Zeros [8 * 1024]int64 int64Zeros [8 * 1024]int64
int64Ones = func() (a [8 * 1024]int64) { int64Ones = func() (a [8 * 1024]int64) {