From 1e6bcc6a5012a329882de52f35a0cca056130be7 Mon Sep 17 00:00:00 2001 From: siddontang Date: Tue, 1 Jul 2014 07:55:34 +0800 Subject: [PATCH 1/2] bugfix for revrangebyscore command min and max score param position may be same as redis --- server/cmd_zset.go | 12 +++++++++++- server/cmd_zset_test.go | 8 ++++---- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/server/cmd_zset.go b/server/cmd_zset.go index d51c825..eb25073 100644 --- a/server/cmd_zset.go +++ b/server/cmd_zset.go @@ -335,7 +335,17 @@ func zrangebyscoreGeneric(c *client, reverse bool) error { } key := args[0] - min, max, err := zparseScoreRange(args[1], args[2]) + + var minScore, maxScore []byte + + if !reverse { + minScore, maxScore = args[1], args[2] + } else { + minScore, maxScore = args[2], args[1] + } + + min, max, err := zparseScoreRange(minScore, maxScore) + if err != nil { return err } diff --git a/server/cmd_zset_test.go b/server/cmd_zset_test.go index 69664cf..cf512c7 100644 --- a/server/cmd_zset_test.go +++ b/server/cmd_zset_test.go @@ -264,7 +264,7 @@ func TestZSetRangeScore(t *testing.T) { } } - if v, err := ledis.MultiBulk(c.Do("zrevrangebyscore", key, 1, 4, "withscores")); err != nil { + if v, err := ledis.MultiBulk(c.Do("zrevrangebyscore", key, 4, 1, "withscores")); err != nil { t.Fatal(err) } else { if err := testZSetRange(v, "d", 4, "c", 3, "b", 2, "a", 1); err != nil { @@ -272,7 +272,7 @@ func TestZSetRangeScore(t *testing.T) { } } - if v, err := ledis.MultiBulk(c.Do("zrevrangebyscore", key, 1, 4, "withscores", "limit", 1, 2)); err != nil { + if v, err := ledis.MultiBulk(c.Do("zrevrangebyscore", key, 4, 1, "withscores", "limit", 1, 2)); err != nil { t.Fatal(err) } else { if err := testZSetRange(v, "c", 3, "b", 2); err != nil { @@ -280,7 +280,7 @@ func TestZSetRangeScore(t *testing.T) { } } - if v, err := ledis.MultiBulk(c.Do("zrevrangebyscore", key, "-inf", "+inf", "withscores")); err != nil { + if v, err := ledis.MultiBulk(c.Do("zrevrangebyscore", key, "+inf", "-inf", "withscores")); err != nil { t.Fatal(err) } else { if err := testZSetRange(v, "d", 4, "c", 3, "b", 2, "a", 1); err != nil { @@ -288,7 +288,7 @@ func TestZSetRangeScore(t *testing.T) { } } - if v, err := ledis.MultiBulk(c.Do("zrevrangebyscore", key, "(1", "(4")); err != nil { + if v, err := ledis.MultiBulk(c.Do("zrevrangebyscore", key, "(4", "(1")); err != nil { t.Fatal(err) } else { if err := testZSetRange(v, "c", "b"); err != nil { From b13ce1329a3ecca6900b8e161d1ce07a8d062f7a Mon Sep 17 00:00:00 2001 From: siddontang Date: Tue, 1 Jul 2014 09:21:14 +0800 Subject: [PATCH 2/2] bugfix for lrange adjust start and end to be same as redid --- ledis/t_list.go | 51 ++++++++++++++++++++------------------------ ledis/t_list_test.go | 12 +++++++++++ 2 files changed, 35 insertions(+), 28 deletions(-) diff --git a/ledis/t_list.go b/ledis/t_list.go index d6dca0f..60c4bc5 100644 --- a/ledis/t_list.go +++ b/ledis/t_list.go @@ -322,46 +322,41 @@ func (db *DB) LRange(key []byte, start int32, stop int32) ([][]byte, error) { return nil, err } - var startSeq int32 - var stopSeq int32 - - if start > stop { - return [][]byte{}, nil - } - - v := make([][]byte, 0, 16) - var headSeq int32 - var tailSeq int32 + var llen int32 var err error metaKey := db.lEncodeMetaKey(key) - if headSeq, tailSeq, _, err = db.lGetMeta(metaKey); err != nil { + if headSeq, _, llen, err = db.lGetMeta(metaKey); err != nil { return nil, err } - if start >= 0 && stop >= 0 { - startSeq = headSeq + start - stopSeq = headSeq + stop - } else if start < 0 && stop < 0 { - startSeq = tailSeq + start + 1 - stopSeq = tailSeq + stop + 1 - } else { - //start < 0 && stop > 0 - startSeq = tailSeq + start + 1 - stopSeq = headSeq + stop + if start < 0 { + start = llen + start + } + if stop < 0 { + stop = llen + stop + } + if start < 0 { + start = 0 } - if startSeq < listMinSeq { - startSeq = listMinSeq - } else if stopSeq > listMaxSeq { - stopSeq = listMaxSeq + if start > stop || start >= llen { + return [][]byte{}, nil } - startKey := db.lEncodeListKey(key, startSeq) - stopKey := db.lEncodeListKey(key, stopSeq) - it := db.db.RangeLimitIterator(startKey, stopKey, leveldb.RangeClose, 0, -1) + if stop >= llen { + stop = llen - 1 + } + + limit := (stop - start) + 1 + headSeq += start + + v := make([][]byte, 0, limit) + + startKey := db.lEncodeListKey(key, headSeq) + it := db.db.RangeLimitIterator(startKey, nil, leveldb.RangeClose, 0, int(limit)) for ; it.Valid(); it.Next() { v = append(v, it.Value()) } diff --git a/ledis/t_list_test.go b/ledis/t_list_test.go index bb525eb..2a2bd2f 100644 --- a/ledis/t_list_test.go +++ b/ledis/t_list_test.go @@ -37,6 +37,18 @@ func TestDBList(t *testing.T) { t.Fatal(n) } + if ay, err := db.LRange(key, 0, -1); err != nil { + t.Fatal(err) + } else if len(ay) != 3 { + t.Fatal(len(ay)) + } else { + for i := range ay { + if ay[i][0] != '1'+byte(i) { + t.Fatal(string(ay[i])) + } + } + } + if k, err := db.RPop(key); err != nil { t.Fatal(err) } else if string(k) != "3" {