Skip to content

Commit

Permalink
opt: RESP support command inline
Browse files Browse the repository at this point in the history
  • Loading branch information
xgzlucario committed Jun 15, 2024
1 parent 1777572 commit 3e7742d
Show file tree
Hide file tree
Showing 9 changed files with 77 additions and 142 deletions.
23 changes: 0 additions & 23 deletions bench.sh

This file was deleted.

21 changes: 21 additions & 0 deletions command.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package main

import (
"strconv"

"github.com/xgzlucario/rotom/structx"
)

Expand All @@ -25,6 +27,7 @@ var cmdTable []*Command = []*Command{
{"ping", pingCommand, 0, false},
{"set", setCommand, 2, true},
{"get", getCommand, 1, false},
{"incr", incrCommand, 1, true},
{"hset", hsetCommand, 3, true},
{"hget", hgetCommand, 2, false},
{"hdel", hdelCommand, 2, true},
Expand Down Expand Up @@ -77,6 +80,24 @@ func setCommand(args []Arg) Value {
return ValueOK
}

func incrCommand(args []Arg) Value {
key := args[0].ToString()
val, _, ok := db.strs.Get(key)
if !ok {
db.strs.Set(key, []byte("1"))
return newIntegerValue(1)

} else {
num, err := strconv.Atoi(b2s(val))
if err != nil {
return newErrValue(ErrParseInteger)
}
num++
db.strs.Set(key, []byte(strconv.Itoa(num)))
return newIntegerValue(num)
}
}

func getCommand(args []Arg) Value {
key := args[0].ToStringUnsafe()

Expand Down
12 changes: 12 additions & 0 deletions command_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,18 @@ func TestCommand(t *testing.T) {
assert.Equal(res, "")
})

t.Run("incr", func(t *testing.T) {
res, _ := rdb.Incr(ctx, "testIncr").Result()
assert.Equal(res, int64(1))

res, _ = rdb.Incr(ctx, "testIncr").Result()
assert.Equal(res, int64(2))

rdb.Set(ctx, "notNum", "bar", 0)
_, err := rdb.Incr(ctx, "notNum").Result()
assert.Equal(err.Error(), ErrParseInteger.Error())
})

t.Run("hash", func(t *testing.T) {
// hset
res, _ := rdb.HSet(ctx, "map", "k1", "v1").Result()
Expand Down
3 changes: 0 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ module github.com/xgzlucario/rotom
go 1.22

require (
github.com/RoaringBitmap/roaring v1.9.4
github.com/deckarep/golang-set/v2 v2.6.0
github.com/redis/go-redis/v9 v9.5.2
github.com/rs/zerolog v1.33.0
Expand All @@ -16,7 +15,6 @@ require (
)

require (
github.com/bits-and-blooms/bitset v1.13.0 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/cockroachdb/swiss v0.0.0-20240612210725-f4de07ae6964 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
Expand All @@ -26,7 +24,6 @@ require (
github.com/kr/text v0.2.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mschoch/smat v0.2.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/zeebo/xxh3 v1.0.2 // indirect
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 // indirect
Expand Down
11 changes: 0 additions & 11 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
github.com/RoaringBitmap/roaring v1.9.4 h1:yhEIoH4YezLYT04s1nHehNO64EKFTop/wBhxv2QzDdQ=
github.com/RoaringBitmap/roaring v1.9.4/go.mod h1:6AXUsoIEzDTFFQCe1RbGA6uFONMhvejWj5rqITANK90=
github.com/aclements/go-perfevent v0.0.0-20240301234650-f7843625020f h1:JjxwchlOepwsUWcQwD2mLUAGE9aCp0/ehy6yCHFBOvo=
github.com/aclements/go-perfevent v0.0.0-20240301234650-f7843625020f/go.mod h1:tMDTce/yLLN/SK8gMOxQfnyeMeCg8KGzp0D1cbECEeo=
github.com/bits-and-blooms/bitset v1.12.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=
github.com/bits-and-blooms/bitset v1.13.0 h1:bAQ9OPNFYbGHV6Nez0tmNI0RiEu7/hxlYJRUA0wFAVE=
github.com/bits-and-blooms/bitset v1.13.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=
github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
Expand All @@ -15,7 +10,6 @@ github.com/cockroachdb/swiss v0.0.0-20240612210725-f4de07ae6964 h1:Ew0znI2JatzKy
github.com/cockroachdb/swiss v0.0.0-20240612210725-f4de07ae6964/go.mod h1:yBRu/cnL4ks9bgy4vAASdjIW+/xMlFwuHKqtmh3GZQg=
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/deckarep/golang-set/v2 v2.6.0 h1:XfcQbWM1LlMB8BsJ8N9vW5ehnnPVIw0je80NsVHagjM=
Expand All @@ -37,8 +31,6 @@ github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mschoch/smat v0.2.0 h1:8imxQsjDm8yFEAVBe7azKmKSgzSkZXDuKkSq9374khM=
github.com/mschoch/smat v0.2.0/go.mod h1:kc9mz7DoBKqDyiRL7VZN8KvXQMWeTaVnttLRXOlotKw=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
Expand All @@ -51,8 +43,6 @@ github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8=
github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
github.com/sakeven/RbTree v1.1.1 h1:uraKm67BJYqWDOWAYVOhPsRaMSJZqFF1+bQgaeCR3so=
github.com/sakeven/RbTree v1.1.1/go.mod h1:zwEumjdcK6Q/ky/gFPqMviw1p7ZUb+B3pU4ybgOHvns=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/tidwall/mmap v0.3.0 h1:XXt1YsiXCF5/UAu3pLbu6g7iulJ9jsbs6vt7UpiV0sY=
Expand All @@ -77,6 +67,5 @@ golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
46 changes: 26 additions & 20 deletions resp.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ type Value struct {
array []Value // Used for arrays of nested values
}

// Arg represents the raw arguments bytes of RESP.
type Arg []byte

// Resp is a parser for RESP encoded data.
Expand Down Expand Up @@ -82,15 +83,15 @@ func parseInt(b []byte) (int, error) {
return strconv.Atoi(b2s(b))
}

func (r *Resp) ReadNextCommand(argsBuf []Arg) (res []Arg, err error) {
func (r *Resp) ReadNextCommand(argsBuf []Arg) (args []Arg, err error) {
if len(r.b) == 0 {
return nil, io.EOF
}
res = argsBuf[:0]
args = argsBuf[:0]

switch r.b[0] {
case ARRAY:
// read CRLF
// command_bulk format
before, after, ok := cutByCRLF(r.b[1:])
if !ok {
return nil, ErrCRLFNotFound
Expand All @@ -104,29 +105,34 @@ func (r *Resp) ReadNextCommand(argsBuf []Arg) (res []Arg, err error) {
for i := 0; i < count; i++ {
switch r.b[0] {
case BULK:
// read CRLF
before, after, ok := cutByCRLF(r.b[1:])
if !ok {
return nil, ErrCRLFNotFound
}
count, err := parseInt(before)
if err != nil {
return nil, err
}
r.b = after

res = append(res, r.b[:count])
r.b = r.b[count+2:]

default:
return nil, fmt.Errorf("unsupport array-in type: %c", r.b[0])
return nil, fmt.Errorf("unsupport array-in type: '%c'", r.b[0])
}

// read CRLF
before, after, ok := cutByCRLF(r.b[1:])
if !ok {
return nil, ErrCRLFNotFound
}
count, err := parseInt(before)
if err != nil {
return nil, err
}
r.b = after

args = append(args, r.b[:count])
r.b = r.b[count+2:]
}

default:
return nil, fmt.Errorf("unknown command: %s", r.b)
// command_inline format
before, after, ok := cutByCRLF(r.b)
if !ok {
return nil, ErrUnknownCommand(string(r.b))
}
args = append(args, before)
r.b = after
}

return
}

Expand Down
20 changes: 14 additions & 6 deletions resp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,12 @@ func TestValue(t *testing.T) {
value := ValueOK
data := value.Append(nil)
assert.Equal(string(data), "+OK\r\n")

_, err := NewResp(data).ReadNextCommand(nil)
assert.NotNil(err)
})

t.Run("err-value", func(t *testing.T) {
value := newErrValue(errors.New("err message"))
data := value.Append(nil)
assert.Equal(string(data), "-err message\r\n")

_, err := NewResp(data).ReadNextCommand(nil)
assert.NotNil(err)
})

t.Run("bulk-value", func(t *testing.T) {
Expand Down Expand Up @@ -78,4 +72,18 @@ func TestValue(t *testing.T) {
assert.Equal(string(after), "5678")
assert.True(ok)
})

t.Run("readCommandBulk", func(t *testing.T) {
args, err := NewResp([]byte("*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$3\r\nbar\r\n")).ReadNextCommand(nil)
assert.Equal(args[0].ToString(), "SET")
assert.Equal(args[1].ToString(), "foo")
assert.Equal(args[2].ToString(), "bar")
assert.Nil(err)
})

t.Run("readCommandInline", func(t *testing.T) {
args, err := NewResp([]byte("PING\r\n")).ReadNextCommand(nil)
assert.Equal(args[0].ToString(), "PING")
assert.Nil(err)
})
}
9 changes: 4 additions & 5 deletions rotom.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,10 @@ const (
)

type (
Map = *structx.Map
Set = *structx.Set
List = *structx.List
ZSet = *structx.ZSet
BitMap = *structx.Bitmap
Map = *structx.Map
Set = *structx.Set
List = *structx.List
ZSet = *structx.ZSet
)

type DB struct {
Expand Down
74 changes: 0 additions & 74 deletions structx/bitmap.go

This file was deleted.

0 comments on commit 3e7742d

Please sign in to comment.