Skip to content

Commit 0f23a8f

Browse files
committed
fix: new thoughts of design
1 parent cbd41fb commit 0f23a8f

File tree

11 files changed

+141
-44
lines changed

11 files changed

+141
-44
lines changed

datastruct/consts.go

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package datastruct
2+
3+
import (
4+
"errors"
5+
)
6+
7+
type KeyType string
8+
9+
const (
10+
KeyTypeString KeyType = "string"
11+
KeyTypeList KeyType = "list"
12+
KeyTypeSet KeyType = "set"
13+
KeyTypeSortedSet KeyType = "sortedSet"
14+
KeyTypeHashMap KeyType = "hashMap"
15+
)
16+
17+
var (
18+
ErrNil = errors.New("redis: not found")
19+
)

datastruct/memory.go

+29-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,35 @@ import (
44
"sync"
55
)
66

7+
var defaultCache = newMemoryCache()
8+
79
// MemoryCache 总数结构
810
type MemoryCache struct {
9-
Keys sync.Map
11+
keys sync.Map
12+
}
13+
14+
func newMemoryCache() *MemoryCache {
15+
return &MemoryCache{keys: sync.Map{}}
16+
}
17+
18+
type KeyInfo struct {
19+
Type KeyType
20+
}
21+
22+
func (m *MemoryCache) Exists(key string) bool {
23+
_, ok := m.keys.Load(key)
24+
return ok
25+
}
26+
27+
func (m *MemoryCache) Set(key string, kt KeyType) {
28+
m.keys.Store(key, &KeyInfo{Type: kt})
29+
}
30+
31+
func (m *MemoryCache) Type(key string) (kt KeyType, found bool) {
32+
v, ok := m.keys.Load(key)
33+
if !ok {
34+
return "", false
35+
}
36+
37+
return v.(*KeyInfo).Type, true
1038
}

datastruct/operate.go

-7
This file was deleted.

datastruct/string.go

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package datastruct
2+
3+
import (
4+
"sync"
5+
)
6+
7+
type String struct {
8+
m sync.Map
9+
mc *MemoryCache
10+
}
11+
12+
func newString(mc *MemoryCache) *String {
13+
return &String{
14+
m: sync.Map{},
15+
mc: mc,
16+
}
17+
}
18+
19+
var (
20+
StringImpl = newString(defaultCache)
21+
)
22+
23+
func (s *String) Set(key, value string, options []string) error {
24+
s.mc.Set(key, KeyTypeString)
25+
26+
s.m.Store(key, value)
27+
return nil
28+
}
29+
30+
func (s *String) Get(key string) (value string, err error) {
31+
v, ok := s.m.Load(key)
32+
if !ok {
33+
return "", ErrNil
34+
}
35+
36+
return v.(string), nil
37+
}
38+
39+
func (s *String) MGet(keys []string) (values []string, err error) {
40+
for _, key := range keys {
41+
v, ok := s.m.Load(key)
42+
if !ok {
43+
values = append(values, "")
44+
}
45+
46+
values = append(values, v.(string))
47+
}
48+
49+
return
50+
}

protocol/encode_test.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ func TestEncodeDataWithSimpleString(t *testing.T) {
3434

3535
func TestEncodeDataWithArray(t *testing.T) {
3636
var want = "*2\r\n$6\r\nHello \r\n$5\r\nWorld\r\n"
37-
assert.Equal(t, want, encodeDataWithArray(
38-
encodeBulkString("Hello "),
39-
encodeBulkString("World"),
37+
assert.Equal(t, want, encodeBulkStrings(
38+
"Hello ",
39+
"World",
4040
))
4141
}

redis/README.md

+13-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
11
# redis
22

3-
Implement how to execute redis command.
3+
Implement how to execute redis command.
4+
5+
## TODO
6+
7+
拆开 command 的实现和数据底层操作的逻辑,最后根据根命令找到对应的方法,然后传入 Command struct,但是这样做很有可能会出现 cycle import 问题,
8+
这个可以通过定义 interface 的方式解决不直接调用实现即可,但是如何通过 command 确定要调的方法呢?
9+
10+
## 暂时想法
11+
12+
1.`exec` 方法作为入口,内部实现对 `datastruct` 包内的方法的封装,
13+
2. `datastruct` 包保持独立,不引入 redis 或者 protocol 包
14+
15+
![redis.exec](..//static/redis.png)

redis/command.go

+2-11
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,6 @@ func NewCommandFromMsg(msg *protocol.Message) *Command {
3636
// 2. found cmd excute func
3737

3838
func (c *Command) Execute(ctx context.Context) (rsp []byte, err error) {
39-
f, ok := KnownCommands[c.Command]
40-
if !ok {
41-
return wrapError(ErrUnknownCommand), nil
42-
}
43-
44-
result, err := f(c)
45-
if err != nil {
46-
return wrapError(err), nil
47-
}
48-
49-
return wrapResult(result), nil
39+
//return exec(c)
40+
return wrapResult([]string{RespOK}), err
5041
}

redis/consts.go

-10
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,6 @@ package redis
22

33
import "errors"
44

5-
type KeyType string
6-
7-
const (
8-
KeyTypeString KeyType = "string"
9-
KeyTypeList KeyType = "list"
10-
KeyTypeSet KeyType = "set"
11-
KeyTypeSortedSet KeyType = "sortedSet"
12-
KeyTypeHashMap KeyType = "hashMap"
13-
)
14-
155
var (
166
ErrUnknownCommand = errors.New("unknown command key")
177
)

redis/exec.go

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package redis
2+
3+
// exec 实现 Command 到 真正执行底层数据操作的过程
4+
func exec(c *Command) (reply []interface{}, err error) {
5+
f, ok := KnownCommands[c.Command]
6+
if !ok {
7+
return nil, ErrUnknownCommand
8+
}
9+
10+
result, err := f(c)
11+
if err != nil {
12+
return nil, err
13+
}
14+
15+
return result, nil
16+
}

redis/keyword.go

+9-11
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,26 @@
11
package redis
22

33
// ExecuteFunc define command execute, returns slice of string as result and error if has any error occur .
4-
type ExecuteFunc func(*Command) ([]string, error)
4+
type ExecuteFunc func(*Command) ([]interface{}, error)
55

6-
func defaultExecFunc(c *Command) ([]string, error) {
7-
return []string{RespOK}, nil
6+
func defaultExecFunc(c *Command) ([]interface{}, error) {
7+
return []interface{}{RespOK}, nil
88
}
99

1010
var KnownCommands = map[string]ExecuteFunc{
1111
// native
12-
"command": func(c *Command) ([]string, error) {
13-
return []string{RespCommand}, nil
12+
"command": func(c *Command) ([]interface{}, error) {
13+
return []interface{}{RespCommand}, nil
1414
},
15-
"ping": func(c *Command) ([]string, error) {
16-
return []string{RespPong}, nil
15+
"ping": func(c *Command) ([]interface{}, error) {
16+
return []interface{}{RespPong}, nil
1717
},
1818
// strings
1919
"append": defaultExecFunc,
2020
"incr": defaultExecFunc,
2121
"decr": defaultExecFunc,
2222
"get": defaultExecFunc,
23-
"mget": func(c *Command) ([]string, error) {
24-
return c.Values, nil
25-
},
26-
"set": defaultExecFunc,
23+
"mget": defaultExecFunc,
24+
"set": defaultExecFunc,
2725
//... more
2826
}

static/redis.png

220 KB
Loading

0 commit comments

Comments
 (0)