minor optimizations

This commit is contained in:
Josh Baker 2016-08-20 09:23:39 -07:00
parent 55f1a9cf23
commit b110d63709
1 changed files with 28 additions and 12 deletions

View File

@ -42,17 +42,22 @@ func ListenAndServe(
return err return err
} }
defer ln.Close() defer ln.Close()
tcpln := ln.(*net.TCPListener)
if handler == nil { if handler == nil {
handler = func(conn Conn, cmds [][]string) {} handler = func(conn Conn, cmds [][]string) {}
} }
var mu sync.Mutex var mu sync.Mutex
for { for {
nc, err := ln.Accept() tcpc, err := tcpln.AcceptTCP()
if err != nil { if err != nil {
return err return err
} }
tcpc := nc.(*net.TCPConn) c := &conn{
c := &conn{tcpc, newWriter(tcpc), tcpc.RemoteAddr().String()} tcpc,
newWriter(tcpc),
newReader(tcpc),
tcpc.RemoteAddr().String(),
}
if accept != nil && !accept(c) { if accept != nil && !accept(c) {
c.Close() c.Close()
continue continue
@ -75,10 +80,9 @@ func handle(c *conn, mu *sync.Mutex,
closed(c, err) closed(c, err)
} }
}() }()
rd := newReader(c.conn)
err = func() error { err = func() error {
for { for {
cmds, err := rd.ReadCommands() cmds, err := c.rd.ReadCommands()
if err != nil { if err != nil {
if err, ok := err.(*errProtocol); ok { if err, ok := err.(*errProtocol); ok {
// All protocol errors should attempt a response to // All protocol errors should attempt a response to
@ -107,6 +111,7 @@ func handle(c *conn, mu *sync.Mutex,
type conn struct { type conn struct {
conn *net.TCPConn conn *net.TCPConn
wr *writer wr *writer
rd *reader
addr string addr string
} }
@ -136,22 +141,24 @@ func (c *conn) RemoteAddr() string {
} }
// Reader represents a RESP command reader. // Reader represents a RESP command reader.
type respReader struct { type reader struct {
r *net.TCPConn // base reader r *net.TCPConn // base reader
b []byte // unprocessed bytes b []byte // unprocessed bytes
a []byte // static read buffer a []byte // static read buffer
} }
const buflen = 1024 * 8
// NewReader returns a RESP command reader. // NewReader returns a RESP command reader.
func newReader(r *net.TCPConn) *respReader { func newReader(r *net.TCPConn) *reader {
return &respReader{ return &reader{
r: r, r: r,
a: make([]byte, 8192), a: make([]byte, buflen),
} }
} }
// ReadCommands reads one or more commands from the reader. // ReadCommands reads one or more commands from the reader.
func (r *respReader) ReadCommands() ([][]string, error) { func (r *reader) ReadCommands() ([][]string, error) {
if len(r.b) > 0 { if len(r.b) > 0 {
// we have some potential commands. // we have some potential commands.
var cmds [][]string var cmds [][]string
@ -306,7 +313,10 @@ func (r *respReader) ReadCommands() ([][]string, error) {
return cmds, nil return cmds, nil
} }
} }
n, err := r.r.Read(r.a[:]) if len(r.a) == 0 {
r.a = make([]byte, buflen)
}
n, err := r.r.Read(r.a)
if err != nil { if err != nil {
if err == io.EOF { if err == io.EOF {
if len(r.b) > 0 { if len(r.b) > 0 {
@ -315,7 +325,13 @@ func (r *respReader) ReadCommands() ([][]string, error) {
} }
return nil, err return nil, err
} }
r.b = append(r.b, r.a[:n]...) if len(r.b) == 0 {
r.b = r.a[:n]
} else {
r.b = append(r.b, r.a[:n]...)
}
r.a = r.a[n:]
return r.ReadCommands() return r.ReadCommands()
} }