Skip to content

Commit

Permalink
perf: optimize lookupCommand
Browse files Browse the repository at this point in the history
  • Loading branch information
xgzlucario committed Jul 30, 2024
1 parent 60911d8 commit 3b81313
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 37 deletions.
33 changes: 12 additions & 21 deletions command.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package main

import (
"fmt"
"strconv"
"strings"

"github.com/xgzlucario/rotom/internal/dict"
"github.com/xgzlucario/rotom/internal/hash"
Expand All @@ -16,8 +18,8 @@ type Command struct {
// handler is this command real database handler function.
handler func(writer *RESPWriter, args []RESP)

// arity represents the minimal number of arguments that command accepts.
arity int
// minArgsNum represents the minimal number of arguments that command accepts.
minArgsNum int

// persist indicates whether this command needs to be persisted.
// effective when `appendonly` is true.
Expand Down Expand Up @@ -49,33 +51,22 @@ var cmdTable []*Command = []*Command{
{"mset", todoCommand, 0, false},
{"zpopmin", todoCommand, 0, false},
{"xadd", todoCommand, 0, false},
// TODO: distribution
{"sync", todoCommand, 0, false},
{"log", todoCommand, 0, false},
}

func lookupCommand(command string) *Command {
func lookupCommand(name string) (*Command, error) {
for _, c := range cmdTable {
if equalCommand(command, c.name) {
return c
if len(name) == len(c.name) && strings.EqualFold(name, c.name) {
return c, nil
}
}
return nil
}

func equalCommand(str, lowerText string) bool {
if len(str) != len(lowerText) {
return false
}
const s = 'a' - 'A'
for i, lt := range lowerText {
delta := lt - rune(str[i])
if delta != 0 && delta != s {
return false
}
}
return true
return nil, fmt.Errorf("%w '%s'", errUnknownCommand, name)
}

func (cmd *Command) processCommand(writer *RESPWriter, args []RESP) {
if len(args) < cmd.arity {
if len(args) < cmd.minArgsNum {
writer.WriteError(errInvalidArguments)
return
}
Expand Down
3 changes: 1 addition & 2 deletions resp.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package main

import (
"bytes"
"fmt"
"io"
"slices"
"strconv"
Expand Down Expand Up @@ -97,7 +96,7 @@ func (r *RESPReader) ReadNextCommand(argsBuf []RESP) (args []RESP, err error) {
// command_inline format
before, after, ok := cutByCRLF(r.b)
if !ok {
return nil, fmt.Errorf("%w '%s'", errUnknownCommand, r.b)
return nil, errInvalidArguments
}
args = append(args, before)
r.b = after
Expand Down
28 changes: 14 additions & 14 deletions rotom.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package main

import (
"fmt"
"io"
"runtime"
"runtime/debug"
Expand Down Expand Up @@ -67,10 +66,10 @@ func InitDB(config *Config) (err error) {
// Load the initial data into memory by processing each stored command.
emptyWriter := NewWriter(WRITE_BUF_SIZE)
return db.aof.Read(func(args []RESP) {
command := args[0].ToString()
command := args[0].ToStringUnsafe()

cmd := lookupCommand(command)
if cmd != nil {
cmd, err := lookupCommand(command)
if err == nil {
cmd.processCommand(emptyWriter, args[1:])
emptyWriter.Reset()
}
Expand Down Expand Up @@ -154,23 +153,24 @@ func ProcessQueryBuf(client *Client) {
command := args[0].ToStringUnsafe()
args = args[1:]

cmd := lookupCommand(command)
if cmd != nil {
cmd.processCommand(client.replyWriter, args)
cmd, err := lookupCommand(command)
if err != nil {
client.replyWriter.WriteError(err)
log.Error().Msg(err.Error())

if server.outOfMemory {
} else {
// reject write request when OOM
if cmd.persist && server.outOfMemory {
client.replyWriter.WriteError(errOOM)
goto WRITE
}

if server.config.AppendOnly && cmd.persist {
cmd.processCommand(client.replyWriter, args)

// write aof file
if cmd.persist && server.config.AppendOnly {
db.aof.Write(queryBuf)
}

} else {
err := fmt.Errorf("%w '%s'", errUnknownCommand, command)
client.replyWriter.WriteError(err)
log.Error().Msg(err.Error())
}
}

Expand Down

0 comments on commit 3b81313

Please sign in to comment.