use redcon for loading aof

This commit is contained in:
Josh Baker 2017-10-04 16:15:20 -07:00
parent 1c8027c580
commit d4d51a8191
1 changed files with 35 additions and 64 deletions

View File

@ -1,7 +1,6 @@
package controller package controller
import ( import (
"bufio"
"errors" "errors"
"fmt" "fmt"
"io" "io"
@ -13,6 +12,7 @@ import (
"time" "time"
"github.com/tidwall/buntdb" "github.com/tidwall/buntdb"
"github.com/tidwall/redcon"
"github.com/tidwall/resp" "github.com/tidwall/resp"
"github.com/tidwall/tile38/controller/log" "github.com/tidwall/tile38/controller/log"
"github.com/tidwall/tile38/controller/server" "github.com/tidwall/tile38/controller/server"
@ -53,86 +53,57 @@ func (c *Controller) loadAOF() error {
log.Infof("AOF loaded %d commands: %.2fs, %.0f/s, %s", log.Infof("AOF loaded %d commands: %.2fs, %.0f/s, %s",
count, float64(d)/float64(time.Second), ps, byteSpeed) count, float64(d)/float64(time.Second), ps, byteSpeed)
}() }()
var buf []byte
var args [][]byte
var packet [0xFFFF]byte
var msg server.Message var msg server.Message
rd := bufio.NewReader(c.aof)
for { for {
var nn int n, err := c.aof.Read(packet[:])
ch, err := rd.ReadByte()
if err != nil { if err != nil {
if err == io.EOF { if err == io.EOF {
if len(buf) > 0 {
return io.ErrUnexpectedEOF
}
return nil return nil
} }
return err return err
} }
nn += 1 c.aofsz += n
if ch != '*' { data := packet[:n]
return errInvalidAOF if len(buf) > 0 {
data = append(buf, data...)
} }
ns, err := rd.ReadString('\n') var complete bool
if err != nil { for {
return err complete, args, _, data, err = redcon.ReadNextCommand(data, args[:0])
}
nn += len(ns)
if len(ns) < 2 || ns[len(ns)-2] != '\r' {
return errInvalidAOF
}
n, err := strconv.ParseUint(ns[:len(ns)-2], 10, 64)
if err != nil {
return err
}
if int(n) == 0 {
continue
}
msg.Values = msg.Values[:0]
for i := 0; i < int(n); i++ {
ch, err := rd.ReadByte()
if err != nil { if err != nil {
return err return err
} }
if ch != '$' { if !complete {
return errInvalidAOF break
} }
ns, err := rd.ReadString('\n') if len(args) > 0 {
if err != nil { msg.Values = msg.Values[:0]
return err for _, arg := range args {
} msg.Values = append(msg.Values, resp.BytesValue(arg))
if len(ns) < 2 || ns[len(ns)-2] != '\r' { }
return errInvalidAOF msg.Command = qlower(args[0])
} if _, _, err := c.command(&msg, nil, nil); err != nil {
n, err := strconv.ParseUint(ns[:len(ns)-2], 10, 64) if commandErrIsFatal(err) {
if err != nil { return err
return err }
} }
b := make([]byte, int(n)) count++
_, err = io.ReadFull(rd, b)
if err != nil {
return err
}
if ch, err := rd.ReadByte(); err != nil {
return err
} else if ch != '\r' {
return errInvalidAOF
}
if ch, err := rd.ReadByte(); err != nil {
return err
} else if ch != '\n' {
return errInvalidAOF
}
msg.Values = append(msg.Values, resp.BytesValue(b))
if i == 0 {
msg.Command = qlower(b)
}
nn += 1 + len(ns) + int(n) + 2
}
if _, _, err := c.command(&msg, nil, nil); err != nil {
if commandErrIsFatal(err) {
return err
} }
} }
c.aofsz += nn if len(data) > 0 {
count++ buf = append(buf[:0], data...)
} else if len(buf) > 0 {
buf = buf[:0]
}
} }
} }
func qlower(s []byte) string { func qlower(s []byte) string {
if len(s) == 3 { if len(s) == 3 {
if s[0] == 'S' && s[1] == 'E' && s[2] == 'T' { if s[0] == 'S' && s[1] == 'E' && s[2] == 'T' {