From 4a8c8385b52807d0889b9f5e4817999942061d8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Fri, 13 Dec 2024 19:53:11 +0000 Subject: [PATCH 1/3] zeroalloc: don't use unsafe.Pointer --- utils/zeroalloc.go | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/utils/zeroalloc.go b/utils/zeroalloc.go index ca3798c0d..941f55fa3 100644 --- a/utils/zeroalloc.go +++ b/utils/zeroalloc.go @@ -1,27 +1,30 @@ package utils -import "unsafe" +import ( + "math" + "unsafe" +) func StringToByteSlice(s string) []byte { - return *(*[]byte)(unsafe.Pointer(&s)) + return unsafe.Slice(unsafe.StringData(s), len(s)) } func ByteSliceToString(b []byte) string { - return *(*string)(unsafe.Pointer(&b)) + return unsafe.String(unsafe.SliceData(b), len(b)) } func Uint64ToInt64(val uint64) int64 { - return *(*int64)(unsafe.Pointer(&val)) + return int64(val) } func Uint64ToFloat64(val uint64) float64 { - return *(*float64)(unsafe.Pointer(&val)) + return math.Float64frombits(val) } func Int64ToUint64(val int64) uint64 { - return *(*uint64)(unsafe.Pointer(&val)) + return uint64(val) } func Float64ToUint64(val float64) uint64 { - return *(*uint64)(unsafe.Pointer(&val)) + return math.Float64bits(val) } From e700be5ba538d6c68be06cd2b6432ae373d25069 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Sun, 15 Dec 2024 00:29:41 +0000 Subject: [PATCH 2/3] replace siddontang/go/hack with zeroalloc --- client/resp.go | 7 +++---- driver/driver.go | 4 ++-- mysql/mysql_gtid.go | 6 +++--- mysql/resultset.go | 4 ++-- mysql/resultset_helper.go | 13 +++++++------ mysql/util.go | 4 ++-- replication/json_binary.go | 8 ++++---- replication/row_event.go | 8 ++++---- server/command.go | 12 ++++++------ 9 files changed, 33 insertions(+), 33 deletions(-) diff --git a/client/resp.go b/client/resp.go index ad72deff6..941e5b423 100644 --- a/client/resp.go +++ b/client/resp.go @@ -9,7 +9,6 @@ import ( "fmt" "github.com/pingcap/errors" - "github.com/siddontang/go/hack" . "github.com/go-mysql-org/go-mysql/mysql" "github.com/go-mysql-org/go-mysql/utils" @@ -78,11 +77,11 @@ func (c *Conn) handleErrorPacket(data []byte) error { if c.capability&CLIENT_PROTOCOL_41 > 0 { // skip '#' pos++ - e.State = hack.String(data[pos : pos+5]) + e.State = utils.ByteSliceToString(data[pos : pos+5]) pos += 5 } - e.Message = hack.String(data[pos:]) + e.Message = utils.ByteSliceToString(data[pos:]) return e } @@ -372,7 +371,7 @@ func (c *Conn) readResultColumns(result *Result) (err error) { return err } - result.FieldNames[hack.String(result.Fields[i].Name)] = i + result.FieldNames[utils.ByteSliceToString(result.Fields[i].Name)] = i i++ } diff --git a/driver/driver.go b/driver/driver.go index fa36dc8e0..eb72f2ca3 100644 --- a/driver/driver.go +++ b/driver/driver.go @@ -17,8 +17,8 @@ import ( "github.com/go-mysql-org/go-mysql/client" "github.com/go-mysql-org/go-mysql/mysql" + "github.com/go-mysql-org/go-mysql/utils" "github.com/pingcap/errors" - "github.com/siddontang/go/hack" ) var customTLSMutex sync.Mutex @@ -352,7 +352,7 @@ func newRows(r *mysql.Resultset) (*rows, error) { rs.columns = make([]string, len(r.Fields)) for i, f := range r.Fields { - rs.columns[i] = hack.String(f.Name) + rs.columns[i] = utils.ByteSliceToString(f.Name) } rs.step = 0 diff --git a/mysql/mysql_gtid.go b/mysql/mysql_gtid.go index 47eae6294..ecf726c1e 100644 --- a/mysql/mysql_gtid.go +++ b/mysql/mysql_gtid.go @@ -10,9 +10,9 @@ import ( "strconv" "strings" + "github.com/go-mysql-org/go-mysql/utils" "github.com/google/uuid" "github.com/pingcap/errors" - "github.com/siddontang/go/hack" ) // Like MySQL GTID Interval struct, [start, stop), left closed and right open @@ -318,7 +318,7 @@ func (s *UUIDSet) MinusInterval(in IntervalSlice) { } func (s *UUIDSet) String() string { - return hack.String(s.Bytes()) + return utils.ByteSliceToString(s.Bytes()) } func (s *UUIDSet) encode(w io.Writer) { @@ -571,7 +571,7 @@ func (s *MysqlGTIDSet) String() string { sep = "," } - return hack.String(buf.Bytes()) + return utils.ByteSliceToString(buf.Bytes()) } func (s *MysqlGTIDSet) Encode() []byte { diff --git a/mysql/resultset.go b/mysql/resultset.go index d90796b83..eee819aee 100644 --- a/mysql/resultset.go +++ b/mysql/resultset.go @@ -5,8 +5,8 @@ import ( "strconv" "sync" + "github.com/go-mysql-org/go-mysql/utils" "github.com/pingcap/errors" - "github.com/siddontang/go/hack" ) type StreamingType int @@ -263,7 +263,7 @@ func (r *Resultset) GetString(row, column int) (string, error) { case string: return v, nil case []byte: - return hack.String(v), nil + return utils.ByteSliceToString(v), nil case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64: return fmt.Sprintf("%d", v), nil diff --git a/mysql/resultset_helper.go b/mysql/resultset_helper.go index 36c0f0a3b..21a120866 100644 --- a/mysql/resultset_helper.go +++ b/mysql/resultset_helper.go @@ -5,7 +5,8 @@ import ( "strconv" "github.com/pingcap/errors" - "github.com/siddontang/go/hack" + + "github.com/go-mysql-org/go-mysql/utils" ) func FormatTextValue(value interface{}) ([]byte, error) { @@ -37,7 +38,7 @@ func FormatTextValue(value interface{}) ([]byte, error) { case []byte: return v, nil case string: - return hack.Slice(v), nil + return utils.StringToByteSlice(v), nil case nil: return nil, nil default: @@ -74,7 +75,7 @@ func formatBinaryValue(value interface{}) ([]byte, error) { case []byte: return v, nil case string: - return hack.Slice(v), nil + return utils.StringToByteSlice(v), nil default: return nil, errors.Errorf("invalid type %T", value) } @@ -128,7 +129,7 @@ func BuildSimpleTextResultset(names []string, values [][]interface{}) (*Resultse if len(values) == 0 { for i, name := range names { - r.Fields[i] = &Field{Name: hack.Slice(name), Charset: 33, Type: MYSQL_TYPE_NULL} + r.Fields[i] = &Field{Name: utils.StringToByteSlice(name), Charset: 33, Type: MYSQL_TYPE_NULL} } return r, nil } @@ -145,7 +146,7 @@ func BuildSimpleTextResultset(names []string, values [][]interface{}) (*Resultse return nil, errors.Trace(err) } if r.Fields[j] == nil { - r.Fields[j] = &Field{Name: hack.Slice(names[j]), Type: typ} + r.Fields[j] = &Field{Name: utils.StringToByteSlice(names[j]), Type: typ} err = formatField(r.Fields[j], value) if err != nil { return nil, errors.Trace(err) @@ -213,7 +214,7 @@ func BuildSimpleBinaryResultset(names []string, values [][]interface{}) (*Result if i == 0 { field := &Field{Type: typ} r.Fields[j] = field - field.Name = hack.Slice(names[j]) + field.Name = utils.StringToByteSlice(names[j]) if err = formatField(field, value); err != nil { return nil, errors.Trace(err) diff --git a/mysql/util.go b/mysql/util.go index 738ca9a98..c0c9f5452 100644 --- a/mysql/util.go +++ b/mysql/util.go @@ -16,8 +16,8 @@ import ( "time" "github.com/Masterminds/semver" + "github.com/go-mysql-org/go-mysql/utils" "github.com/pingcap/errors" - "github.com/siddontang/go/hack" ) func Pstack() string { @@ -375,7 +375,7 @@ var ( func Escape(sql string) string { dest := make([]byte, 0, 2*len(sql)) - for _, w := range hack.Slice(sql) { + for _, w := range utils.StringToByteSlice(sql) { if c := EncodeMap[w]; c == DONTESCAPE { dest = append(dest, w) } else { diff --git a/replication/json_binary.go b/replication/json_binary.go index 065dd6b2e..34186f09e 100644 --- a/replication/json_binary.go +++ b/replication/json_binary.go @@ -4,9 +4,9 @@ import ( "fmt" "math" + "github.com/go-mysql-org/go-mysql/utils" "github.com/goccy/go-json" "github.com/pingcap/errors" - "github.com/siddontang/go/hack" . "github.com/go-mysql-org/go-mysql/mysql" ) @@ -243,7 +243,7 @@ func (d *jsonBinaryDecoder) decodeObjectOrArray(data []byte, isSmall bool, isObj return nil } - keys[i] = hack.String(data[keyOffset : keyOffset+keyLength]) + keys[i] = utils.ByteSliceToString(data[keyOffset : keyOffset+keyLength]) } } @@ -411,7 +411,7 @@ func (d *jsonBinaryDecoder) decodeString(data []byte) string { data = data[n:] - v := hack.String(data[0:l]) + v := utils.ByteSliceToString(data[0:l]) return v } @@ -439,7 +439,7 @@ func (d *jsonBinaryDecoder) decodeOpaque(data []byte) interface{} { case MYSQL_TYPE_DATE, MYSQL_TYPE_DATETIME, MYSQL_TYPE_TIMESTAMP: return d.decodeDateTime(data) default: - return hack.String(data) + return utils.ByteSliceToString(data) } } diff --git a/replication/row_event.go b/replication/row_event.go index a0d42e8ec..0eebe6914 100644 --- a/replication/row_event.go +++ b/replication/row_event.go @@ -11,9 +11,9 @@ import ( "github.com/pingcap/errors" "github.com/shopspring/decimal" - "github.com/siddontang/go/hack" . "github.com/go-mysql-org/go-mysql/mysql" + "github.com/go-mysql-org/go-mysql/utils" ) var errMissingTableMapEvent = errors.New("invalid table id, no corresponding table map event") @@ -1393,7 +1393,7 @@ func (e *RowsEvent) decodeValue(data []byte, tp byte, meta uint16, isPartial boo var d []byte d, err = e.decodeJsonBinary(data[meta:n]) if err == nil { - v = hack.String(d) + v = utils.ByteSliceToString(d) } } } @@ -1417,11 +1417,11 @@ func decodeString(data []byte, length int) (v string, n int) { length = int(data[0]) n = length + 1 - v = hack.String(data[1:n]) + v = utils.ByteSliceToString(data[1:n]) } else { length = int(binary.LittleEndian.Uint16(data[0:])) n = length + 2 - v = hack.String(data[2:n]) + v = utils.ByteSliceToString(data[2:n]) } return diff --git a/server/command.go b/server/command.go index 3c73697ae..2f4f0b961 100644 --- a/server/command.go +++ b/server/command.go @@ -8,7 +8,7 @@ import ( "github.com/go-mysql-org/go-mysql/mysql" . "github.com/go-mysql-org/go-mysql/mysql" "github.com/go-mysql-org/go-mysql/replication" - "github.com/siddontang/go/hack" + "github.com/go-mysql-org/go-mysql/utils" ) // Handler is what a server needs to implement the client-server protocol @@ -81,7 +81,7 @@ func (c *Conn) dispatch(data []byte) interface{} { c.Conn = nil return noResponse{} case COM_QUERY: - if r, err := c.h.HandleQuery(hack.String(data)); err != nil { + if r, err := c.h.HandleQuery(utils.ByteSliceToString(data)); err != nil { return err } else { return r @@ -89,15 +89,15 @@ func (c *Conn) dispatch(data []byte) interface{} { case COM_PING: return nil case COM_INIT_DB: - if err := c.h.UseDB(hack.String(data)); err != nil { + if err := c.h.UseDB(utils.ByteSliceToString(data)); err != nil { return err } else { return nil } case COM_FIELD_LIST: index := bytes.IndexByte(data, 0x00) - table := hack.String(data[0:index]) - wildcard := hack.String(data[index+1:]) + table := utils.ByteSliceToString(data[0:index]) + wildcard := utils.ByteSliceToString(data[index+1:]) if fs, err := c.h.HandleFieldList(table, wildcard); err != nil { return err @@ -108,7 +108,7 @@ func (c *Conn) dispatch(data []byte) interface{} { c.stmtID++ st := new(Stmt) st.ID = c.stmtID - st.Query = hack.String(data) + st.Query = utils.ByteSliceToString(data) var err error if st.Params, st.Columns, st.Context, err = c.h.HandleStmtPrepare(st.Query); err != nil { return err From 7e624ef0aa4d9cd8eea78925d2d1534e37a739a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20Dub=C3=A9?= Date: Sun, 15 Dec 2024 01:42:18 +0000 Subject: [PATCH 3/3] remove rest of siddontang/go dependencies --- driver/driver_options_test.go | 2 +- go.mod | 1 - go.sum | 2 -- server/conn.go | 12 +++++------- 4 files changed, 6 insertions(+), 11 deletions(-) diff --git a/driver/driver_options_test.go b/driver/driver_options_test.go index d195e22af..3836e61d4 100644 --- a/driver/driver_options_test.go +++ b/driver/driver_options_test.go @@ -16,7 +16,7 @@ import ( "time" "github.com/pingcap/errors" - "github.com/siddontang/go/log" + "github.com/siddontang/go-log/log" "github.com/stretchr/testify/require" "github.com/go-mysql-org/go-mysql/client" diff --git a/go.mod b/go.mod index 2a60d30ac..59658762e 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,6 @@ require ( github.com/pingcap/errors v0.11.5-0.20240311024730-e056997136bb github.com/pingcap/tidb/pkg/parser v0.0.0-20241118164214-4f047be191be github.com/shopspring/decimal v1.2.0 - github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726 github.com/siddontang/go-log v0.0.0-20180807004314-8d05993dda07 github.com/stretchr/testify v1.8.4 ) diff --git a/go.sum b/go.sum index ba30bf4bc..f460625bf 100644 --- a/go.sum +++ b/go.sum @@ -48,8 +48,6 @@ github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjR github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ= github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= -github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726 h1:xT+JlYxNGqyT+XcU8iUrN18JYed2TvG9yN5ULG2jATM= -github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726/go.mod h1:3yhqj7WBBfRhbBlzyOC3gUxftwsU0u8gqevxwIHQpMw= github.com/siddontang/go-log v0.0.0-20180807004314-8d05993dda07 h1:oI+RNwuC9jF2g2lP0u0cVEEZrc/AYBCuFdvwrLWM/6Q= github.com/siddontang/go-log v0.0.0-20180807004314-8d05993dda07/go.mod h1:yFdBgwXP24JziuRl2NMUahT7nGLNOKi1SIiFxMttVD4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= diff --git a/server/conn.go b/server/conn.go index e71d9d42c..7fc80727c 100644 --- a/server/conn.go +++ b/server/conn.go @@ -5,8 +5,6 @@ import ( "net" "sync/atomic" - "github.com/siddontang/go/sync2" - . "github.com/go-mysql-org/go-mysql/mysql" "github.com/go-mysql-org/go-mysql/packet" ) @@ -35,7 +33,7 @@ type Conn struct { stmts map[uint32]*Stmt stmtID uint32 - closed sync2.AtomicBool + closed atomic.Bool } var baseConnID uint32 = 10000 @@ -61,7 +59,7 @@ func NewConn(conn net.Conn, user string, password string, h Handler) (*Conn, err stmts: make(map[uint32]*Stmt), salt: RandomBuf(20), } - c.closed.Set(false) + c.closed.Store(false) if err := c.handshake(); err != nil { c.Close() @@ -89,7 +87,7 @@ func NewCustomizedConn(conn net.Conn, serverConf *Server, p CredentialProvider, stmts: make(map[uint32]*Stmt), salt: RandomBuf(20), } - c.closed.Set(false) + c.closed.Store(false) if err := c.handshake(); err != nil { c.Close() @@ -126,12 +124,12 @@ func (c *Conn) handshake() error { } func (c *Conn) Close() { - c.closed.Set(true) + c.closed.Store(true) c.Conn.Close() } func (c *Conn) Closed() bool { - return c.closed.Get() + return c.closed.Load() } func (c *Conn) GetUser() string {