From fc47f3eca0e21eea8719d7af855eb2205cc5ca6b Mon Sep 17 00:00:00 2001 From: bandl <1658002533@qq.com> Date: Fri, 24 Sep 2021 22:48:08 +0800 Subject: [PATCH] feat(structure): add base value --- pkg/errorx/err.go | 4 +- pkg/structure/define.go | 26 ++++++++ pkg/structure/stringx/option.go | 1 - pkg/structure/value.go | 115 ++++++++++++++++++++++++++++++++ 4 files changed, 143 insertions(+), 3 deletions(-) delete mode 100644 pkg/structure/stringx/option.go create mode 100644 pkg/structure/value.go diff --git a/pkg/errorx/err.go b/pkg/errorx/err.go index 364cb52..efb41f3 100644 --- a/pkg/errorx/err.go +++ b/pkg/errorx/err.go @@ -6,7 +6,7 @@ import ( ) // New TODO 添加链路追踪等 @bandl @lgq -func New(msg string, opt ...interface{}) error { - msg = fmt.Sprintf(msg, opt...) +func New(msg string, format ...interface{}) error { + msg = fmt.Sprintf(msg, format...) return errors.New(msg) } diff --git a/pkg/structure/define.go b/pkg/structure/define.go index d0d30e7..39f72d1 100644 --- a/pkg/structure/define.go +++ b/pkg/structure/define.go @@ -1,3 +1,29 @@ package structure +const ( + defaultLen = 32 // 默认创建的 value 大小 +) +type DynamicType int8 + +const ( + DynamicNull = DynamicType(iota) + DynamicInt + DynamicFloat + DynamicString +) + +type ResultConn struct { + Result []string + UpdateSize int64 // 操作以后发生变更的大小, 负数表示减小 +} + +func NewResult(s ...string) *ResultConn { + res := make([]string, len(s)) + + res = append(res, s...) + + return &ResultConn{ + Result: res, + } +} diff --git a/pkg/structure/stringx/option.go b/pkg/structure/stringx/option.go deleted file mode 100644 index 653ddc2..0000000 --- a/pkg/structure/stringx/option.go +++ /dev/null @@ -1 +0,0 @@ -package stringx diff --git a/pkg/structure/value.go b/pkg/structure/value.go new file mode 100644 index 0000000..b440db1 --- /dev/null +++ b/pkg/structure/value.go @@ -0,0 +1,115 @@ +package structure + +import ( + "bytes" + "encoding/binary" + "math" + "strconv" + + "gitee.com/timedb/wheatCache/pkg/errorx" +) + +// Value 提供一个基础的 动态类型 + +type Value struct { + val []byte + length int + onType DynamicType +} + +func NewValue() *Value { + return &Value{ + val: make([]byte, defaultLen), + length: 0, + onType: DynamicNull, + } +} + +func (v *Value) GetLength() int { + return v.length +} + +func (v *Value) GetDynamicType() DynamicType { + return v.onType +} + +func (v *Value) SetString(str string) { + v.onType = DynamicString + if len(v.val) >= len(str) { + copy(v.val, str) + v.length = len(str) + return + } + + // 超过 cap + if len(str) > cap(v.val) { + v.val = make([]byte, len(str)) + copy(v.val, str) + v.length = len(str) + return + } + + // 在 cap 以内 + copy(v.val, str[:v.length]) + v.val = append(v.val, str[v.length:]...) +} + +func (v *Value) ToString() string { + return string(v.val[:v.length]) +} + +// SetInt 使用高位存储 +func (v *Value) SetInt(i int64) { + byteBuf := bytes.NewBuffer([]byte{}) + binary.Write(byteBuf, binary.BigEndian, i) + v.val = byteBuf.Bytes() + v.length = len(v.val) + v.onType = DynamicInt +} + +func (v *Value) ToInt() (reI int64, err error) { + if v.onType != DynamicInt { + return 0, errorx.New("can only be resolved from dynamic int") + } + + byteBuff := bytes.NewBuffer(v.val) + err = binary.Read(byteBuff, binary.BigEndian, &reI) + if err != nil { + return 0, err + } + + return reI, nil +} + +func (v *Value) SetFloat64(f float64) { + bits := math.Float64bits(f) + v.length = 8 + binary.LittleEndian.PutUint64(v.val[:v.length], bits) + v.onType = DynamicFloat +} + +func (v *Value) ToFloat64() (float64, error) { + if v.onType != DynamicFloat { + return 0, errorx.New("can only be resolved from dynamic float") + } + + bits := binary.LittleEndian.Uint64(v.val[:v.length]) + return math.Float64frombits(bits), nil +} + +// InferValue 通过字符串来自动推导类型,性能较低 +func (v *Value) InferValue(str string) { + rInt, err := strconv.Atoi(str) + if err == nil { + v.SetInt(int64(rInt)) + return + } + + rf, err := strconv.ParseFloat(str, 64) + if err == nil { + v.SetFloat64(rf) + return + } + + v.SetString(str) +}