Skip to content

Commit

Permalink
opt: performance of lookupCommand
Browse files Browse the repository at this point in the history
  • Loading branch information
xgzlucario committed Jun 3, 2024
1 parent d7ec096 commit dc431e3
Show file tree
Hide file tree
Showing 7 changed files with 54 additions and 43 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ test-cover:
go tool cover -html=coverage.txt -o coverage.html

pprof:
go tool pprof -http=:18081 "http://localhost:6060/debug/pprof/profile?seconds=30"
go tool pprof -http=:18081 "http://192.168.1.6:6060/debug/pprof/profile?seconds=30"

heap:
go tool pprof http://localhost:6060/debug/pprof/heap
3 changes: 2 additions & 1 deletion epoll.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,9 @@ func (e *epoll) Remove(conn net.Conn) error {

func (e *epoll) Wait() ([]net.Conn, error) {
events := make([]unix.EpollEvent, 100)

retry:
n, err := unix.EpollWait(e.fd, events, 0)
n, err := unix.EpollWait(e.fd, events, 100)
if err != nil {
if err == unix.EINTR {
goto retry
Expand Down
3 changes: 0 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ require (
github.com/deckarep/golang-set/v2 v2.6.0
github.com/redis/go-redis/v9 v9.5.2
github.com/sakeven/RbTree v0.0.0-20240321014605-9899538dc980
github.com/sourcegraph/conc v0.3.0
github.com/stretchr/testify v1.9.0
github.com/xgzlucario/GigaCache v0.0.0-20240531152919-576765cef731
github.com/xgzlucario/quicklist v0.0.0-20240530174658-6f1a884f579b
Expand All @@ -22,8 +21,6 @@ require (
github.com/kr/text v0.2.0 // indirect
github.com/mschoch/smat v0.2.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
go.uber.org/atomic v1.7.0 // indirect
go.uber.org/multierr v1.9.0 // indirect
golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
7 changes: 0 additions & 7 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -31,21 +31,14 @@ github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZV
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/sakeven/RbTree v0.0.0-20240321014605-9899538dc980 h1:t5uAkycj8WepkboiZvJzHB+FvkNj+P6Z2dEN4pFajU4=
github.com/sakeven/RbTree v0.0.0-20240321014605-9899538dc980/go.mod h1:zwEumjdcK6Q/ky/gFPqMviw1p7ZUb+B3pU4ybgOHvns=
github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
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/xgzlucario/GigaCache v0.0.0-20240531152919-576765cef731 h1:frRQxMZFCPWfoiWau4bPcYmNDGNVPLqM9nqnsp6Uakg=
github.com/xgzlucario/GigaCache v0.0.0-20240531152919-576765cef731/go.mod h1:sPwGPAuvd9WdiONTmusXGNocqcY5L/J7+st1upAMlX8=
github.com/xgzlucario/quicklist v0.0.0-20240530174658-6f1a884f579b h1:C/+nN/kFJ6yrmEhIu+5Ra2jx/W8w+Ayu8pTiZfuU5Xc=
github.com/xgzlucario/quicklist v0.0.0-20240530174658-6f1a884f579b/go.mod h1:1ZgyZNk91XIllYdOPpwP+9L2RCw6QGSy6alTYF+Z0iU=
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI=
go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ=
golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc h1:O9NuF4s+E/PvMIy+9IUZB9znFwUIXEWSstNjek6VpVg=
golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc=
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
Expand Down
12 changes: 12 additions & 0 deletions resp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ package main
import (
"bytes"
"errors"
"strconv"
"strings"
"testing"
"time"

"github.com/stretchr/testify/assert"
)
Expand Down Expand Up @@ -99,6 +102,15 @@ func TestValue(t *testing.T) {
data := value.Marshal()
assert.Equal(string(data), ErrUnknownType.Error())
})

t.Run("to-lower-nocopy", func(t *testing.T) {
for i := 0; i < 1000; i++ {
timeFormat := strconv.FormatInt(time.Now().UnixNano(), 36)
lower := strings.ToLower(timeFormat)
lower2 := ToLowerNoCopy([]byte(lower))
assert.Equal(lower, string(lower2))
}
})
}

func BenchmarkRESP(b *testing.B) {
Expand Down
61 changes: 30 additions & 31 deletions rotom.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,7 @@ import (
"log"
"net"
"os"
"runtime"
"strings"

"github.com/sourcegraph/conc/pool"
cache "github.com/xgzlucario/GigaCache"
"github.com/xgzlucario/rotom/structx"
)
Expand All @@ -30,21 +27,34 @@ type DB struct {
}

type Server struct {
config *Config
epoller *epoll
workerPool *pool.Pool
config *Config
epoller *epoll
}

type Command struct {
name string
// name is command string name.
// it should consist of all lowercase letters.
name string

// handler is this command real database handler function.
handler func([]Value) Value
arity int // arity represents the minimal number of arguments that command accepts.
aofNeed bool

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

// persist indicates whether this command needs to be persisted.
// effective when `appendonly` is true.
persist bool
}

var (
db DB
server Server
// db is the main database object.
db DB

// server is the main server object.
server Server

// cmdTable is the list of all available commands.
cmdTable []Command = []Command{
{"ping", pingCommand, 0, false},
{"set", setCommand, 2, true},
Expand All @@ -53,22 +63,20 @@ var (
{"hget", hgetCommand, 2, false},
{"hdel", hdelCommand, 2, true},
{"hgetall", hgetallCommand, 1, false},
// TODO
}
)

func lookupCommand(command string) (*Command, error) {
command = strings.ToLower(command)
func lookupCommand(command []byte) (*Command, error) {
cmdStr := b2s(ToLowerNoCopy(command))
for _, c := range cmdTable {
if c.name == command {
if c.name == cmdStr {
return &c, nil
}
}
return nil, fmt.Errorf("invalid command: %s", command)
}

func (cmd *Command) processCommand(args []Value) Value {
// Check command arguments.
if len(args) < cmd.arity {
return newErrValue(ErrWrongArgs(cmd.name))
}
Expand Down Expand Up @@ -96,7 +104,7 @@ func InitDB(config *Config) (err error) {
command := value.array[0].bulk
args := value.array[1:]

cmd, err := lookupCommand(b2s(command))
cmd, err := lookupCommand(command)
if err == nil {
cmd.processCommand(args)
}
Expand All @@ -123,9 +131,6 @@ func (server *Server) RunServe() {
}
server.epoller = epoller

// Start goroutine workerPool.
server.workerPool = pool.New().WithMaxGoroutines(runtime.NumCPU())

go func() {
var buf = make([]byte, 512)

Expand Down Expand Up @@ -185,26 +190,20 @@ func (server *Server) handleConnection(buf []byte, conn net.Conn) {
command := value.array[0].bulk
var res Value

// Lookup for command.
cmd, err := lookupCommand(b2s(command))
cmd, err := lookupCommand(command)
if err != nil {
res = newErrValue(err)

} else {
// Process command.
res = cmd.processCommand(value.array[1:])

// Write aof file after proccess success.
if server.config.AppendOnly && cmd.aofNeed && res.typ != ERROR {
if server.config.AppendOnly && cmd.persist && res.typ != ERROR {
db.aof.Write(buf)
}
}

// Async write result.
server.workerPool.Go(func() {
if _, err = conn.Write(res.Marshal()); err != nil {
log.Println("write reply error:", err)
}
})
if _, err = conn.Write(res.Marshal()); err != nil {
log.Println("write reply error:", err)
}
}
}
9 changes: 9 additions & 0 deletions utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,12 @@ import "unsafe"
func b2s(b []byte) string {
return *(*string)(unsafe.Pointer(&b))
}

func ToLowerNoCopy(b []byte) []byte {
for i, c := range b {
if c >= 'A' && c <= 'Z' {
b[i] += 'a' - 'A'
}
}
return b
}

0 comments on commit dc431e3

Please sign in to comment.