diff --git a/cmd/ledis-server/main.go b/cmd/ledis-server/main.go index 5fda7b3..8a76984 100644 --- a/cmd/ledis-server/main.go +++ b/cmd/ledis-server/main.go @@ -2,7 +2,7 @@ package main import ( "flag" - "github.com/siddontang/ledisdb/ledis" + "github.com/siddontang/ledisdb/server" "os" "os/signal" "runtime" @@ -20,13 +20,13 @@ func main() { panic("must use a config file") } - cfg, err := ledis.NewConfigWithFile(*configFile) + cfg, err := server.NewConfigWithFile(*configFile) if err != nil { panic(err) } - var app *ledis.App - app, err = ledis.NewApp(cfg) + var app *server.App + app, err = server.NewApp(cfg) if err != nil { panic(err) } diff --git a/ledis/db_test.go b/ledis/db_test.go new file mode 100644 index 0000000..683882a --- /dev/null +++ b/ledis/db_test.go @@ -0,0 +1,41 @@ +package ledis + +import ( + "sync" + "testing" +) + +var testDB *DB +var testDBOnce sync.Once + +func getTestDB() *DB { + f := func() { + var d = []byte(` + { + "data_db" : { + "path" : "/tmp/testdb", + "compression":true, + "block_size" : 32768, + "write_buffer_size" : 2097152, + "cache_size" : 20971520 + } + } + `) + db, err := OpenDB(d) + if err != nil { + println(err.Error()) + panic(err) + } + + testDB = db + + testDB.db.Clear() + } + + testDBOnce.Do(f) + return testDB +} + +func TestDB(t *testing.T) { + getTestDB() +} diff --git a/ledis/t_hash.go b/ledis/t_hash.go index 7ed6914..f6e8826 100644 --- a/ledis/t_hash.go +++ b/ledis/t_hash.go @@ -21,14 +21,14 @@ const ( func encode_hsize_key(key []byte) []byte { buf := make([]byte, len(key)+1) - buf[0] = HSIZE_TYPE + buf[0] = hSizeType copy(buf[1:], key) return buf } func decode_hsize_key(ek []byte) ([]byte, error) { - if len(ek) == 0 || ek[0] != HSIZE_TYPE { + if len(ek) == 0 || ek[0] != hSizeType { return nil, errHSizeKey } @@ -39,7 +39,7 @@ func encode_hash_key(key []byte, field []byte) []byte { buf := make([]byte, len(key)+len(field)+1+4+1) pos := 0 - buf[pos] = HASH_TYPE + buf[pos] = hashType pos++ binary.BigEndian.PutUint32(buf[pos:], uint32(len(key))) pos += 4 @@ -68,7 +68,7 @@ func encode_hash_stop_key(key []byte) []byte { } func decode_hash_key(ek []byte) ([]byte, []byte, error) { - if len(ek) < 6 || ek[0] != HASH_TYPE { + if len(ek) < 6 || ek[0] != hashType { return nil, nil, errHashKey } diff --git a/ledis/t_kv.go b/ledis/t_kv.go index f30af86..5df995b 100644 --- a/ledis/t_kv.go +++ b/ledis/t_kv.go @@ -13,13 +13,13 @@ var errKVKey = errors.New("invalid encode kv key") func encode_kv_key(key []byte) []byte { ek := make([]byte, len(key)+1) - ek[0] = KV_TYPE + ek[0] = kvType copy(ek[1:], key) return ek } func decode_kv_key(ek []byte) ([]byte, error) { - if len(ek) == 0 || ek[0] != KV_TYPE { + if len(ek) == 0 || ek[0] != kvType { return nil, errKVKey } diff --git a/ledis/t_list.go b/ledis/t_list.go index ab65c82..2a8aa3e 100644 --- a/ledis/t_list.go +++ b/ledis/t_list.go @@ -21,14 +21,14 @@ var errListSeq = errors.New("invalid list sequence, overflow") func encode_lmeta_key(key []byte) []byte { buf := make([]byte, len(key)+1) - buf[0] = LMETA_TYPE + buf[0] = lMetaType copy(buf[1:], key) return buf } func decode_lmeta_key(ek []byte) ([]byte, error) { - if len(ek) == 0 || ek[0] != LMETA_TYPE { + if len(ek) == 0 || ek[0] != lMetaType { return nil, errLMetaKey } @@ -39,7 +39,7 @@ func encode_list_key(key []byte, seq int32) []byte { buf := make([]byte, len(key)+9) pos := 0 - buf[pos] = LIST_TYPE + buf[pos] = listType pos++ binary.BigEndian.PutUint32(buf[pos:], uint32(len(key))) @@ -54,7 +54,7 @@ func encode_list_key(key []byte, seq int32) []byte { } func decode_list_key(ek []byte) (key []byte, seq int32, err error) { - if len(ek) < 9 || ek[0] != LIST_TYPE { + if len(ek) < 9 || ek[0] != listType { err = errListKey return } diff --git a/ledis/t_zset.go b/ledis/t_zset.go index a7b305e..013e66b 100644 --- a/ledis/t_zset.go +++ b/ledis/t_zset.go @@ -20,6 +20,7 @@ type ScorePair struct { var errZSizeKey = errors.New("invalid zsize key") var errZSetKey = errors.New("invalid zset key") var errZScoreKey = errors.New("invalid zscore key") +var errScoreOverflow = errors.New("zset score overflow") const ( zsetNScoreSep byte = '<' @@ -32,14 +33,14 @@ const ( func encode_zsize_key(key []byte) []byte { buf := make([]byte, len(key)+1) - buf[0] = ZSIZE_TYPE + buf[0] = zSizeType copy(buf[1:], key) return buf } func decode_zsize_key(ek []byte) ([]byte, error) { - if len(ek) == 0 || ek[0] != ZSIZE_TYPE { + if len(ek) == 0 || ek[0] != zSizeType { return nil, errZSizeKey } @@ -50,7 +51,7 @@ func encode_zset_key(key []byte, member []byte) []byte { buf := make([]byte, len(key)+len(member)+5) pos := 0 - buf[pos] = ZSET_TYPE + buf[pos] = zsetType pos++ binary.BigEndian.PutUint32(buf[pos:], uint32(len(key))) @@ -65,7 +66,7 @@ func encode_zset_key(key []byte, member []byte) []byte { } func decode_zset_key(ek []byte) ([]byte, []byte, error) { - if len(ek) < 5 || ek[0] != ZSET_TYPE { + if len(ek) < 5 || ek[0] != zsetType { return nil, nil, errZSetKey } @@ -83,7 +84,7 @@ func encode_zscore_key(key []byte, member []byte, score int64) []byte { buf := make([]byte, len(key)+len(member)+15) pos := 0 - buf[pos] = ZSCORE_TYPE + buf[pos] = zScoreType pos++ binary.BigEndian.PutUint32(buf[pos:], uint32(len(key))) @@ -121,7 +122,7 @@ func encode_stop_zscore_key(key []byte, score int64) []byte { } func decode_zscore_key(ek []byte) (key []byte, member []byte, score int64, err error) { - if len(ek) < 15 || ek[0] != ZSCORE_TYPE { + if len(ek) < 15 || ek[0] != zScoreType { err = errZScoreKey return } diff --git a/ledis/app.go b/server/app.go similarity index 86% rename from ledis/app.go rename to server/app.go index 5cbdacd..99e7dce 100644 --- a/ledis/app.go +++ b/server/app.go @@ -1,6 +1,7 @@ -package ledis +package server import ( + "github.com/siddontang/ledisdb/ledis" "net" "strings" ) @@ -10,7 +11,7 @@ type App struct { listener net.Listener - db *DB + db *ledis.DB closed bool } @@ -34,7 +35,7 @@ func NewApp(cfg *Config) (*App, error) { return nil, err } - app.db, err = OpenDBWithConfig(&cfg.DB) + app.db, err = ledis.OpenDBWithConfig(&cfg.DB) if err != nil { return nil, err } diff --git a/ledis/app_test.go b/server/app_test.go similarity index 94% rename from ledis/app_test.go rename to server/app_test.go index c80fccb..2293ce2 100644 --- a/ledis/app_test.go +++ b/server/app_test.go @@ -1,4 +1,4 @@ -package ledis +package server import ( "github.com/garyburd/redigo/redis" @@ -30,12 +30,6 @@ func getTestConn() redis.Conn { return testPool.Get() } -func getTestDB() *DB { - startTestApp() - - return testApp.db -} - func startTestApp() { f := func() { newTestRedisPool() diff --git a/ledis/client.go b/server/client.go similarity index 86% rename from ledis/client.go rename to server/client.go index 6b9b1ed..f89f38e 100644 --- a/ledis/client.go +++ b/server/client.go @@ -1,9 +1,10 @@ -package ledis +package server import ( "bufio" "errors" "github.com/siddontang/golib/log" + "github.com/siddontang/ledisdb/ledis" "io" "net" "runtime" @@ -14,7 +15,7 @@ import ( var errReadRequest = errors.New("invalid request protocol") type client struct { - db *DB + db *ledis.DB c net.Conn rb *bufio.Reader @@ -26,7 +27,7 @@ type client struct { reqC chan error } -func newClient(c net.Conn, db *DB) { +func newClient(c net.Conn, db *ledis.DB) { co := new(client) co.db = db co.c = c @@ -91,7 +92,7 @@ func (c *client) readRequest() ([][]byte, error) { } var nparams int - if nparams, err = strconv.Atoi(String(l[1:])); err != nil { + if nparams, err = strconv.Atoi(ledis.String(l[1:])); err != nil { return nil, err } else if nparams <= 0 { return nil, errReadRequest @@ -108,7 +109,7 @@ func (c *client) readRequest() ([][]byte, error) { return nil, errReadRequest } else if l[0] == '$' { //handle resp string - if n, err = strconv.Atoi(String(l[1:])); err != nil { + if n, err = strconv.Atoi(ledis.String(l[1:])); err != nil { return nil, err } else if n == -1 { req = append(req, nil) @@ -138,7 +139,7 @@ func (c *client) handleRequest(req [][]byte) { if len(req) == 0 { err = ErrEmptyCommand } else { - c.cmd = strings.ToLower(String(req[0])) + c.cmd = strings.ToLower(ledis.String(req[0])) c.args = req[1:] f, ok := regCmds[c.cmd] @@ -160,23 +161,23 @@ func (c *client) handleRequest(req [][]byte) { } func (c *client) writeError(err error) { - c.wb.Write(Slice("-ERR")) + c.wb.Write(ledis.Slice("-ERR")) if err != nil { c.wb.WriteByte(' ') - c.wb.Write(Slice(err.Error())) + c.wb.Write(ledis.Slice(err.Error())) } c.wb.Write(Delims) } func (c *client) writeStatus(status string) { c.wb.WriteByte('+') - c.wb.Write(Slice(status)) + c.wb.Write(ledis.Slice(status)) c.wb.Write(Delims) } func (c *client) writeInteger(n int64) { c.wb.WriteByte(':') - c.wb.Write(StrPutInt64(n)) + c.wb.Write(ledis.StrPutInt64(n)) c.wb.Write(Delims) } @@ -185,7 +186,7 @@ func (c *client) writeBulk(b []byte) { if b == nil { c.wb.Write(NullBulk) } else { - c.wb.Write(Slice(strconv.Itoa(len(b)))) + c.wb.Write(ledis.Slice(strconv.Itoa(len(b)))) c.wb.Write(Delims) c.wb.Write(b) } @@ -199,7 +200,7 @@ func (c *client) writeArray(ay []interface{}) { c.wb.Write(NullArray) c.wb.Write(Delims) } else { - c.wb.Write(Slice(strconv.Itoa(len(ay)))) + c.wb.Write(ledis.Slice(strconv.Itoa(len(ay)))) c.wb.Write(Delims) for i := 0; i < len(ay); i++ { diff --git a/ledis/cmd_hash.go b/server/cmd_hash.go similarity index 95% rename from ledis/cmd_hash.go rename to server/cmd_hash.go index 1fe2c18..b86e339 100644 --- a/ledis/cmd_hash.go +++ b/server/cmd_hash.go @@ -1,6 +1,8 @@ -package ledis +package server -import () +import ( + "github.com/siddontang/ledisdb/ledis" +) func hsetCommand(c *client) error { args := c.args @@ -87,7 +89,7 @@ func hincrbyCommand(c *client) error { return ErrCmdParams } - delta, err := StrInt64(args[2], nil) + delta, err := ledis.StrInt64(args[2], nil) if err != nil { return err } @@ -115,7 +117,7 @@ func hmsetCommand(c *client) error { args = args[1:] - kvs := make([]FVPair, len(args)/2) + kvs := make([]ledis.FVPair, len(args)/2) for i := 0; i < len(kvs); i++ { kvs[i].Field = args[2*i] kvs[i].Value = args[2*i+1] diff --git a/ledis/cmd_hash_test.go b/server/cmd_hash_test.go similarity index 99% rename from ledis/cmd_hash_test.go rename to server/cmd_hash_test.go index e292cd3..26b0b47 100644 --- a/ledis/cmd_hash_test.go +++ b/server/cmd_hash_test.go @@ -1,4 +1,4 @@ -package ledis +package server import ( "fmt" diff --git a/ledis/cmd_kv.go b/server/cmd_kv.go similarity index 94% rename from ledis/cmd_kv.go rename to server/cmd_kv.go index b41f853..a6bdcbd 100644 --- a/ledis/cmd_kv.go +++ b/server/cmd_kv.go @@ -1,6 +1,8 @@ -package ledis +package server -import () +import ( + "github.com/siddontang/ledisdb/ledis" +) func getCommand(c *client) error { args := c.args @@ -112,7 +114,7 @@ func incrbyCommand(c *client) error { return ErrCmdParams } - delta, err := StrInt64(args[1], nil) + delta, err := ledis.StrInt64(args[1], nil) if err != nil { return err } @@ -132,7 +134,7 @@ func decrbyCommand(c *client) error { return ErrCmdParams } - delta, err := StrInt64(args[1], nil) + delta, err := ledis.StrInt64(args[1], nil) if err != nil { return err } @@ -167,7 +169,7 @@ func msetCommand(c *client) error { return ErrCmdParams } - kvs := make([]KVPair, len(args)/2) + kvs := make([]ledis.KVPair, len(args)/2) for i := 0; i < len(kvs); i++ { kvs[i].Key = args[2*i] kvs[i].Value = args[2*i+1] diff --git a/ledis/cmd_kv_test.go b/server/cmd_kv_test.go similarity index 99% rename from ledis/cmd_kv_test.go rename to server/cmd_kv_test.go index ced52b7..8318a97 100644 --- a/ledis/cmd_kv_test.go +++ b/server/cmd_kv_test.go @@ -1,4 +1,4 @@ -package ledis +package server import ( "github.com/garyburd/redigo/redis" diff --git a/ledis/cmd_list.go b/server/cmd_list.go similarity index 91% rename from ledis/cmd_list.go rename to server/cmd_list.go index 18847ef..193e27d 100644 --- a/ledis/cmd_list.go +++ b/server/cmd_list.go @@ -1,6 +1,8 @@ -package ledis +package server -import () +import ( + "github.com/siddontang/ledisdb/ledis" +) func lpushCommand(c *client) error { args := c.args @@ -83,7 +85,7 @@ func lindexCommand(c *client) error { return ErrCmdParams } - index, err := StrInt64(args[1], nil) + index, err := ledis.StrInt64(args[1], nil) if err != nil { return err } @@ -107,12 +109,12 @@ func lrangeCommand(c *client) error { var stop int64 var err error - start, err = StrInt64(args[1], nil) + start, err = ledis.StrInt64(args[1], nil) if err != nil { return err } - stop, err = StrInt64(args[2], nil) + stop, err = ledis.StrInt64(args[2], nil) if err != nil { return err } diff --git a/ledis/cmd_list_test.go b/server/cmd_list_test.go similarity index 99% rename from ledis/cmd_list_test.go rename to server/cmd_list_test.go index 5b40fb3..58bab33 100644 --- a/ledis/cmd_list_test.go +++ b/server/cmd_list_test.go @@ -1,4 +1,4 @@ -package ledis +package server import ( "fmt" diff --git a/ledis/cmd_zset.go b/server/cmd_zset.go similarity index 86% rename from ledis/cmd_zset.go rename to server/cmd_zset.go index f30f8de..c7f26b5 100644 --- a/ledis/cmd_zset.go +++ b/server/cmd_zset.go @@ -1,7 +1,8 @@ -package ledis +package server import ( "errors" + "github.com/siddontang/ledisdb/ledis" "math" "strconv" "strings" @@ -24,9 +25,9 @@ func zaddCommand(c *client) error { args = args[1:] - params := make([]ScorePair, len(args)/2) + params := make([]ledis.ScorePair, len(args)/2) for i := 0; i < len(params); i++ { - score, err := StrInt64(args[2*i], nil) + score, err := ledis.StrInt64(args[2*i], nil) if err != nil { return err } @@ -97,7 +98,7 @@ func zincrbyCommand(c *client) error { key := args[0] - delta, err := StrInt64(args[1], nil) + delta, err := ledis.StrInt64(args[1], nil) if err != nil { return err } @@ -112,7 +113,7 @@ func zincrbyCommand(c *client) error { } func zparseScoreRange(minBuf []byte, maxBuf []byte) (min int64, max int64, err error) { - if strings.ToLower(String(minBuf)) == "-inf" { + if strings.ToLower(ledis.String(minBuf)) == "-inf" { min = math.MinInt64 } else { var lopen bool = false @@ -126,12 +127,12 @@ func zparseScoreRange(minBuf []byte, maxBuf []byte) (min int64, max int64, err e return } - min, err = StrInt64(minBuf, nil) + min, err = ledis.StrInt64(minBuf, nil) if err != nil { return } - if min <= MinScore || min >= MaxScore { + if min <= ledis.MinScore || min >= ledis.MaxScore { err = errScoreOverflow return } @@ -141,7 +142,7 @@ func zparseScoreRange(minBuf []byte, maxBuf []byte) (min int64, max int64, err e } } - if strings.ToLower(String(maxBuf)) == "+inf" { + if strings.ToLower(ledis.String(maxBuf)) == "+inf" { max = math.MaxInt64 } else { var ropen = false @@ -155,12 +156,12 @@ func zparseScoreRange(minBuf []byte, maxBuf []byte) (min int64, max int64, err e return } - max, err = StrInt64(maxBuf, nil) + max, err = ledis.StrInt64(maxBuf, nil) if err != nil { return } - if max <= MinScore || max >= MaxScore { + if max <= ledis.MinScore || max >= ledis.MaxScore { err = errScoreOverflow return } @@ -276,11 +277,11 @@ func zremrangebyscoreCommand(c *client) error { } func zparseRange(c *client, a1 []byte, a2 []byte) (start int, stop int, err error) { - if start, err = strconv.Atoi(String(a1)); err != nil { + if start, err = strconv.Atoi(ledis.String(a1)); err != nil { return } - if stop, err = strconv.Atoi(String(a2)); err != nil { + if stop, err = strconv.Atoi(ledis.String(a2)); err != nil { return } @@ -303,7 +304,7 @@ func zrangeGeneric(c *client, reverse bool) error { args = args[3:] var withScores bool = false - if len(args) > 0 && strings.ToLower(String(args[0])) == "withscores" { + if len(args) > 0 && strings.ToLower(ledis.String(args[0])) == "withscores" { withScores = true } @@ -339,7 +340,7 @@ func zrangebyscoreGeneric(c *client, reverse bool) error { var withScores bool = false - if len(args) > 0 && strings.ToLower(String(args[0])) == "withscores" { + if len(args) > 0 && strings.ToLower(ledis.String(args[0])) == "withscores" { withScores = true args = args[1:] } @@ -352,15 +353,15 @@ func zrangebyscoreGeneric(c *client, reverse bool) error { return ErrCmdParams } - if strings.ToLower(String(args[0])) != "limit" { + if strings.ToLower(ledis.String(args[0])) != "limit" { return ErrCmdParams } - if offset, err = strconv.Atoi(String(args[1])); err != nil { + if offset, err = strconv.Atoi(ledis.String(args[1])); err != nil { return ErrCmdParams } - if count, err = strconv.Atoi(String(args[2])); err != nil { + if count, err = strconv.Atoi(ledis.String(args[2])); err != nil { return ErrCmdParams } } diff --git a/ledis/cmd_zset_test.go b/server/cmd_zset_test.go similarity index 90% rename from ledis/cmd_zset_test.go rename to server/cmd_zset_test.go index e8d4b11..8ac59ab 100644 --- a/ledis/cmd_zset_test.go +++ b/server/cmd_zset_test.go @@ -1,61 +1,12 @@ -package ledis +package server import ( - "bytes" "fmt" "github.com/garyburd/redigo/redis" "strconv" "testing" ) -func TestCodecZSet(t *testing.T) { - key := []byte("a") - - ek := encode_zsize_key(key) - - if k, err := decode_zsize_key(ek); err != nil { - t.Fatal(err) - } else if !bytes.Equal(key, k) { - t.Fatal(string(k)) - } - - member := []byte("f") - - ek = encode_zset_key(key, member) - - if k, m, err := decode_zset_key(ek); err != nil { - t.Fatal(err) - } else if !bytes.Equal(key, k) { - t.Fatal(string(k)) - } else if !bytes.Equal(member, m) { - t.Fatal(string(m)) - } - - ek = encode_zscore_key(key, member, 3) - - if k, m, s, err := decode_zscore_key(ek); err != nil { - t.Fatal(err) - } else if !bytes.Equal(key, k) { - t.Fatal(string(k)) - } else if !bytes.Equal(member, m) { - t.Fatal(string(m)) - } else if s != 3 { - t.Fatal(s) - } - - ek = encode_zscore_key(key, member, -3) - - if k, m, s, err := decode_zscore_key(ek); err != nil { - t.Fatal(err) - } else if !bytes.Equal(key, k) { - t.Fatal(string(k)) - } else if !bytes.Equal(member, m) { - t.Fatal(string(m)) - } else if s != -3 { - t.Fatal(s) - } -} - func TestZSet(t *testing.T) { c := getTestConn() defer c.Close() diff --git a/ledis/command.go b/server/command.go similarity index 97% rename from ledis/command.go rename to server/command.go index 39a855f..0a64810 100644 --- a/ledis/command.go +++ b/server/command.go @@ -1,4 +1,4 @@ -package ledis +package server import ( "fmt" diff --git a/ledis/config.go b/server/config.go similarity index 83% rename from ledis/config.go rename to server/config.go index 78abf7d..ee9b503 100644 --- a/ledis/config.go +++ b/server/config.go @@ -1,14 +1,15 @@ -package ledis +package server import ( "encoding/json" + "github.com/siddontang/ledisdb/ledis" "io/ioutil" ) type Config struct { Addr string `json:"addr"` - DB DBConfig `json:"db"` + DB ledis.DBConfig `json:"db"` } func NewConfig(data json.RawMessage) (*Config, error) { diff --git a/ledis/const.go b/server/const.go similarity index 69% rename from ledis/const.go rename to server/const.go index 235053f..36235a8 100644 --- a/ledis/const.go +++ b/server/const.go @@ -1,4 +1,4 @@ -package ledis +package server import ( "errors" @@ -19,14 +19,3 @@ var ( PONG = "PONG" OK = "OK" ) - -const ( - KV_TYPE byte = iota + 1 - HASH_TYPE - HSIZE_TYPE - LIST_TYPE - LMETA_TYPE - ZSET_TYPE - ZSIZE_TYPE - ZSCORE_TYPE -)