use arena to reduce object create

This commit is contained in:
siddontang 2014-10-30 00:01:19 +08:00
parent d7c59f337d
commit 796f4b3af2
5 changed files with 60 additions and 38 deletions

22
Godeps/Godeps.json generated
View File

@ -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",

View File

@ -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]))
} }

View File

@ -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

View File

@ -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
} }

View File

@ -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
} }
} }