Merge pull request #138 from go-redis/fix/unsafe-conv

Use unsafe for bytes->string conversion.
This commit is contained in:
Vladimir Mihailenco 2015-07-25 09:29:23 +03:00
commit fc28d0fa24
3 changed files with 31 additions and 18 deletions

View File

@ -400,7 +400,7 @@ func (cmd *StringCmd) reset() {
} }
func (cmd *StringCmd) Val() string { func (cmd *StringCmd) Val() string {
return string(cmd.val) return bytesToString(cmd.val)
} }
func (cmd *StringCmd) Result() (string, error) { func (cmd *StringCmd) Result() (string, error) {
@ -486,7 +486,8 @@ func (cmd *FloatCmd) parseReply(rd *bufio.Reader) error {
cmd.err = err cmd.err = err
return err return err
} }
cmd.val, cmd.err = strconv.ParseFloat(string(v.([]byte)), 64) b := v.([]byte)
cmd.val, cmd.err = strconv.ParseFloat(bytesToString(b), 64)
return cmd.err return cmd.err
} }

View File

@ -118,80 +118,80 @@ func scan(b []byte, val interface{}) error {
case nil: case nil:
return errorf("redis: Scan(nil)") return errorf("redis: Scan(nil)")
case *string: case *string:
*v = string(b) *v = bytesToString(b)
return nil return nil
case *[]byte: case *[]byte:
*v = b *v = b
return nil return nil
case *int: case *int:
var err error var err error
*v, err = strconv.Atoi(string(b)) *v, err = strconv.Atoi(bytesToString(b))
return err return err
case *int8: case *int8:
n, err := strconv.ParseInt(string(b), 10, 8) n, err := strconv.ParseInt(bytesToString(b), 10, 8)
if err != nil { if err != nil {
return err return err
} }
*v = int8(n) *v = int8(n)
return nil return nil
case *int16: case *int16:
n, err := strconv.ParseInt(string(b), 10, 16) n, err := strconv.ParseInt(bytesToString(b), 10, 16)
if err != nil { if err != nil {
return err return err
} }
*v = int16(n) *v = int16(n)
return nil return nil
case *int32: case *int32:
n, err := strconv.ParseInt(string(b), 10, 16) n, err := strconv.ParseInt(bytesToString(b), 10, 16)
if err != nil { if err != nil {
return err return err
} }
*v = int32(n) *v = int32(n)
return nil return nil
case *int64: case *int64:
n, err := strconv.ParseInt(string(b), 10, 64) n, err := strconv.ParseInt(bytesToString(b), 10, 64)
if err != nil { if err != nil {
return err return err
} }
*v = n *v = n
return nil return nil
case *uint: case *uint:
n, err := strconv.ParseUint(string(b), 10, 64) n, err := strconv.ParseUint(bytesToString(b), 10, 64)
if err != nil { if err != nil {
return err return err
} }
*v = uint(n) *v = uint(n)
return nil return nil
case *uint8: case *uint8:
n, err := strconv.ParseUint(string(b), 10, 8) n, err := strconv.ParseUint(bytesToString(b), 10, 8)
if err != nil { if err != nil {
return err return err
} }
*v = uint8(n) *v = uint8(n)
return nil return nil
case *uint16: case *uint16:
n, err := strconv.ParseUint(string(b), 10, 16) n, err := strconv.ParseUint(bytesToString(b), 10, 16)
if err != nil { if err != nil {
return err return err
} }
*v = uint16(n) *v = uint16(n)
return nil return nil
case *uint32: case *uint32:
n, err := strconv.ParseUint(string(b), 10, 32) n, err := strconv.ParseUint(bytesToString(b), 10, 32)
if err != nil { if err != nil {
return err return err
} }
*v = uint32(n) *v = uint32(n)
return nil return nil
case *uint64: case *uint64:
n, err := strconv.ParseUint(string(b), 10, 64) n, err := strconv.ParseUint(bytesToString(b), 10, 64)
if err != nil { if err != nil {
return err return err
} }
*v = n *v = n
return nil return nil
case *float32: case *float32:
n, err := strconv.ParseFloat(string(b), 32) n, err := strconv.ParseFloat(bytesToString(b), 32)
if err != nil { if err != nil {
return err return err
} }
@ -199,7 +199,7 @@ func scan(b []byte, val interface{}) error {
return err return err
case *float64: case *float64:
var err error var err error
*v, err = strconv.ParseFloat(string(b), 64) *v, err = strconv.ParseFloat(bytesToString(b), 64)
return err return err
case *bool: case *bool:
*v = len(b) == 1 && b[0] == '1' *v = len(b) == 1 && b[0] == '1'
@ -305,7 +305,7 @@ func parseReply(rd *bufio.Reader, p multiBulkParser) (interface{}, error) {
case '+': case '+':
return line[1:], nil return line[1:], nil
case ':': case ':':
v, err := strconv.ParseInt(string(line[1:]), 10, 64) v, err := strconv.ParseInt(bytesToString(line[1:]), 10, 64)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -330,7 +330,7 @@ func parseReply(rd *bufio.Reader, p multiBulkParser) (interface{}, error) {
return nil, Nil return nil, Nil
} }
repliesNum, err := strconv.ParseInt(string(line[1:]), 10, 64) repliesNum, err := strconv.ParseInt(bytesToString(line[1:]), 10, 64)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -472,7 +472,7 @@ func parseZSlice(rd *bufio.Reader, n int64) (interface{}, error) {
if !ok { if !ok {
return nil, fmt.Errorf("got %T, expected string", scoreiface) return nil, fmt.Errorf("got %T, expected string", scoreiface)
} }
score, err := strconv.ParseFloat(string(scoreb), 64) score, err := strconv.ParseFloat(bytesToString(scoreb), 64)
if err != nil { if err != nil {
return nil, err return nil, err
} }

12
unsafe.go Normal file
View File

@ -0,0 +1,12 @@
package redis
import (
"reflect"
"unsafe"
)
func bytesToString(b []byte) string {
bytesHeader := (*reflect.SliceHeader)(unsafe.Pointer(&b))
strHeader := reflect.StringHeader{bytesHeader.Data, bytesHeader.Len}
return *(*string)(unsafe.Pointer(&strHeader))
}