Skip to content

Commit

Permalink
feat: add type command
Browse files Browse the repository at this point in the history
  • Loading branch information
xgzlucario committed Dec 13, 2024
1 parent 55fcf15 commit 778e9d4
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 24 deletions.
52 changes: 42 additions & 10 deletions command.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import (
const (
KeepTtl = "KEEPTTL"
Count = "COUNT"
Match = "MATCH"
NX = "NX"
EX = "EX"
PX = "PX"
Expand All @@ -45,6 +44,7 @@ var cmdTable = []*Command{
{"set", setCommand, 2, true},
{"get", getCommand, 1, false},
{"del", delCommand, 1, true},
{"type", typeCommand, 1, false},
{"scan", scanCommand, 1, false},
{"incr", incrCommand, 1, true},
{"hset", hsetCommand, 3, true},
Expand Down Expand Up @@ -194,6 +194,29 @@ func delCommand(writer *resp.Writer, args []redcon.RESP) {
writer.WriteInt(count)
}

func typeCommand(writer *resp.Writer, args []redcon.RESP) {
key := b2s(args[0].Bytes())
object, ttl := db.dict.Get(key)
if ttl == KeyNotExist {
writer.WriteString("none")
return
}
switch v := object.(type) {
case int, []byte:
writer.WriteString("string")
case *hash.ZipMap:
writer.WriteString("hash")
case *hash.ZipSet, *hash.Set:
writer.WriteString("set")
case *list.QuickList:
writer.WriteString("list")
case *zset.ZipZSet, *zset.ZSet:
writer.WriteString("zset")
default:
writer.WriteError(fmt.Sprintf("unknown type: %T", v))
}
}

func scanCommand(writer *resp.Writer, args []redcon.RESP) {
cursor := int(args[0].Int())
count := 10
Expand Down Expand Up @@ -304,11 +327,16 @@ func lpushCommand(writer *resp.Writer, args []redcon.RESP) {
writer.WriteError(err.Error())
return
}
keys := make([]string, 0, len(args)-1)
for _, arg := range args[1:] {
keys = append(keys, b2s(arg.Bytes()))
// fast push
if len(args[1:]) == 1 {
ls.LPush(b2s(args[1].Bytes()))
} else {
keys := make([]string, 0, len(args)-1)
for _, arg := range args[1:] {
keys = append(keys, b2s(arg.Bytes()))
}
ls.LPush(keys...)
}
ls.LPush(keys...)
writer.WriteInt(ls.Len())
}

Expand All @@ -319,11 +347,16 @@ func rpushCommand(writer *resp.Writer, args []redcon.RESP) {
writer.WriteError(err.Error())
return
}
keys := make([]string, 0, len(args)-1)
for _, arg := range args[1:] {
keys = append(keys, b2s(arg.Bytes()))
// fast push
if len(args[1:]) == 1 {
ls.RPush(b2s(args[1].Bytes()))
} else {
keys := make([]string, 0, len(args)-1)
for _, arg := range args[1:] {
keys = append(keys, b2s(arg.Bytes()))
}
ls.RPush(keys...)
}
ls.RPush(keys...)
writer.WriteInt(ls.Len())
}

Expand Down Expand Up @@ -599,7 +632,6 @@ func fetch[T any](key []byte, new func() T, setnx ...bool) (T, error) {
if !ok {
return v, errWrongType
}

// conversion zipped structure
if len(setnx) > 0 && setnx[0] {
switch data := object.(type) {
Expand Down
33 changes: 33 additions & 0 deletions command_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,12 @@ func testCommand(t *testing.T, testType string, rdb *redis.Client, sleepFn func(
ast.Equal(res, "")
ast.Equal(err, redis.Nil)

_type, _ := rdb.Type(ctx, "foo").Result()
ast.Equal(_type, "string")

_type, _ = rdb.Type(ctx, "not-exist").Result()
ast.Equal(_type, "none")

n, _ := rdb.Del(ctx, "foo", "none").Result()
ast.Equal(n, int64(1))
// setex
Expand Down Expand Up @@ -150,6 +156,9 @@ func testCommand(t *testing.T, testType string, rdb *redis.Client, sleepFn func(
res, _ = rdb.Incr(ctx, "testInt").Result()
ast.Equal(res, int64(2))

_type, _ := rdb.Type(ctx, "testInt").Result()
ast.Equal(_type, "string")

// get int
str, _ := rdb.Get(ctx, "testInt").Result()
ast.Equal(str, "2")
Expand Down Expand Up @@ -188,10 +197,16 @@ func testCommand(t *testing.T, testType string, rdb *redis.Client, sleepFn func(
ast.Nil(err)
}

_, err = rdb.HGet(ctx, "map", "not-exist").Result()
ast.Equal(err, redis.Nil)

// hgetall
resm, _ := rdb.HGetAll(ctx, "map").Result()
ast.Equal(len(resm), 100)

_type, _ := rdb.Type(ctx, "map").Result()
ast.Equal(_type, "hash")

// hdel
res, _ = rdb.HDel(ctx, "map", keys[0:10]...).Result()
ast.Equal(res, int64(10))
Expand Down Expand Up @@ -228,6 +243,9 @@ func testCommand(t *testing.T, testType string, rdb *redis.Client, sleepFn func(
n, _ = rdb.RPush(ctx, "list", "4", "5", "6").Result()
ast.Equal(n, int64(6))

_type, _ := rdb.Type(ctx, "list").Result()
ast.Equal(_type, "list")

// list: [1,2,3,4,5,6]
// lrange
res, _ := rdb.LRange(ctx, "list", 0, -1).Result()
Expand Down Expand Up @@ -261,6 +279,9 @@ func testCommand(t *testing.T, testType string, rdb *redis.Client, sleepFn func(
val, _ = rdb.RPop(ctx, "list").Result()
ast.Equal(val, "6")

n, _ = rdb.LPush(ctx, "list", "6").Result()
ast.Equal(n, int64(5))

// pop nil
{
_, err := rdb.LPop(ctx, "list-empty").Result()
Expand Down Expand Up @@ -301,6 +322,9 @@ func testCommand(t *testing.T, testType string, rdb *redis.Client, sleepFn func(
mems, _ := rdb.SMembers(ctx, "set").Result()
ast.ElementsMatch(mems, []string{"k1", "k2", "k3"})

_type, _ := rdb.Type(ctx, "set").Result()
ast.Equal(_type, "set")

// spop
for i := 0; i < 3; i++ {
val, _ := rdb.SPop(ctx, "set").Result()
Expand All @@ -324,6 +348,9 @@ func testCommand(t *testing.T, testType string, rdb *redis.Client, sleepFn func(
_, err = rdb.SRem(ctx, "key", "1").Result()
ast.Equal(err.Error(), errWrongType.Error())

_, err = rdb.SMembers(ctx, "key").Result()
ast.Equal(err.Error(), errWrongType.Error())

_, err = rdb.SPop(ctx, "key").Result()
ast.Equal(err.Error(), errWrongType.Error())
})
Expand All @@ -338,6 +365,9 @@ func testCommand(t *testing.T, testType string, rdb *redis.Client, sleepFn func(
redis.Z{Member: "user3", Score: 100}).Result()
ast.Equal(n, int64(2))

_type, _ := rdb.Type(ctx, "rank").Result()
ast.Equal(_type, "zset")

// zrank
{
res, _ := rdb.ZRank(ctx, "rank", "user1").Result()
Expand Down Expand Up @@ -411,6 +441,9 @@ func testCommand(t *testing.T, testType string, rdb *redis.Client, sleepFn func(
_, err = rdb.ZRank(ctx, "key", "member1").Result()
ast.Equal(err.Error(), errWrongType.Error())

_, err = rdb.ZRange(ctx, "key", 0, -1).Result()
ast.Equal(err.Error(), errWrongType.Error())

_, err = rdb.ZRem(ctx, "key", "member1").Result()
ast.Equal(err.Error(), errWrongType.Error())

Expand Down
14 changes: 0 additions & 14 deletions const.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@ package main

import (
"github.com/redis/go-redis/v9"
"github.com/xgzlucario/rotom/internal/hash"
"github.com/xgzlucario/rotom/internal/iface"
"github.com/xgzlucario/rotom/internal/list"
"github.com/xgzlucario/rotom/internal/zset"
)

type ObjectType byte
Expand All @@ -32,13 +28,3 @@ const (
MB = 1024 * KB
GB = 1024 * MB
)

// type2c is objectType to new encoder.
var type2c = map[ObjectType]func() iface.Encoder{
TypeMap: func() iface.Encoder { return hash.New() },
TypeSet: func() iface.Encoder { return hash.NewSet() },
TypeZipSet: func() iface.Encoder { return hash.NewZipSet() },
TypeList: func() iface.Encoder { return list.New() },
TypeZSet: func() iface.Encoder { return zset.New() },
TypeZipZSet: func() iface.Encoder { return zset.NewZipZSet() },
}

0 comments on commit 778e9d4

Please sign in to comment.