Skip to content

Commit

Permalink
Merge pull request #315 from illia-li/il/fix/marshal/optimization_sma…
Browse files Browse the repository at this point in the history
…llint

Fix marshal `smallint` - optimization
  • Loading branch information
dkropachev authored Oct 31, 2024
2 parents caa589b + 07bd366 commit fc1b783
Show file tree
Hide file tree
Showing 2 changed files with 365 additions and 86 deletions.
66 changes: 54 additions & 12 deletions serialization/smallint/marshal_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ var (
)

func EncInt8(v int8) ([]byte, error) {
return encInt16(int16(v)), nil
if v < 0 {
return []byte{255, byte(v)}, nil
}
return []byte{0, byte(v)}, nil
}

func EncInt8R(v *int8) ([]byte, error) {
Expand Down Expand Up @@ -53,7 +56,7 @@ func EncInt64(v int64) ([]byte, error) {
if v > math.MaxInt16 || v < math.MinInt16 {
return nil, fmt.Errorf("failed to marshal smallint: value %#v out of range", v)
}
return []byte{byte(v >> 8), byte(v)}, nil
return encInt64(v), nil
}

func EncInt64R(v *int64) ([]byte, error) {
Expand Down Expand Up @@ -117,7 +120,7 @@ func EncUint64(v uint64) ([]byte, error) {
if v > math.MaxUint16 {
return nil, fmt.Errorf("failed to marshal smallint: value %#v out of range", v)
}
return []byte{byte(v >> 8), byte(v)}, nil
return encUint64(v), nil
}

func EncUint64R(v *uint64) ([]byte, error) {
Expand Down Expand Up @@ -145,15 +148,17 @@ func EncBigInt(v big.Int) ([]byte, error) {
if v.Cmp(maxBigInt) == 1 || v.Cmp(minBigInt) == -1 {
return nil, fmt.Errorf("failed to marshal smallint: value (%T)(%s) out of range", v, v.String())
}
iv := v.Int64()
return []byte{byte(iv >> 8), byte(iv)}, nil
return encInt64(v.Int64()), nil
}

func EncBigIntR(v *big.Int) ([]byte, error) {
if v == nil {
return nil, nil
}
return EncBigInt(*v)
if v.Cmp(maxBigInt) == 1 || v.Cmp(minBigInt) == -1 {
return nil, fmt.Errorf("failed to marshal smallint: value (%T)(%s) out of range", v, v.String())
}
return encInt64(v.Int64()), nil
}

func EncString(v string) ([]byte, error) {
Expand All @@ -165,7 +170,7 @@ func EncString(v string) ([]byte, error) {
if err != nil {
return nil, fmt.Errorf("failed to marshal smallint: can not marshal (%T)(%[1]v) %s", v, err)
}
return []byte{byte(n >> 8), byte(n)}, nil
return encInt64(n), nil
}

func EncStringR(v *string) ([]byte, error) {
Expand All @@ -177,12 +182,41 @@ func EncStringR(v *string) ([]byte, error) {

func EncReflect(v reflect.Value) ([]byte, error) {
switch v.Type().Kind() {
case reflect.Int, reflect.Int64, reflect.Int32, reflect.Int16, reflect.Int8:
return EncInt64(v.Int())
case reflect.Uint, reflect.Uint64, reflect.Uint32, reflect.Uint16, reflect.Uint8:
return EncUint64(v.Uint())
case reflect.Int8:
val := v.Int()
if val < 0 {
return []byte{255, byte(val)}, nil
}
return []byte{0, byte(val)}, nil
case reflect.Int16:
return encInt64(v.Int()), nil
case reflect.Int, reflect.Int64, reflect.Int32:
val := v.Int()
if val > math.MaxInt16 || val < math.MinInt16 {
return nil, fmt.Errorf("failed to marshal smallint: custom type value (%T)(%[1]v) out of range", v.Interface())
}
return encInt64(val), nil
case reflect.Uint8:
return []byte{0, byte(v.Uint())}, nil
case reflect.Uint16:
return encUint64(v.Uint()), nil
case reflect.Uint, reflect.Uint64, reflect.Uint32:
val := v.Uint()
if val > math.MaxUint16 {
return nil, fmt.Errorf("failed to marshal smallint: custom type value (%T)(%[1]v) out of range", v.Interface())
}
return encUint64(val), nil
case reflect.String:
return EncString(v.String())
val := v.String()
if val == "" {
return nil, nil
}

n, err := strconv.ParseInt(val, 10, 16)
if err != nil {
return nil, fmt.Errorf("failed to marshal smallint: can not marshal (%T)(%[1]v), %s", v.Interface(), err)
}
return encInt64(n), nil
default:
return nil, fmt.Errorf("failed to marshal smallint: unsupported value type (%T)(%[1]v)", v.Interface())
}
Expand All @@ -198,3 +232,11 @@ func EncReflectR(v reflect.Value) ([]byte, error) {
func encInt16(v int16) []byte {
return []byte{byte(v >> 8), byte(v)}
}

func encInt64(v int64) []byte {
return []byte{byte(v >> 8), byte(v)}
}

func encUint64(v uint64) []byte {
return []byte{byte(v >> 8), byte(v)}
}
Loading

0 comments on commit fc1b783

Please sign in to comment.