forked from p93542168/wheat-cache
feat(structure): add stringx type
This commit is contained in:
parent
a8bbbc70a4
commit
8d663fe920
|
@ -1,8 +1,10 @@
|
||||||
package stringx
|
package stringx
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"gitee.com/timedb/wheatCache/pkg/errorx"
|
||||||
"gitee.com/timedb/wheatCache/pkg/proto"
|
"gitee.com/timedb/wheatCache/pkg/proto"
|
||||||
"gitee.com/timedb/wheatCache/pkg/structure"
|
"gitee.com/timedb/wheatCache/pkg/structure"
|
||||||
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
type StringSingle struct {
|
type StringSingle struct {
|
||||||
|
@ -19,7 +21,7 @@ func (s *StringSingle) SizeByte() int64 {
|
||||||
return int64(s.val.GetLength())
|
return int64(s.val.GetLength())
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO RollBack 事务相关, V2 实现
|
// RollBack TODO 事务相关, V2 实现
|
||||||
func (s *StringSingle) RollBack() error {
|
func (s *StringSingle) RollBack() error {
|
||||||
panic("not implemented") // TODO: Implement
|
panic("not implemented") // TODO: Implement
|
||||||
}
|
}
|
||||||
|
@ -38,26 +40,90 @@ func (s *StringSingle) Encode() ([]byte, error) {
|
||||||
panic("not implemented") // TODO: Implement
|
panic("not implemented") // TODO: Implement
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *StringSingle) Set(req *proto.SetRequest) (*structure.ResultConn, error) {
|
func (s *StringSingle) Set(req *proto.SetRequest) (*proto.SetResponse, error) {
|
||||||
return nil, nil
|
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) {
|
func (s *StringSingle) Get(req *proto.GetRequest) (*proto.GetResponse, error) {
|
||||||
panic("not implemented") // TODO: Implement
|
return &proto.GetResponse{
|
||||||
|
Result: s.val.ToString(),
|
||||||
|
UpdateSize: 0,
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *StringSingle) Add(req *proto.AddRequest) (*structure.ResultConn, error) {
|
func updateValueNotString(s *StringSingle, val int32) (string, int64, error) {
|
||||||
panic("not implemented") // TODO: Implement
|
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) {
|
func (s *StringSingle) Add(req *proto.AddRequest) (*proto.AddResponse, error) {
|
||||||
panic("not implemented") // TODO: Implement
|
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) {
|
func (s *StringSingle) Reduce(req *proto.ReduceRequest) (*proto.ReduceResponse, error) {
|
||||||
panic("not implemented") // TODO: Implement
|
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) {
|
func (s *StringSingle) Setbit(req *proto.SetbitRequest) (*proto.SetbitResponse, error) {
|
||||||
panic("not implemented") // TODO: Implement
|
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
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,7 @@ func (v *Value) SetString(str string) {
|
||||||
if len(v.val) >= len(str) {
|
if len(v.val) >= len(str) {
|
||||||
copy(v.val, str)
|
copy(v.val, str)
|
||||||
v.length = len(str)
|
v.length = len(str)
|
||||||
|
v.val = v.val[:v.length]
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,6 +55,18 @@ func (v *Value) SetString(str string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Value) ToString() 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])
|
return string(v.val[:v.length])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,6 +97,7 @@ func (v *Value) SetFloat64(f float64) {
|
||||||
bits := math.Float64bits(f)
|
bits := math.Float64bits(f)
|
||||||
v.length = 8
|
v.length = 8
|
||||||
binary.LittleEndian.PutUint64(v.val[:v.length], bits)
|
binary.LittleEndian.PutUint64(v.val[:v.length], bits)
|
||||||
|
v.val = v.val[:v.length]
|
||||||
v.onType = DynamicFloat
|
v.onType = DynamicFloat
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,9 +127,36 @@ func (v *Value) InferValue(str string) {
|
||||||
v.SetString(str)
|
v.SetString(str)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ChangeValueLength 根据类型推断 change 的大小
|
// ChangeValueLength 根据类型推断 change 的大小, 只用于 Set 操作不发生错误
|
||||||
func (v *Value) ChangeValueLength(f func()) int64 {
|
func (v *Value) ChangeValueLength(f func()) int64 {
|
||||||
startLen := v.GetLength()
|
startLen := v.GetLength()
|
||||||
f()
|
f()
|
||||||
return int64(v.GetLength() - startLen)
|
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")
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue