mirror of https://github.com/ledisdb/ledisdb.git
use arena to reduce object create
This commit is contained in:
parent
d7c59f337d
commit
796f4b3af2
|
@ -14,41 +14,45 @@
|
||||||
"Comment": "data/v1-228-g8fb50d5",
|
"Comment": "data/v1-228-g8fb50d5",
|
||||||
"Rev": "8fb50d5ee57110936b904a7539d4c5f2bf2359db"
|
"Rev": "8fb50d5ee57110936b904a7539d4c5f2bf2359db"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/siddontang/go/arena",
|
||||||
|
"Rev": "ecf49fc0738105e87d20e29aa82c403b666ff0b4"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/siddontang/go/bson",
|
"ImportPath": "github.com/siddontang/go/bson",
|
||||||
"Rev": "c7a17e4e4a1b72e4bc38b8b52cac8558aff4a4b1"
|
"Rev": "ecf49fc0738105e87d20e29aa82c403b666ff0b4"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/siddontang/go/filelock",
|
"ImportPath": "github.com/siddontang/go/filelock",
|
||||||
"Rev": "c7a17e4e4a1b72e4bc38b8b52cac8558aff4a4b1"
|
"Rev": "ecf49fc0738105e87d20e29aa82c403b666ff0b4"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/siddontang/go/hack",
|
"ImportPath": "github.com/siddontang/go/hack",
|
||||||
"Rev": "c7a17e4e4a1b72e4bc38b8b52cac8558aff4a4b1"
|
"Rev": "ecf49fc0738105e87d20e29aa82c403b666ff0b4"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/siddontang/go/ioutil2",
|
"ImportPath": "github.com/siddontang/go/ioutil2",
|
||||||
"Rev": "c7a17e4e4a1b72e4bc38b8b52cac8558aff4a4b1"
|
"Rev": "ecf49fc0738105e87d20e29aa82c403b666ff0b4"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/siddontang/go/log",
|
"ImportPath": "github.com/siddontang/go/log",
|
||||||
"Rev": "c7a17e4e4a1b72e4bc38b8b52cac8558aff4a4b1"
|
"Rev": "ecf49fc0738105e87d20e29aa82c403b666ff0b4"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/siddontang/go/num",
|
"ImportPath": "github.com/siddontang/go/num",
|
||||||
"Rev": "c7a17e4e4a1b72e4bc38b8b52cac8558aff4a4b1"
|
"Rev": "ecf49fc0738105e87d20e29aa82c403b666ff0b4"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/siddontang/go/snappy",
|
"ImportPath": "github.com/siddontang/go/snappy",
|
||||||
"Rev": "c7a17e4e4a1b72e4bc38b8b52cac8558aff4a4b1"
|
"Rev": "ecf49fc0738105e87d20e29aa82c403b666ff0b4"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/siddontang/go/sync2",
|
"ImportPath": "github.com/siddontang/go/sync2",
|
||||||
"Rev": "c7a17e4e4a1b72e4bc38b8b52cac8558aff4a4b1"
|
"Rev": "ecf49fc0738105e87d20e29aa82c403b666ff0b4"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/siddontang/goleveldb/leveldb",
|
"ImportPath": "github.com/siddontang/goleveldb/leveldb",
|
||||||
"Rev": "71404b29ccd98b94ec2278afa806d59a11cd0d28"
|
"Rev": "c1f6d721561c48f467b26a277741e55fd224df1e"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/szferi/gomdb",
|
"ImportPath": "github.com/szferi/gomdb",
|
||||||
|
|
|
@ -5,10 +5,10 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/siddontang/go/arena"
|
||||||
"github.com/siddontang/ledisdb/server"
|
"github.com/siddontang/ledisdb/server"
|
||||||
"net"
|
"net"
|
||||||
"runtime"
|
"runtime"
|
||||||
"sync"
|
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -37,12 +37,12 @@ func main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var m = map[string][]byte{}
|
|
||||||
var mu sync.Mutex
|
|
||||||
|
|
||||||
func run(c net.Conn) {
|
func run(c net.Conn) {
|
||||||
//buf := make([]byte, 10240)
|
//buf := make([]byte, 10240)
|
||||||
ok := []byte("+OK\r\n")
|
ok := []byte("+OK\r\n")
|
||||||
|
data := []byte("$4096\r\n")
|
||||||
|
data = append(data, make([]byte, 4096)...)
|
||||||
|
data = append(data, "\r\n"...)
|
||||||
|
|
||||||
var rt time.Duration
|
var rt time.Duration
|
||||||
var wt time.Duration
|
var wt time.Duration
|
||||||
|
@ -50,10 +50,14 @@ func run(c net.Conn) {
|
||||||
rb := bufio.NewReaderSize(c, 10240)
|
rb := bufio.NewReaderSize(c, 10240)
|
||||||
wb := bufio.NewWriterSize(c, 10240)
|
wb := bufio.NewWriterSize(c, 10240)
|
||||||
|
|
||||||
|
a := arena.NewArena(10240)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
t1 := time.Now()
|
t1 := time.Now()
|
||||||
|
|
||||||
req, err := server.ReadRequest(rb)
|
a.Reset()
|
||||||
|
|
||||||
|
req, err := server.ReadRequest(rb, a)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
break
|
break
|
||||||
|
@ -65,21 +69,9 @@ func run(c net.Conn) {
|
||||||
cmd := string(bytes.ToUpper(req[0]))
|
cmd := string(bytes.ToUpper(req[0]))
|
||||||
switch cmd {
|
switch cmd {
|
||||||
case "SET":
|
case "SET":
|
||||||
mu.Lock()
|
|
||||||
m[string(req[1])] = req[2]
|
|
||||||
mu.Unlock()
|
|
||||||
wb.Write(ok)
|
wb.Write(ok)
|
||||||
case "GET":
|
case "GET":
|
||||||
mu.Lock()
|
wb.Write(data)
|
||||||
v := m[string(req[1])]
|
|
||||||
mu.Unlock()
|
|
||||||
if v == nil {
|
|
||||||
wb.WriteString("$-1\r\n")
|
|
||||||
} else {
|
|
||||||
wb.WriteString(fmt.Sprintf("$%d\r\n", len(v)))
|
|
||||||
wb.Write(v)
|
|
||||||
wb.WriteString("\r\n")
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
wb.WriteString(fmt.Sprintf("-Err %s Not Supported Now", req[0]))
|
wb.WriteString(fmt.Sprintf("-Err %s Not Supported Now", req[0]))
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,17 +108,18 @@ func (c *client) perform() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
go func() {
|
// go func() {
|
||||||
c.reqErr <- exeCmd(c)
|
// c.reqErr <- exeCmd(c)
|
||||||
}()
|
// }()
|
||||||
|
|
||||||
err = <-c.reqErr
|
// err = <-c.reqErr
|
||||||
|
err = exeCmd(c)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
duration := time.Since(start)
|
|
||||||
|
|
||||||
if c.app.access != nil {
|
if c.app.access != nil {
|
||||||
|
duration := time.Since(start)
|
||||||
|
|
||||||
fullCmd := c.catGenericCommand()
|
fullCmd := c.catGenericCommand()
|
||||||
cost := duration.Nanoseconds() / 1000000
|
cost := duration.Nanoseconds() / 1000000
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ package server
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"errors"
|
"errors"
|
||||||
|
"github.com/siddontang/go/arena"
|
||||||
"github.com/siddontang/go/hack"
|
"github.com/siddontang/go/hack"
|
||||||
"github.com/siddontang/go/log"
|
"github.com/siddontang/go/log"
|
||||||
"github.com/siddontang/go/num"
|
"github.com/siddontang/go/num"
|
||||||
|
@ -21,6 +22,8 @@ type respClient struct {
|
||||||
|
|
||||||
conn net.Conn
|
conn net.Conn
|
||||||
rb *bufio.Reader
|
rb *bufio.Reader
|
||||||
|
|
||||||
|
ar *arena.Arena
|
||||||
}
|
}
|
||||||
|
|
||||||
type respWriter struct {
|
type respWriter struct {
|
||||||
|
@ -43,6 +46,9 @@ func newClientRESP(conn net.Conn, app *App) {
|
||||||
c.resp = newWriterRESP(conn, app.cfg.ConnWriteBufferSize)
|
c.resp = newWriterRESP(conn, app.cfg.ConnWriteBufferSize)
|
||||||
c.remoteAddr = conn.RemoteAddr().String()
|
c.remoteAddr = conn.RemoteAddr().String()
|
||||||
|
|
||||||
|
//maybe another config?
|
||||||
|
c.ar = arena.NewArena(app.cfg.ConnReadBufferSize)
|
||||||
|
|
||||||
go c.run()
|
go c.run()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,18 +77,31 @@ func (c *respClient) run() {
|
||||||
c.app.removeSlave(c.client, handleQuit)
|
c.app.removeSlave(c.client, handleQuit)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
// done := make(chan error)
|
||||||
for {
|
for {
|
||||||
|
// go func() {
|
||||||
reqData, err := c.readRequest()
|
reqData, err := c.readRequest()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
// done <- err
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.handleRequest(reqData)
|
c.handleRequest(reqData)
|
||||||
|
// done <- nil
|
||||||
|
// }()
|
||||||
|
|
||||||
|
// err := <-done
|
||||||
|
// if err != nil {
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
// if c.conn == nil {
|
||||||
|
// return
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *respClient) readRequest() ([][]byte, error) {
|
func (c *respClient) readRequest() ([][]byte, error) {
|
||||||
return ReadRequest(c.rb)
|
return ReadRequest(c.rb, c.ar)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *respClient) handleRequest(reqData [][]byte) {
|
func (c *respClient) handleRequest(reqData [][]byte) {
|
||||||
|
@ -103,6 +122,11 @@ func (c *respClient) handleRequest(reqData [][]byte) {
|
||||||
|
|
||||||
c.perform()
|
c.perform()
|
||||||
|
|
||||||
|
c.cmd = ""
|
||||||
|
c.args = nil
|
||||||
|
|
||||||
|
c.ar.Reset()
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/siddontang/go/arena"
|
||||||
"io"
|
"io"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -25,7 +26,7 @@ func ReadLine(rb *bufio.Reader) ([]byte, error) {
|
||||||
return p[:i], nil
|
return p[:i], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func readBytes(br *bufio.Reader) (bytes []byte, err error) {
|
func readBytes(br *bufio.Reader, a *arena.Arena) (bytes []byte, err error) {
|
||||||
size, err := readLong(br)
|
size, err := readLong(br)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -37,7 +38,7 @@ func readBytes(br *bufio.Reader) (bytes []byte, err error) {
|
||||||
return nil, errors.New("Invalid size: " + fmt.Sprint("%d", size))
|
return nil, errors.New("Invalid size: " + fmt.Sprint("%d", size))
|
||||||
}
|
}
|
||||||
|
|
||||||
buf := make([]byte, size+2)
|
buf := a.Make(int(size) + 2)
|
||||||
if _, err = io.ReadFull(br, buf); err != nil {
|
if _, err = io.ReadFull(br, buf); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -90,7 +91,7 @@ func readLong(in *bufio.Reader) (result int64, err error) {
|
||||||
return -1, err
|
return -1, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func ReadRequest(in *bufio.Reader) ([][]byte, error) {
|
func ReadRequest(in *bufio.Reader, a *arena.Arena) ([][]byte, error) {
|
||||||
code, err := in.ReadByte()
|
code, err := in.ReadByte()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -115,7 +116,7 @@ func ReadRequest(in *bufio.Reader) ([][]byte, error) {
|
||||||
return nil, errReadRequest
|
return nil, errReadRequest
|
||||||
}
|
}
|
||||||
|
|
||||||
if req[i], err = readBytes(in); err != nil {
|
if req[i], err = readBytes(in, a); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue