feat(structure): add stringx type

This commit is contained in:
bandl 2021-09-26 16:47:54 +08:00
parent a8bbbc70a4
commit 8d663fe920
2 changed files with 121 additions and 14 deletions

View File

@ -1,8 +1,10 @@
package stringx
import (
"gitee.com/timedb/wheatCache/pkg/errorx"
"gitee.com/timedb/wheatCache/pkg/proto"
"gitee.com/timedb/wheatCache/pkg/structure"
"strconv"
)
type StringSingle struct {
@ -19,7 +21,7 @@ func (s *StringSingle) SizeByte() int64 {
return int64(s.val.GetLength())
}
// TODO RollBack 事务相关, V2 实现
// RollBack TODO 事务相关, V2 实现
func (s *StringSingle) RollBack() error {
panic("not implemented") // TODO: Implement
}
@ -38,26 +40,90 @@ func (s *StringSingle) Encode() ([]byte, error) {
panic("not implemented") // TODO: Implement
}
func (s *StringSingle) Set(req *proto.SetRequest) (*structure.ResultConn, error) {
return nil, nil
func (s *StringSingle) Set(req *proto.SetRequest) (*proto.SetResponse, error) {
length := s.val.ChangeValueLength(func() {
s.val.InferValue(req.Val)
})
return &proto.SetResponse{
Result: req.Val,
UpdateSize: length,
}, nil
}
func (s *StringSingle) Get(req *proto.GetRequest) (*structure.ResultConn, error) {
panic("not implemented") // TODO: Implement
func (s *StringSingle) Get(req *proto.GetRequest) (*proto.GetResponse, error) {
return &proto.GetResponse{
Result: s.val.ToString(),
UpdateSize: 0,
}, nil
}
func (s *StringSingle) Add(req *proto.AddRequest) (*structure.ResultConn, error) {
panic("not implemented") // TODO: Implement
func updateValueNotString(s *StringSingle, val int32) (string, int64, error) {
switch s.val.GetDynamicType() {
case structure.DynamicNull:
length := s.val.ChangeValueLength(func() {
s.val.SetInt(int64(val))
})
return strconv.Itoa(int(val)), length, nil
case structure.DynamicFloat:
f, err := s.val.ToFloat64()
if err != nil {
return "", 0, err
}
s.val.SetFloat64(f + float64(val))
return strconv.FormatFloat(f+1, 'f', 2, 64), 0, nil
case structure.DynamicInt:
i, err := s.val.ToInt()
if err != nil {
return "", 0, err
}
s.val.SetInt(int64(val) + i)
return strconv.Itoa(int(i + int64(val))), 0, nil
default:
return "", 0, errorx.New("string cannot perform add operations")
}
}
func (s *StringSingle) Reduce(req *proto.ReduceRequest) (*structure.ResultConn, error) {
panic("not implemented") // TODO: Implement
func (s *StringSingle) Add(req *proto.AddRequest) (*proto.AddResponse, error) {
result, length, err := updateValueNotString(s, req.Renewal)
if err != nil {
return nil, err
}
return &proto.AddResponse{
UpdateSize: length,
Result: result,
}, nil
}
func (s *StringSingle) Setbit(req *proto.SetbitRequest) (*structure.ResultConn, error) {
panic("not implemented") // TODO: Implement
func (s *StringSingle) Reduce(req *proto.ReduceRequest) (*proto.ReduceResponse, error) {
result, length, err := updateValueNotString(s, req.Renewal*-1)
if err != nil {
return nil, err
}
return &proto.ReduceResponse{
UpdateSize: length,
Result: result,
}, nil
}
func (s *StringSingle) Getbit(req *proto.GetbitRequest) (*structure.ResultConn, error) {
panic("not implemented") // TODO: Implement
func (s *StringSingle) Setbit(req *proto.SetbitRequest) (*proto.SetbitResponse, error) {
length := s.val.ChangeValueLength(func() {
s.val.SetByte(int(req.Offer), req.Val)
})
return &proto.SetbitResponse{
UpdateSize: length,
}, nil
}
func (s *StringSingle) Getbit(req *proto.GetbitRequest) (*proto.GetbitResponse, error) {
b, err := s.val.GetByte(int(req.Offer))
if err != nil {
return nil, err
}
return &proto.GetbitResponse{
Val: b,
}, nil
}

View File

@ -37,6 +37,7 @@ func (v *Value) SetString(str string) {
if len(v.val) >= len(str) {
copy(v.val, str)
v.length = len(str)
v.val = v.val[:v.length]
return
}
@ -54,6 +55,18 @@ func (v *Value) SetString(str string) {
}
func (v *Value) ToString() string {
switch v.onType {
case DynamicNull:
return ""
case DynamicString:
return string(v.val[:v.length])
case DynamicInt:
i, _ := v.ToInt()
return strconv.FormatInt(i, 10)
case DynamicFloat:
f, _ := v.ToFloat64()
return strconv.FormatFloat(f, 'f', 2, 64)
}
return string(v.val[:v.length])
}
@ -84,6 +97,7 @@ func (v *Value) SetFloat64(f float64) {
bits := math.Float64bits(f)
v.length = 8
binary.LittleEndian.PutUint64(v.val[:v.length], bits)
v.val = v.val[:v.length]
v.onType = DynamicFloat
}
@ -113,9 +127,36 @@ func (v *Value) InferValue(str string) {
v.SetString(str)
}
// ChangeValueLength 根据类型推断 change 的大小
// ChangeValueLength 根据类型推断 change 的大小, 只用于 Set 操作不发生错误
func (v *Value) ChangeValueLength(f func()) int64 {
startLen := v.GetLength()
f()
return int64(v.GetLength() - startLen)
}
func (v *Value) SetByte(offset int, val bool) {
v.onType = DynamicNull // 位图使用无类型
b := byte(0)
if val {
b = byte(1)
}
if v.length >= offset {
v.val[offset] = b
return
}
newByte := make([]byte, offset+1)
newByte[offset] = b
copy(newByte, v.val[:v.length])
v.val = newByte
v.length = len(newByte)
}
func (v *Value) GetByte(offset int) (bool, error) {
if v.length >= offset {
return v.val[offset] == byte(1), nil
}
return false, errorx.New("the maximum length is exceeded")
}