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 1/3] 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)
+}

From f0835b334425afafc5d9308bf93a3c2cb58badfe Mon Sep 17 00:00:00 2001
From: bandl <1658002533@qq.com>
Date: Fri, 24 Sep 2021 22:48:41 +0800
Subject: [PATCH 2/3] test(structure): test base value

---
 pkg/structure/value_test.go | 86 +++++++++++++++++++++++++++++++++++++
 1 file changed, 86 insertions(+)
 create mode 100644 pkg/structure/value_test.go

diff --git a/pkg/structure/value_test.go b/pkg/structure/value_test.go
new file mode 100644
index 0000000..4e660e6
--- /dev/null
+++ b/pkg/structure/value_test.go
@@ -0,0 +1,86 @@
+package structure
+
+import (
+	"strconv"
+	"testing"
+
+	"github.com/stretchr/testify/require"
+)
+
+func TestValue_SetString(t *testing.T) {
+	value := Value{
+		val: make([]byte, 32, 64),
+	}
+	testStr := "awjkbk沙袋jdawd"
+	value.SetString(testStr)
+
+	require.Equal(t, testStr, value.ToString())
+}
+
+func TestValue_GetString(t *testing.T) {
+	value := NewValue()
+	str := ""
+	for i := 0; i < 100; i++ {
+		str += strconv.Itoa(i)
+	}
+	value.SetString(str)
+	require.Equal(t, value.ToString(), str)
+
+	value.SetString("aw1")
+	require.Equal(t, value.ToString(), "aw1")
+}
+
+func Test_IntToBytes(t *testing.T) {
+	value := NewValue()
+	value.SetInt(2<<62 - 1)
+	require.Equal(t, value.GetLength(), 8)
+}
+
+func TestValue_ToInt(t *testing.T) {
+	value := NewValue()
+	value.SetInt(90)
+	rel, err := value.ToInt()
+	require.NoError(t, err)
+	require.Equal(t, rel, int64(90))
+	value.SetString("abc")
+	require.Equal(t, value.ToString(), "abc")
+	_, err = value.ToInt()
+	require.Error(t, err)
+}
+
+func TestValue_SetFloat64(t *testing.T) {
+	value := NewValue()
+	value.SetFloat64(2.35)
+	f, err := value.ToFloat64()
+	require.NoError(t, err)
+	require.Equal(t, f, 2.35)
+
+	value.SetInt(-10)
+	rel, err := value.ToInt()
+	require.NoError(t, err)
+	require.Equal(t, rel, int64(-10))
+
+	value.SetFloat64(-2.35)
+	f, err = value.ToFloat64()
+	require.NoError(t, err)
+	require.Equal(t, f, -2.35)
+}
+
+func TestValue_InferValue(t *testing.T) {
+	value := NewValue()
+	value.InferValue("hello world")
+	require.Equal(t, value.GetDynamicType(), DynamicString)
+	require.Equal(t, value.ToString(), "hello world")
+
+	value.InferValue("1")
+	require.Equal(t, value.GetDynamicType(), DynamicInt)
+	i, err := value.ToInt()
+	require.NoError(t, err)
+	require.Equal(t, i, int64(1))
+
+	value.InferValue("-1.2")
+	require.Equal(t, value.GetDynamicType(), DynamicFloat)
+	f, err := value.ToFloat64()
+	require.NoError(t, err)
+	require.Equal(t, f, -1.2)
+}

From ec9d3a1a712c7828fb942750666d301fda5247d9 Mon Sep 17 00:00:00 2001
From: bandl <1658002533@qq.com>
Date: Sat, 25 Sep 2021 14:52:42 +0800
Subject: [PATCH 3/3] chore(structure): update model

---
 pkg/lru/define.go                         |  4 +-
 pkg/proto/stringx.pb.go                   | 95 ++++++++++++++++++-----
 pkg/structure/generate/interface.template |  2 +-
 pkg/structure/generate/storage.template   | 45 +++++++++++
 pkg/structure/interface.gen.go            | 12 +--
 pkg/structure/stringx/string.go           | 62 +++++++++------
 pkg/structure/stringx/string_test.go      | 19 +++++
 protobuf/stringx.proto                    |  7 ++
 8 files changed, 194 insertions(+), 52 deletions(-)
 create mode 100644 pkg/structure/generate/storage.template
 create mode 100644 pkg/structure/stringx/string_test.go

diff --git a/pkg/lru/define.go b/pkg/lru/define.go
index 2eb64ef..2f90447 100644
--- a/pkg/lru/define.go
+++ b/pkg/lru/define.go
@@ -1,3 +1,5 @@
 package lru
 
-// define
+import "gitee.com/timedb/wheatCache/pkg/structure"
+
+type SingleWorkFunc func() (*structure.ResultConn, error)
diff --git a/pkg/proto/stringx.pb.go b/pkg/proto/stringx.pb.go
index 58c2e40..07b5ab7 100644
--- a/pkg/proto/stringx.pb.go
+++ b/pkg/proto/stringx.pb.go
@@ -26,6 +26,7 @@ type SetRequest struct {
 	unknownFields protoimpl.UnknownFields
 
 	Key *BaseKey `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
+	Val string   `protobuf:"bytes,2,opt,name=val,proto3" json:"val,omitempty"`
 }
 
 func (x *SetRequest) Reset() {
@@ -67,6 +68,13 @@ func (x *SetRequest) GetKey() *BaseKey {
 	return nil
 }
 
+func (x *SetRequest) GetVal() string {
+	if x != nil {
+		return x.Val
+	}
+	return ""
+}
+
 type GetRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
@@ -120,6 +128,8 @@ type AddRequest struct {
 	unknownFields protoimpl.UnknownFields
 
 	Key *BaseKey `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
+	// 自动增加
+	Raise int32 `protobuf:"varint,2,opt,name=raise,proto3" json:"raise,omitempty"`
 }
 
 func (x *AddRequest) Reset() {
@@ -161,12 +171,20 @@ func (x *AddRequest) GetKey() *BaseKey {
 	return nil
 }
 
+func (x *AddRequest) GetRaise() int32 {
+	if x != nil {
+		return x.Raise
+	}
+	return 0
+}
+
 type ReduceRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
 	Key *BaseKey `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
+	Cut int32    `protobuf:"varint,2,opt,name=cut,proto3" json:"cut,omitempty"`
 }
 
 func (x *ReduceRequest) Reset() {
@@ -208,12 +226,21 @@ func (x *ReduceRequest) GetKey() *BaseKey {
 	return nil
 }
 
+func (x *ReduceRequest) GetCut() int32 {
+	if x != nil {
+		return x.Cut
+	}
+	return 0
+}
+
 type SetbitRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Key *BaseKey `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
+	Key    *BaseKey `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
+	Office int32    `protobuf:"varint,2,opt,name=office,proto3" json:"office,omitempty"`
+	Val    bool     `protobuf:"varint,3,opt,name=val,proto3" json:"val,omitempty"`
 }
 
 func (x *SetbitRequest) Reset() {
@@ -255,12 +282,27 @@ func (x *SetbitRequest) GetKey() *BaseKey {
 	return nil
 }
 
+func (x *SetbitRequest) GetOffice() int32 {
+	if x != nil {
+		return x.Office
+	}
+	return 0
+}
+
+func (x *SetbitRequest) GetVal() bool {
+	if x != nil {
+		return x.Val
+	}
+	return false
+}
+
 type GetbitRequest struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	Key *BaseKey `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
+	Key    *BaseKey `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
+	Office int32    `protobuf:"varint,2,opt,name=office,proto3" json:"office,omitempty"`
 }
 
 func (x *GetbitRequest) Reset() {
@@ -302,29 +344,44 @@ func (x *GetbitRequest) GetKey() *BaseKey {
 	return nil
 }
 
+func (x *GetbitRequest) GetOffice() int32 {
+	if x != nil {
+		return x.Office
+	}
+	return 0
+}
+
 var File_stringx_proto protoreflect.FileDescriptor
 
 var file_stringx_proto_rawDesc = []byte{
 	0x0a, 0x0d, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x78, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a,
-	0x0a, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x28, 0x0a, 0x0a, 0x53,
+	0x0a, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x3a, 0x0a, 0x0a, 0x53,
 	0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x03, 0x6b, 0x65, 0x79,
 	0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x42, 0x61, 0x73, 0x65, 0x4b, 0x65, 0x79,
-	0x52, 0x03, 0x6b, 0x65, 0x79, 0x22, 0x28, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75,
-	0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
-	0x32, 0x08, 0x2e, 0x42, 0x61, 0x73, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x22,
-	0x28, 0x0a, 0x0a, 0x41, 0x64, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a,
-	0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x42, 0x61, 0x73,
-	0x65, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x22, 0x2b, 0x0a, 0x0d, 0x52, 0x65, 0x64,
-	0x75, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x03, 0x6b, 0x65,
-	0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x42, 0x61, 0x73, 0x65, 0x4b, 0x65,
-	0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x22, 0x2b, 0x0a, 0x0d, 0x53, 0x65, 0x74, 0x62, 0x69, 0x74,
-	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01,
-	0x20, 0x01, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x42, 0x61, 0x73, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x03,
-	0x6b, 0x65, 0x79, 0x22, 0x2b, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x62, 0x69, 0x74, 0x52, 0x65, 0x71,
-	0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28,
-	0x0b, 0x32, 0x08, 0x2e, 0x42, 0x61, 0x73, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79,
-	0x42, 0x0b, 0x5a, 0x09, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70,
-	0x72, 0x6f, 0x74, 0x6f, 0x33,
+	0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x76, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x03, 0x76, 0x61, 0x6c, 0x22, 0x28, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x52, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x0b, 0x32, 0x08, 0x2e, 0x42, 0x61, 0x73, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65,
+	0x79, 0x22, 0x3e, 0x0a, 0x0a, 0x41, 0x64, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
+	0x1a, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x42,
+	0x61, 0x73, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x72,
+	0x61, 0x69, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x72, 0x61, 0x69, 0x73,
+	0x65, 0x22, 0x3d, 0x0a, 0x0d, 0x52, 0x65, 0x64, 0x75, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65,
+	0x73, 0x74, 0x12, 0x1a, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
+	0x08, 0x2e, 0x42, 0x61, 0x73, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x10,
+	0x0a, 0x03, 0x63, 0x75, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x63, 0x75, 0x74,
+	0x22, 0x55, 0x0a, 0x0d, 0x53, 0x65, 0x74, 0x62, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+	0x74, 0x12, 0x1a, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x08,
+	0x2e, 0x42, 0x61, 0x73, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x16, 0x0a,
+	0x06, 0x6f, 0x66, 0x66, 0x69, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x6f,
+	0x66, 0x66, 0x69, 0x63, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x76, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01,
+	0x28, 0x08, 0x52, 0x03, 0x76, 0x61, 0x6c, 0x22, 0x43, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x62, 0x69,
+	0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18,
+	0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x42, 0x61, 0x73, 0x65, 0x4b, 0x65, 0x79, 0x52,
+	0x03, 0x6b, 0x65, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x69, 0x63, 0x65, 0x18, 0x02,
+	0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x69, 0x63, 0x65, 0x42, 0x0b, 0x5a, 0x09,
+	0x70, 0x6b, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x33,
 }
 
 var (
diff --git a/pkg/structure/generate/interface.template b/pkg/structure/generate/interface.template
index 97c0780..e82e2de 100644
--- a/pkg/structure/generate/interface.template
+++ b/pkg/structure/generate/interface.template
@@ -22,7 +22,7 @@ type KeyBaseInterface interface {
 type {{key}}Interface interface{
     KeyBaseInterface
     {% for val in value -%}
-    {{val}}(*proto.{{val}}Request) ([]string, error)
+    {{val}}(*proto.{{val}}Request) (*ResultConn, error)
     {% endfor %}
 }
     {% endfor -%}
diff --git a/pkg/structure/generate/storage.template b/pkg/structure/generate/storage.template
new file mode 100644
index 0000000..b9c6d7a
--- /dev/null
+++ b/pkg/structure/generate/storage.template
@@ -0,0 +1,45 @@
+// TODO 添加 storage server 模板
+package server
+
+import (
+	context "context"
+	"gitee.com/timedb/wheatCache/pkg/proto"
+)
+
+type server struct {
+}
+
+func NewServer() proto.CommServerServer {
+	ser := &server{}
+	return ser
+}
+
+func (s *server) Get(
+	cxt context.Context,
+	req *proto.GetRequest,
+) (*proto.CommendResponse, error) {
+	panic("implement me")
+}
+
+func (s *server) Set(
+	ctx context.Context,
+	req *proto.SetRequest,
+) (*proto.CommendResponse, error) {
+	panic("implement me")
+}
+
+func (s *server) Add(ctx context.Context, request *proto.AddRequest) (*proto.CommendResponse, error) {
+	panic("implement me")
+}
+
+func (s *server) Reduce(ctx context.Context, request *proto.ReduceRequest) (*proto.CommendResponse, error) {
+	panic("implement me")
+}
+
+func (s *server) Setbit(ctx context.Context, request *proto.SetbitRequest) (*proto.CommendResponse, error) {
+	panic("implement me")
+}
+
+func (s *server) Getbit(ctx context.Context, request *proto.GetbitRequest) (*proto.CommendResponse, error) {
+	panic("implement me")
+}
diff --git a/pkg/structure/interface.gen.go b/pkg/structure/interface.gen.go
index ba53360..b25cbe1 100644
--- a/pkg/structure/interface.gen.go
+++ b/pkg/structure/interface.gen.go
@@ -20,10 +20,10 @@ type KeyBaseInterface interface {
 
 type StringXInterface interface {
 	KeyBaseInterface
-	Set(*proto.SetRequest) ([]string, error)
-	Get(*proto.GetRequest) ([]string, error)
-	Add(*proto.AddRequest) ([]string, error)
-	Reduce(*proto.ReduceRequest) ([]string, error)
-	Setbit(*proto.SetbitRequest) ([]string, error)
-	Getbit(*proto.GetbitRequest) ([]string, error)
+	Set(*proto.SetRequest) (*ResultConn, error)
+	Get(*proto.GetRequest) (*ResultConn, error)
+	Add(*proto.AddRequest) (*ResultConn, error)
+	Reduce(*proto.ReduceRequest) (*ResultConn, error)
+	Setbit(*proto.SetbitRequest) (*ResultConn, error)
+	Getbit(*proto.GetbitRequest) (*ResultConn, error)
 }
diff --git a/pkg/structure/stringx/string.go b/pkg/structure/stringx/string.go
index 7a86a05..4e7ac6f 100644
--- a/pkg/structure/stringx/string.go
+++ b/pkg/structure/stringx/string.go
@@ -1,51 +1,63 @@
 package stringx
 
-import "gitee.com/timedb/wheatCache/pkg/proto"
+import (
+	"gitee.com/timedb/wheatCache/pkg/proto"
+	"gitee.com/timedb/wheatCache/pkg/structure"
+)
 
-type StringX struct {
-	Value string
+type StringSingle struct {
+	val *structure.Value
 }
 
-func (s *StringX) SizeByte() int64 {
-	panic("implement me")
+func NewStringSingle() structure.StringXInterface {
+	return &StringSingle{
+		val: structure.NewValue(),
+	}
 }
 
-func (s *StringX) RollBack() error {
-	panic("implement me")
+func (s *StringSingle) SizeByte() int64 {
+	return int64(s.val.GetLength())
 }
 
-func (s *StringX) Begin() error {
-	panic("implement me")
+// TODO RollBack 事务相关, V2 实现
+func (s *StringSingle) RollBack() error {
+	panic("not implemented") // TODO: Implement
 }
 
-func (s *StringX) Comment() error {
-	panic("implement me")
+// Begin 事务相关, V2 实现
+func (s *StringSingle) Begin() error {
+	panic("not implemented") // TODO: Implement
 }
 
-func (s *StringX) Encode() ([]byte, error) {
-	panic("implement me")
+// Comment 事务相关, V2 实现
+func (s *StringSingle) Comment() error {
+	panic("not implemented") // TODO: Implement
 }
 
-func (s *StringX) Set(req *proto.SetRequest) ([]string, error) {
-	panic("implement me")
+func (s *StringSingle) Encode() ([]byte, error) {
+	panic("not implemented") // TODO: Implement
 }
 
-func (s *StringX) Get(req *proto.GetRequest) ([]string, error) {
-	panic("implement me")
+func (s *StringSingle) Set(req *proto.SetRequest) (*structure.ResultConn, error) {
+	return nil, nil
 }
 
-func (s *StringX) Add(req *proto.AddRequest) ([]string, error) {
-	panic("implement me")
+func (s *StringSingle) Get(req *proto.GetRequest) (*structure.ResultConn, error) {
+	panic("not implemented") // TODO: Implement
 }
 
-func (s *StringX) Reduce(req *proto.ReduceRequest) ([]string, error) {
-	panic("implement me")
+func (s *StringSingle) Add(req *proto.AddRequest) (*structure.ResultConn, error) {
+	panic("not implemented") // TODO: Implement
 }
 
-func (s *StringX) Setbit(req *proto.SetbitRequest) ([]string, error) {
-	panic("implement me")
+func (s *StringSingle) Reduce(req *proto.ReduceRequest) (*structure.ResultConn, error) {
+	panic("not implemented") // TODO: Implement
 }
 
-func (s *StringX) Getbit(req *proto.GetbitRequest) ([]string, error) {
-	panic("implement me")
+func (s *StringSingle) Setbit(req *proto.SetbitRequest) (*structure.ResultConn, error) {
+	panic("not implemented") // TODO: Implement
+}
+
+func (s *StringSingle) Getbit(req *proto.GetbitRequest) (*structure.ResultConn, error) {
+	panic("not implemented") // TODO: Implement
 }
diff --git a/pkg/structure/stringx/string_test.go b/pkg/structure/stringx/string_test.go
new file mode 100644
index 0000000..4150247
--- /dev/null
+++ b/pkg/structure/stringx/string_test.go
@@ -0,0 +1,19 @@
+package stringx
+
+import (
+	"fmt"
+	"gitee.com/timedb/wheatCache/pkg/proto"
+	"github.com/stretchr/testify/require"
+	"testing"
+)
+
+func TestStringSingle_Set(t *testing.T) {
+	s := new(StringSingle)
+	p := s.SizeByte()
+	require.Equal(t, p, int64(16))
+	s.Set(&proto.SetRequest{
+		Val: "",
+	})
+	p = s.SizeByte()
+	fmt.Println(p)
+}
diff --git a/protobuf/stringx.proto b/protobuf/stringx.proto
index 3c1ca5d..01cb72b 100644
--- a/protobuf/stringx.proto
+++ b/protobuf/stringx.proto
@@ -4,6 +4,7 @@ option go_package = "pkg/proto";
 
 message SetRequest {
   BaseKey key = 1;
+  string val = 2;
 }
 
 message GetRequest {
@@ -12,16 +13,22 @@ message GetRequest {
 
 message AddRequest {
   BaseKey key = 1;
+  // 自动增加
+  int32 raise = 2;
 }
 
 message ReduceRequest {
   BaseKey key = 1;
+  int32 cut = 2;
 }
 
 message SetbitRequest {
   BaseKey key = 1;
+  int32 office = 2;
+  bool val = 3;
 }
 
 message GetbitRequest {
   BaseKey key = 1;
+  int32 office = 2;
 }