refactor, use go-leveldb,

you must re execute bootstrap.sh to go get go-leveldb
you must remove your old leveldb path because hash size format changed
This commit is contained in:
siddontang 2014-05-14 16:35:49 +08:00
parent d8eab1572c
commit 990b2ee69d
14 changed files with 119 additions and 102 deletions

View File

@ -3,7 +3,6 @@
. ./dev.sh . ./dev.sh
go get -u github.com/jmhodges/levigo go get -u github.com/jmhodges/levigo
go get -u github.com/siddontang/golib/leveldb go get -u github.com/siddontang/go-leveldb/leveldb
go get -u github.com/siddontang/golib/log go get -u github.com/siddontang/golib/log
go get -u github.com/siddontang/golib/hack
go get -u github.com/garyburd/redigo/redis go get -u github.com/garyburd/redigo/redis

View File

@ -1,7 +1,7 @@
package ledis package ledis
import ( import (
"github.com/siddontang/golib/leveldb" "github.com/siddontang/go-leveldb/leveldb"
"net" "net"
"strings" "strings"
) )

View File

@ -3,7 +3,6 @@ package ledis
import ( import (
"bufio" "bufio"
"errors" "errors"
"github.com/siddontang/golib/hack"
"github.com/siddontang/golib/log" "github.com/siddontang/golib/log"
"io" "io"
"net" "net"
@ -92,7 +91,7 @@ func (c *client) readRequest() ([][]byte, error) {
} }
var nparams int var nparams int
if nparams, err = strconv.Atoi(hack.String(l[1:])); err != nil { if nparams, err = strconv.Atoi(String(l[1:])); err != nil {
return nil, err return nil, err
} else if nparams <= 0 { } else if nparams <= 0 {
return nil, errReadRequest return nil, errReadRequest
@ -109,7 +108,7 @@ func (c *client) readRequest() ([][]byte, error) {
return nil, errReadRequest return nil, errReadRequest
} else if l[0] == '$' { } else if l[0] == '$' {
//handle resp string //handle resp string
if n, err = strconv.Atoi(hack.String(l[1:])); err != nil { if n, err = strconv.Atoi(String(l[1:])); err != nil {
return nil, err return nil, err
} else if n == -1 { } else if n == -1 {
req = append(req, nil) req = append(req, nil)
@ -139,7 +138,7 @@ func (c *client) handleRequest(req [][]byte) {
if len(req) == 0 { if len(req) == 0 {
err = ErrEmptyCommand err = ErrEmptyCommand
} else { } else {
c.cmd = strings.ToLower(hack.String(req[0])) c.cmd = strings.ToLower(String(req[0]))
c.args = req[1:] c.args = req[1:]
f, ok := regCmds[c.cmd] f, ok := regCmds[c.cmd]
@ -161,23 +160,23 @@ func (c *client) handleRequest(req [][]byte) {
} }
func (c *client) writeError(err error) { func (c *client) writeError(err error) {
c.wb.Write(hack.Slice("-ERR")) c.wb.Write(Slice("-ERR"))
if err != nil { if err != nil {
c.wb.WriteByte(' ') c.wb.WriteByte(' ')
c.wb.Write(hack.Slice(err.Error())) c.wb.Write(Slice(err.Error()))
} }
c.wb.Write(Delims) c.wb.Write(Delims)
} }
func (c *client) writeStatus(status string) { func (c *client) writeStatus(status string) {
c.wb.WriteByte('+') c.wb.WriteByte('+')
c.wb.Write(hack.Slice(status)) c.wb.Write(Slice(status))
c.wb.Write(Delims) c.wb.Write(Delims)
} }
func (c *client) writeInteger(n int64) { func (c *client) writeInteger(n int64) {
c.wb.WriteByte(':') c.wb.WriteByte(':')
c.wb.Write(hack.Slice(strconv.FormatInt(n, 10))) c.wb.Write(Slice(strconv.FormatInt(n, 10)))
c.wb.Write(Delims) c.wb.Write(Delims)
} }
@ -186,7 +185,7 @@ func (c *client) writeBulk(b []byte) {
if b == nil { if b == nil {
c.wb.Write(NullBulk) c.wb.Write(NullBulk)
} else { } else {
c.wb.Write(hack.Slice(strconv.Itoa(len(b)))) c.wb.Write(Slice(strconv.Itoa(len(b))))
c.wb.Write(Delims) c.wb.Write(Delims)
c.wb.Write(b) c.wb.Write(b)
} }
@ -200,7 +199,7 @@ func (c *client) writeArray(ay []interface{}) {
c.wb.Write(NullArray) c.wb.Write(NullArray)
c.wb.Write(Delims) c.wb.Write(Delims)
} else { } else {
c.wb.Write(hack.Slice(strconv.Itoa(len(ay)))) c.wb.Write(Slice(strconv.Itoa(len(ay))))
c.wb.Write(Delims) c.wb.Write(Delims)
for i := 0; i < len(ay); i++ { for i := 0; i < len(ay); i++ {

View File

@ -1,9 +1,6 @@
package ledis package ledis
import ( import ()
"github.com/siddontang/golib/hack"
"strconv"
)
func hsetCommand(c *client) error { func hsetCommand(c *client) error {
args := c.args args := c.args
@ -90,7 +87,7 @@ func hincrbyCommand(c *client) error {
return ErrCmdParams return ErrCmdParams
} }
delta, err := strconv.ParseInt(hack.String(args[2]), 10, 64) delta, err := StrInt64(args[2], nil)
if err != nil { if err != nil {
return err return err
} }

View File

@ -1,9 +1,6 @@
package ledis package ledis
import ( import ()
"github.com/siddontang/golib/hack"
"strconv"
)
func getCommand(c *client) error { func getCommand(c *client) error {
args := c.args args := c.args
@ -115,7 +112,7 @@ func incrbyCommand(c *client) error {
return ErrCmdParams return ErrCmdParams
} }
delta, err := strconv.ParseInt(hack.String(args[1]), 10, 64) delta, err := StrInt64(args[1], nil)
if err != nil { if err != nil {
return err return err
} }
@ -135,7 +132,7 @@ func decrbyCommand(c *client) error {
return ErrCmdParams return ErrCmdParams
} }
delta, err := strconv.ParseInt(hack.String(args[1]), 10, 64) delta, err := StrInt64(args[1], nil)
if err != nil { if err != nil {
return err return err
} }

View File

@ -1,9 +1,6 @@
package ledis package ledis
import ( import ()
"github.com/siddontang/golib/hack"
"strconv"
)
func lpushCommand(c *client) error { func lpushCommand(c *client) error {
args := c.args args := c.args
@ -86,7 +83,7 @@ func lindexCommand(c *client) error {
return ErrCmdParams return ErrCmdParams
} }
index, err := strconv.ParseInt(hack.String(args[1]), 10, 64) index, err := StrInt64(args[1], nil)
if err != nil { if err != nil {
return err return err
} }
@ -110,12 +107,12 @@ func lrangeCommand(c *client) error {
var stop int64 var stop int64
var err error var err error
start, err = strconv.ParseInt(hack.String(args[1]), 10, 64) start, err = StrInt64(args[1], nil)
if err != nil { if err != nil {
return err return err
} }
stop, err = strconv.ParseInt(hack.String(args[2]), 10, 64) stop, err = StrInt64(args[2], nil)
if err != nil { if err != nil {
return err return err
} }

View File

@ -2,7 +2,6 @@ package ledis
import ( import (
"errors" "errors"
"github.com/siddontang/golib/hack"
"math" "math"
"strconv" "strconv"
"strings" "strings"
@ -31,7 +30,7 @@ func zaddCommand(c *client) error {
args = args[1:] args = args[1:]
params := make([]interface{}, len(args)) params := make([]interface{}, len(args))
for i := 0; i < len(params); i += 2 { for i := 0; i < len(params); i += 2 {
score, err := strconv.ParseInt(hack.String(args[i]), 10, 64) score, err := StrInt64(args[i], nil)
if err != nil { if err != nil {
return err return err
} }
@ -102,7 +101,7 @@ func zincrbyCommand(c *client) error {
key := args[0] key := args[0]
delta, err := strconv.ParseInt(hack.String(args[1]), 10, 64) delta, err := StrInt64(args[1], nil)
if err != nil { if err != nil {
return err return err
} }
@ -117,7 +116,7 @@ func zincrbyCommand(c *client) error {
} }
func zparseScoreRange(minBuf []byte, maxBuf []byte) (min int64, max int64, err error) { func zparseScoreRange(minBuf []byte, maxBuf []byte) (min int64, max int64, err error) {
if strings.ToLower(hack.String(minBuf)) == "-inf" { if strings.ToLower(String(minBuf)) == "-inf" {
min = math.MinInt64 min = math.MinInt64
} else { } else {
var lopen bool = false var lopen bool = false
@ -131,7 +130,7 @@ func zparseScoreRange(minBuf []byte, maxBuf []byte) (min int64, max int64, err e
return return
} }
min, err = strconv.ParseInt(hack.String(minBuf), 10, 64) min, err = StrInt64(minBuf, nil)
if err != nil { if err != nil {
return return
} }
@ -146,7 +145,7 @@ func zparseScoreRange(minBuf []byte, maxBuf []byte) (min int64, max int64, err e
} }
} }
if strings.ToLower(hack.String(maxBuf)) == "+inf" { if strings.ToLower(String(maxBuf)) == "+inf" {
max = math.MaxInt64 max = math.MaxInt64
} else { } else {
var ropen = false var ropen = false
@ -160,7 +159,7 @@ func zparseScoreRange(minBuf []byte, maxBuf []byte) (min int64, max int64, err e
return return
} }
max, err = strconv.ParseInt(hack.String(maxBuf), 10, 64) max, err = StrInt64(maxBuf, nil)
if err != nil { if err != nil {
return return
} }
@ -288,11 +287,11 @@ func zremrangebyscoreCommand(c *client) error {
func zparseRange(c *client, key []byte, startBuf []byte, stopBuf []byte) (offset int, limit int, err error) { func zparseRange(c *client, key []byte, startBuf []byte, stopBuf []byte) (offset int, limit int, err error) {
var start int var start int
var stop int var stop int
if start, err = strconv.Atoi(hack.String(startBuf)); err != nil { if start, err = strconv.Atoi(String(startBuf)); err != nil {
return return
} }
if stop, err = strconv.Atoi(hack.String(stopBuf)); err != nil { if stop, err = strconv.Atoi(String(stopBuf)); err != nil {
return return
} }
@ -354,7 +353,7 @@ func zrangeGeneric(c *client, reverse bool) error {
args = args[3:] args = args[3:]
var withScores bool = false var withScores bool = false
if len(args) > 0 && strings.ToLower(hack.String(args[0])) == "withscores" { if len(args) > 0 && strings.ToLower(String(args[0])) == "withscores" {
withScores = true withScores = true
} }
@ -390,7 +389,7 @@ func zrangebyscoreGeneric(c *client, reverse bool) error {
var withScores bool = false var withScores bool = false
if len(args) > 0 && strings.ToLower(hack.String(args[0])) == "withscores" { if len(args) > 0 && strings.ToLower(String(args[0])) == "withscores" {
withScores = true withScores = true
args = args[1:] args = args[1:]
} }
@ -403,15 +402,15 @@ func zrangebyscoreGeneric(c *client, reverse bool) error {
return ErrCmdParams return ErrCmdParams
} }
if strings.ToLower(hack.String(args[0])) != "limit" { if strings.ToLower(String(args[0])) != "limit" {
return ErrCmdParams return ErrCmdParams
} }
if offset, err = strconv.Atoi(hack.String(args[1])); err != nil { if offset, err = strconv.Atoi(String(args[1])); err != nil {
return ErrCmdParams return ErrCmdParams
} }
if limit, err = strconv.Atoi(hack.String(args[2])); err != nil { if limit, err = strconv.Atoi(String(args[2])); err != nil {
return ErrCmdParams return ErrCmdParams
} }
} }

View File

@ -2,7 +2,7 @@ package ledis
import ( import (
"encoding/json" "encoding/json"
"github.com/siddontang/golib/leveldb" "github.com/siddontang/go-leveldb/leveldb"
"io/ioutil" "io/ioutil"
) )

View File

@ -3,9 +3,7 @@ package ledis
import ( import (
"encoding/binary" "encoding/binary"
"errors" "errors"
"github.com/siddontang/golib/hack" "github.com/siddontang/go-leveldb/leveldb"
"github.com/siddontang/golib/leveldb"
"strconv"
) )
var errHashKey = errors.New("invalid hash key") var errHashKey = errors.New("invalid hash key")
@ -90,26 +88,21 @@ func decode_hash_key(ek []byte) ([]byte, []byte, error) {
} }
func (a *App) hash_len(key []byte) (int64, error) { func (a *App) hash_len(key []byte) (int64, error) {
return a.db.GetInt(encode_hsize_key(key)) return Int64(a.db.Get(encode_hsize_key(key)))
} }
func (a *App) hash_setItem(key []byte, field []byte, value []byte) (int64, error) { func (a *App) hash_setItem(key []byte, field []byte, value []byte) (int64, error) {
t := a.hashTx t := a.hashTx
ek := encode_hash_key(key, field) ek := encode_hash_key(key, field)
sk := encode_hsize_key(key)
size, err := a.db.GetInt(sk)
if err != nil {
return 0, err
}
var n int64 = 1 var n int64 = 1
if v, _ := a.db.Get(ek); v != nil { if v, _ := a.db.Get(ek); v != nil {
n = 0 n = 0
} else { } else {
size++ if _, err := a.hash_incrSize(key, 1); err != nil {
t.Put(sk, hack.Slice(strconv.FormatInt(size, 10))) return 0, err
}
} }
t.Put(ek, value) t.Put(ek, value)
@ -137,30 +130,26 @@ func (a *App) hash_get(key []byte, field []byte) ([]byte, error) {
} }
func (a *App) hash_mset(key []byte, args [][]byte) error { func (a *App) hash_mset(key []byte, args [][]byte) error {
sk := encode_hsize_key(key)
t := a.hashTx t := a.hashTx
t.Lock() t.Lock()
defer t.Unlock() defer t.Unlock()
size, err := a.db.GetInt(sk) var num int64 = 0
if err != nil {
return err
}
for i := 0; i < len(args); i += 2 { for i := 0; i < len(args); i += 2 {
ek := encode_hash_key(key, args[i]) ek := encode_hash_key(key, args[i])
if v, _ := a.db.Get(ek); v == nil { if v, _ := a.db.Get(ek); v == nil {
size++ num++
} }
t.Put(ek, args[i+1]) t.Put(ek, args[i+1])
} }
t.Put(sk, hack.Slice(strconv.FormatInt(size, 10))) if _, err := a.hash_incrSize(key, num); err != nil {
return err
}
//todo add binglog //todo add binglog
err = t.Commit() err := t.Commit()
return err return err
} }
@ -179,17 +168,10 @@ func (a *App) hash_mget(key []byte, args [][]byte) ([]interface{}, error) {
} }
func (a *App) hash_del(key []byte, args [][]byte) (int64, error) { func (a *App) hash_del(key []byte, args [][]byte) (int64, error) {
sk := encode_hsize_key(key)
t := a.hashTx t := a.hashTx
t.Lock() t.Lock()
defer t.Unlock() defer t.Unlock()
size, err := a.db.GetInt(sk)
if err != nil {
return 0, err
}
var num int64 = 0 var num int64 = 0
for i := 0; i < len(args); i++ { for i := 0; i < len(args); i++ {
ek := encode_hash_key(key, args[i]) ek := encode_hash_key(key, args[i])
@ -199,22 +181,38 @@ func (a *App) hash_del(key []byte, args [][]byte) (int64, error) {
continue continue
} else { } else {
num++ num++
size--
t.Delete(ek) t.Delete(ek)
} }
} }
if size <= 0 { if _, err := a.hash_incrSize(key, -num); err != nil {
t.Delete(sk) return 0, err
} else {
t.Put(sk, hack.Slice(strconv.FormatInt(size, 10)))
} }
err = t.Commit() err := t.Commit()
return num, err return num, err
} }
func (a *App) hash_incrSize(key []byte, delta int64) (int64, error) {
t := a.hashTx
sk := encode_hsize_key(key)
size, err := Int64(a.db.Get(sk))
if err != nil {
return 0, err
} else {
size += delta
if size <= 0 {
size = 0
t.Delete(sk)
} else {
t.Put(sk, PutInt64(size))
}
}
return size, nil
}
func (a *App) hash_incrby(key []byte, field []byte, delta int64) (int64, error) { func (a *App) hash_incrby(key []byte, field []byte, delta int64) (int64, error) {
t := a.hashTx t := a.hashTx
t.Lock() t.Lock()
@ -223,18 +221,14 @@ func (a *App) hash_incrby(key []byte, field []byte, delta int64) (int64, error)
ek := encode_hash_key(key, field) ek := encode_hash_key(key, field)
var n int64 = 0 var n int64 = 0
v, err := a.db.Get(ek) n, err := StrInt64(a.db.Get(ek))
if err != nil { if err != nil {
return 0, err return 0, err
} else if v != nil {
if n, err = strconv.ParseInt(hack.String(v), 10, 64); err != nil {
return 0, err
}
} }
n += delta n += delta
_, err = a.hash_setItem(key, field, hack.Slice(strconv.FormatInt(n, 10))) _, err = a.hash_setItem(key, field, StrPutInt64(n))
if err != nil { if err != nil {
return 0, err return 0, err
} }

View File

@ -2,8 +2,6 @@ package ledis
import ( import (
"errors" "errors"
"github.com/siddontang/golib/hack"
"strconv"
) )
var errKVKey = errors.New("invalid encode kv key") var errKVKey = errors.New("invalid encode kv key")
@ -117,14 +115,14 @@ func (a *App) kv_incr(key []byte, delta int64) (int64, error) {
defer t.Unlock() defer t.Unlock()
var n int64 var n int64
n, err = a.db.GetInt(key) n, err = StrInt64(a.db.Get(key))
if err != nil { if err != nil {
return 0, err return 0, err
} }
n += delta n += delta
t.Put(key, hack.Slice(strconv.FormatInt(n, 10))) t.Put(key, StrPutInt64(n))
//todo binlog //todo binlog

View File

@ -3,7 +3,7 @@ package ledis
import ( import (
"encoding/binary" "encoding/binary"
"errors" "errors"
"github.com/siddontang/golib/leveldb" "github.com/siddontang/go-leveldb/leveldb"
) )
const ( const (

View File

@ -4,8 +4,7 @@ import (
"bytes" "bytes"
"encoding/binary" "encoding/binary"
"errors" "errors"
"github.com/siddontang/golib/hack" "github.com/siddontang/go-leveldb/leveldb"
"github.com/siddontang/golib/leveldb"
"strconv" "strconv"
) )
@ -262,7 +261,7 @@ func (a *App) zset_score(key []byte, member []byte) ([]byte, error) {
return nil, err return nil, err
} }
return hack.Slice(strconv.FormatInt(score, 10)), nil return Slice(strconv.FormatInt(score, 10)), nil
} }
func (a *App) zset_rem(key []byte, args [][]byte) (int64, error) { func (a *App) zset_rem(key []byte, args [][]byte) (int64, error) {
@ -319,7 +318,7 @@ func (a *App) zset_incrby(key []byte, delta int64, member []byte) ([]byte, error
t.Put(encode_zscore_key(key, member, score), []byte{}) t.Put(encode_zscore_key(key, member, score), []byte{})
err = t.Commit() err = t.Commit()
return hack.Slice(strconv.FormatInt(score, 10)), err return Slice(strconv.FormatInt(score, 10)), err
} }
func (a *App) zset_count(key []byte, min int64, max int64) (int64, error) { func (a *App) zset_count(key []byte, min int64, max int64) (int64, error) {
@ -471,7 +470,7 @@ func (a *App) zset_range(key []byte, min int64, max int64, withScores bool, offs
v = append(v, m) v = append(v, m)
if withScores { if withScores {
v = append(v, hack.Slice(strconv.FormatInt(s, 10))) v = append(v, Slice(strconv.FormatInt(s, 10)))
} }
} }

View File

@ -1,7 +1,7 @@
package ledis package ledis
import ( import (
"github.com/siddontang/golib/leveldb" "github.com/siddontang/go-leveldb/leveldb"
"sync" "sync"
) )

View File

@ -3,11 +3,34 @@ package ledis
import ( import (
"encoding/binary" "encoding/binary"
"errors" "errors"
"github.com/siddontang/golib/hack" "reflect"
"strconv"
"unsafe"
) )
var errIntNumber = errors.New("invalid integer") var errIntNumber = errors.New("invalid integer")
// no copy to change slice to string
// use your own risk
func String(b []byte) (s string) {
pbytes := (*reflect.SliceHeader)(unsafe.Pointer(&b))
pstring := (*reflect.StringHeader)(unsafe.Pointer(&s))
pstring.Data = pbytes.Data
pstring.Len = pbytes.Len
return
}
// no copy to change string to slice
// use your own risk
func Slice(s string) (b []byte) {
pbytes := (*reflect.SliceHeader)(unsafe.Pointer(&b))
pstring := (*reflect.StringHeader)(unsafe.Pointer(&s))
pbytes.Data = pstring.Data
pbytes.Len = pstring.Len
pbytes.Cap = pstring.Len
return
}
func Int64(v []byte, err error) (int64, error) { func Int64(v []byte, err error) (int64, error) {
if err != nil { if err != nil {
return 0, err return 0, err
@ -21,9 +44,24 @@ func Int64(v []byte, err error) (int64, error) {
} }
func PutInt64(v int64) []byte { func PutInt64(v int64) []byte {
return hack.Int64Slice(v) var b []byte
pbytes := (*reflect.SliceHeader)(unsafe.Pointer(&b))
pbytes.Data = uintptr(unsafe.Pointer(&v))
pbytes.Len = 8
pbytes.Cap = 8
return b
} }
func PutInt32(v int32) []byte { func StrInt64(v []byte, err error) (int64, error) {
return hack.Int32Slice(v) if err != nil {
return 0, err
} else if v == nil {
return 0, nil
} else {
return strconv.ParseInt(String(v), 10, 64)
}
}
func StrPutInt64(v int64) []byte {
return Slice(strconv.FormatInt(v, 10))
} }