Skip to content

Commit

Permalink
Add RESP3 big number
Browse files Browse the repository at this point in the history
  • Loading branch information
git-hulk committed Jan 21, 2024
1 parent c772109 commit b722e17
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 15 deletions.
4 changes: 3 additions & 1 deletion src/commands/cmd_server.cc
Original file line number Diff line number Diff line change
Expand Up @@ -623,6 +623,8 @@ class CommandDebug : public Commander {
*output += redis::Integer(i);
*output += conn->Bool(i == 1);
}
} else if (protocol_type_ == "bignum") {
*output = conn->BigNumber("1234567999999999999999999999999999999");
} else if (protocol_type_ == "true") {
*output = conn->Bool(true);
} else if (protocol_type_ == "false") {
Expand All @@ -631,7 +633,7 @@ class CommandDebug : public Commander {
*output = conn->NilString();
} else {
*output = redis::Error(
"Wrong protocol type name. Please use one of the following: string|int|array|set|true|false|null");
"Wrong protocol type name. Please use one of the following: string|int|array|set|bignum|true|false|null");
}
} else {
return {Status::RedisInvalidCmd, "Unknown subcommand, should be DEBUG or PROTOCOL"};
Expand Down
3 changes: 3 additions & 0 deletions src/server/redis_connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ class Connection : public EvbufCallbackBase<Connection> {
RESP GetProtocolVersion() const { return protocol_version_; }
void SetProtocolVersion(RESP version) { protocol_version_ = version; }
std::string Bool(bool b) const;
std::string BigNumber(const std::string &n) const {
return protocol_version_ == RESP::v3 ? "(" + n + CRLF : BulkString(n);
}
std::string NilString() const { return redis::NilString(protocol_version_); }
std::string NilArray() const { return protocol_version_ == RESP::v3 ? "_" CRLF : "*-1" CRLF; }
std::string MultiBulkString(const std::vector<std::string> &values, bool output_nil_for_empty_string = true) const;
Expand Down
42 changes: 28 additions & 14 deletions src/storage/scripting.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1080,6 +1080,7 @@ std::string ReplyToRedisReply(redis::Connection *conn, lua_State *lua) {
std::string output;
const char *obj_s = nullptr;
size_t obj_len = 0;
int j, mbulklen;

int t = lua_type(lua, -1);
switch (t) {
Expand Down Expand Up @@ -1113,6 +1114,7 @@ std::string ReplyToRedisReply(redis::Connection *conn, lua_State *lua) {
return output;
}
lua_pop(lua, 1); /* Discard field name pushed before. */

/* Handle status reply. */
lua_pushstring(lua, "ok");
lua_gettable(lua, -2);
Expand All @@ -1122,23 +1124,35 @@ std::string ReplyToRedisReply(redis::Connection *conn, lua_State *lua) {
output = redis::BulkString(std::string(obj_s, obj_len));
lua_pop(lua, 1);
return output;
} else {
int j = 1, mbulklen = 0;
lua_pop(lua, 1); /* Discard the 'ok' field value we popped */
while (true) {
lua_pushnumber(lua, j++);
lua_gettable(lua, -2);
t = lua_type(lua, -1);
if (t == LUA_TNIL) {
lua_pop(lua, 1);
break;
}
mbulklen++;
output += ReplyToRedisReply(conn, lua);
}
lua_pop(lua, 1); /* Discard the 'ok' field value we pushed */

/* Handle big number reply. */
lua_pushstring(lua, "big_number");
lua_gettable(lua, -2);
t = lua_type(lua, -1);
if (t == LUA_TSTRING) {
obj_s = lua_tolstring(lua, -1, &obj_len);
output = conn->BigNumber(std::string(obj_s, obj_len));
lua_pop(lua, 1);
return output;
}
lua_pop(lua, 1); /* Discard the 'big_number' field value we pushed */

j = 1, mbulklen = 0;
while (true) {
lua_pushnumber(lua, j++);
lua_gettable(lua, -2);
t = lua_type(lua, -1);
if (t == LUA_TNIL) {
lua_pop(lua, 1);
break;
}
output = redis::MultiLen(mbulklen) + output;
mbulklen++;
output += ReplyToRedisReply(conn, lua);
lua_pop(lua, 1);
}
output = redis::MultiLen(mbulklen) + output;
break;
default:
output = conn->NilString();
Expand Down
4 changes: 4 additions & 0 deletions tests/gocase/unit/debug/debug_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ package debug

import (
"context"
"math/big"
"testing"

"github.com/redis/go-redis/v9"
Expand All @@ -46,6 +47,7 @@ func TestDebugProtocolV2(t *testing.T) {
"array": []interface{}{int64(0), int64(1), int64(2)},
"set": []interface{}{int64(0), int64(1), int64(2)},
"map": []interface{}{int64(0), int64(0), int64(1), int64(1), int64(2), int64(0)},
"bignum": "1234567999999999999999999999999999999",
"true": int64(1),
"false": int64(0),
}
Expand Down Expand Up @@ -83,12 +85,14 @@ func TestDebugProtocolV3(t *testing.T) {
defer func() { require.NoError(t, rdb.Close()) }()

t.Run("debug protocol type", func(t *testing.T) {
bignum, _ := big.NewInt(0).SetString("1234567999999999999999999999999999999", 10)
types := map[string]interface{}{
"string": "Hello World",
"integer": int64(12345),
"array": []interface{}{int64(0), int64(1), int64(2)},
"set": []interface{}{int64(0), int64(1), int64(2)},
"map": map[interface{}]interface{}{int64(0): false, int64(1): true, int64(2): false},
"bignum": bignum,
"true": true,
"false": false,
}
Expand Down
2 changes: 2 additions & 0 deletions tests/gocase/unit/protocol/protocol_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ func TestProtocolRESP2(t *testing.T) {
"array": {"*3", ":0", ":1", ":2"},
"set": {"*3", ":0", ":1", ":2"},
"map": {"*6", ":0", ":0", ":1", ":1", ":2", ":0"},
"bignum": {"$37", "1234567999999999999999999999999999999"},
"true": {":1"},
"false": {":0"},
"null": {"$-1"},
Expand Down Expand Up @@ -210,6 +211,7 @@ func TestProtocolRESP3(t *testing.T) {
"array": {"*3", ":0", ":1", ":2"},
"set": {"~3", ":0", ":1", ":2"},
"map": {"%3", ":0", "#f", ":1", "#t", ":2", "#f"},
"bignum": {"(1234567999999999999999999999999999999"},
"true": {"#t"},
"false": {"#f"},
"null": {"_"},
Expand Down

0 comments on commit b722e17

Please sign in to comment.