From 4a5f1054492526ebaa60eb08e963107af4ef3810 Mon Sep 17 00:00:00 2001 From: silentsai Date: Wed, 4 Jun 2014 18:32:23 +0800 Subject: [PATCH 1/3] change the type of return score --- ledis/t_zset.go | 45 +++++++++++++++++++++++++------------------- ledis/t_zset_test.go | 27 +++++++++++++++++++++++++- server/cmd_zset.go | 4 ++-- 3 files changed, 54 insertions(+), 22 deletions(-) diff --git a/ledis/t_zset.go b/ledis/t_zset.go index 222b4ae..372368e 100644 --- a/ledis/t_zset.go +++ b/ledis/t_zset.go @@ -8,8 +8,9 @@ import ( ) const ( - MinScore int64 = -1<<63 + 1 - MaxScore int64 = 1<<63 - 1 + MinScore int64 = -1<<63 + 1 + MaxScore int64 = 1<<63 - 1 + InvalidScore int64 = -1 << 63 ) type ScorePair struct { @@ -21,6 +22,7 @@ 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") +var errScoreMiss = errors.New("zset score miss") const ( zsetNScoreSep byte = '<' @@ -311,19 +313,25 @@ func (db *DB) ZCard(key []byte) (int64, error) { return Int64(db.db.Get(sk)) } -func (db *DB) ZScore(key []byte, member []byte) ([]byte, error) { +func (db *DB) ZScore(key []byte, member []byte) (int64, error) { if err := checkZSetKMSize(key, member); err != nil { - return nil, err + return InvalidScore, err } + var score int64 = InvalidScore + k := db.zEncodeSetKey(key, member) - - score, err := Int64(db.db.Get(k)) - if err != nil { - return nil, err + if v, err := db.db.Get(k); err != nil { + return InvalidScore, err + } else if v == nil { + return InvalidScore, errScoreMiss + } else { + if score, err = Int64(v, nil); err != nil { + return InvalidScore, err + } } - return StrPutInt64(score), nil + return score, nil } func (db *DB) ZRem(key []byte, members ...[]byte) (int64, error) { @@ -356,9 +364,9 @@ func (db *DB) ZRem(key []byte, members ...[]byte) (int64, error) { return num, err } -func (db *DB) ZIncrBy(key []byte, delta int64, member []byte) ([]byte, error) { +func (db *DB) ZIncrBy(key []byte, delta int64, member []byte) (int64, error) { if err := checkZSetKMSize(key, member); err != nil { - return nil, err + return InvalidScore, err } t := db.zsetTx @@ -371,18 +379,17 @@ func (db *DB) ZIncrBy(key []byte, delta int64, member []byte) ([]byte, error) { v, err := db.db.Get(ek) if err != nil { - return nil, err + return InvalidScore, err } else if v != nil { if s, err := Int64(v, err); err != nil { - return nil, err + return InvalidScore, err } else { sk := db.zEncodeScoreKey(key, member, s) t.Delete(sk) score = s + delta - if score >= MaxScore || score <= MinScore { - return nil, errScoreOverflow + return InvalidScore, errScoreOverflow } } } else { @@ -395,7 +402,7 @@ func (db *DB) ZIncrBy(key []byte, delta int64, member []byte) ([]byte, error) { t.Put(sk, []byte{}) err = t.Commit() - return StrPutInt64(score), err + return score, err } func (db *DB) ZCount(key []byte, min int64, max int64) (int64, error) { @@ -563,10 +570,10 @@ func (db *DB) zRange(key []byte, min int64, max int64, withScores bool, offset i continue } - v = append(v, m) - if withScores { - v = append(v, StrPutInt64(s)) + v = append(v, m, s) + } else { + v = append(v, m) } } diff --git a/ledis/t_zset_test.go b/ledis/t_zset_test.go index fa2bb45..92c0a3d 100644 --- a/ledis/t_zset_test.go +++ b/ledis/t_zset_test.go @@ -71,6 +71,16 @@ func TestDBZSet(t *testing.T) { t.Fatal(n) } + if s, err := db.ZScore(key, bin("d")); err != nil { + t.Fatal(err) + } else if s != 3 { + t.Fatal(s) + } + + if s, err := db.ZScore(key, bin("zzz")); err != errScoreMiss || s != InvalidScore { + t.Fatal(fmt.Sprintf("s=[%d] err=[%s]", s, err)) + } + // {c':2, 'd':3} if n, err := db.ZRem(key, bin("a"), bin("b")); err != nil { t.Fatal(err) @@ -179,8 +189,10 @@ func TestZSetOrder(t *testing.T) { } // {'a':0, 'b':1, 'c':2, 'd':999, 'e':6, 'f':5} - if _, err := db.ZIncrBy(key, 2, bin("e")); err != nil { + if s, err := db.ZIncrBy(key, 2, bin("e")); err != nil { t.Fatal(err) + } else if s != 6 { + t.Fatal(s) } if pos, _ := db.ZRank(key, bin("e")); int(pos) != 4 { @@ -190,6 +202,19 @@ func TestZSetOrder(t *testing.T) { if pos, _ := db.ZRevRank(key, bin("e")); int(pos) != 1 { t.Fatal(pos) } + + if datas, _ := db.ZRange(key, 0, endPos, true); len(datas) != 12 { + t.Fatal(len(datas)) + } else { + scores := []int64{0, 1, 2, 5, 6, 999} + for i := 1; i < len(datas); i += 2 { + if s, ok := datas[i].(int64); !ok || s != scores[(i-1)/2] { + t.Fatal(fmt.Sprintf("[%d]=%d", i, datas[i])) + } + } + } + + return } func TestDBZScan(t *testing.T) { diff --git a/server/cmd_zset.go b/server/cmd_zset.go index c7f26b5..c68f71b 100644 --- a/server/cmd_zset.go +++ b/server/cmd_zset.go @@ -66,10 +66,10 @@ func zscoreCommand(c *client) error { return ErrCmdParams } - if v, err := c.db.ZScore(args[0], args[1]); err != nil { + if s, err := c.db.ZScore(args[0], args[1]); err != nil { return err } else { - c.writeBulk(v) + c.writeInteger(s) } return nil From dee78beef18bc2cfdbf7e8cab51c472687ca1533 Mon Sep 17 00:00:00 2001 From: silentsai Date: Thu, 5 Jun 2014 10:20:50 +0800 Subject: [PATCH 2/3] fix the type of return value from zscore command --- ledis/const.go | 1 + ledis/t_zset.go | 3 +-- server/cmd_zset.go | 8 ++++++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/ledis/const.go b/ledis/const.go index 9e4d0cf..ba0cf05 100644 --- a/ledis/const.go +++ b/ledis/const.go @@ -37,4 +37,5 @@ var ( ErrKeySize = errors.New("invalid key size") ErrHashFieldSize = errors.New("invalid hash field size") ErrZSetMemberSize = errors.New("invalid zset member size") + ErrScoreMiss = errors.New("zset score miss") ) diff --git a/ledis/t_zset.go b/ledis/t_zset.go index 372368e..8be54b7 100644 --- a/ledis/t_zset.go +++ b/ledis/t_zset.go @@ -22,7 +22,6 @@ 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") -var errScoreMiss = errors.New("zset score miss") const ( zsetNScoreSep byte = '<' @@ -324,7 +323,7 @@ func (db *DB) ZScore(key []byte, member []byte) (int64, error) { if v, err := db.db.Get(k); err != nil { return InvalidScore, err } else if v == nil { - return InvalidScore, errScoreMiss + return InvalidScore, ErrScoreMiss } else { if score, err = Int64(v, nil); err != nil { return InvalidScore, err diff --git a/server/cmd_zset.go b/server/cmd_zset.go index c68f71b..d9cb78a 100644 --- a/server/cmd_zset.go +++ b/server/cmd_zset.go @@ -67,9 +67,13 @@ func zscoreCommand(c *client) error { } if s, err := c.db.ZScore(args[0], args[1]); err != nil { - return err + if err == ledis.ErrScoreMiss { + c.writeBulk(nil) + } else { + return err + } } else { - c.writeInteger(s) + c.writeBulk(ledis.StrPutInt64(s)) } return nil From d0e15d4c1de4dfa206bc0bacbdd233e7eee032fb Mon Sep 17 00:00:00 2001 From: silentsai Date: Thu, 5 Jun 2014 11:49:12 +0800 Subject: [PATCH 3/3] fix bug - unify the return score type to bluk while call rangeXXX --- ledis/t_zset_test.go | 2 +- server/cmd_zset.go | 22 +++++++++++++++++----- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/ledis/t_zset_test.go b/ledis/t_zset_test.go index 92c0a3d..202da70 100644 --- a/ledis/t_zset_test.go +++ b/ledis/t_zset_test.go @@ -77,7 +77,7 @@ func TestDBZSet(t *testing.T) { t.Fatal(s) } - if s, err := db.ZScore(key, bin("zzz")); err != errScoreMiss || s != InvalidScore { + if s, err := db.ZScore(key, bin("zzz")); err != ErrScoreMiss || s != InvalidScore { t.Fatal(fmt.Sprintf("s=[%d] err=[%s]", s, err)) } diff --git a/server/cmd_zset.go b/server/cmd_zset.go index d9cb78a..c72fa71 100644 --- a/server/cmd_zset.go +++ b/server/cmd_zset.go @@ -110,7 +110,7 @@ func zincrbyCommand(c *client) error { if v, err := c.db.ZIncrBy(key, delta, args[2]); err != nil { return err } else { - c.writeBulk(v) + c.writeBulk(ledis.StrPutInt64(v)) } return nil @@ -312,10 +312,16 @@ func zrangeGeneric(c *client, reverse bool) error { withScores = true } - if v, err := c.db.ZRangeGeneric(key, start, stop, withScores, reverse); err != nil { + if datas, err := c.db.ZRangeGeneric(key, start, stop, withScores, reverse); err != nil { return err } else { - c.writeArray(v) + if withScores { + for i := len(datas) - 1; i > 0; i -= 2 { + v, _ := datas[i].(int64) + datas[i] = ledis.StrPutInt64(v) + } + } + c.writeArray(datas) } return nil } @@ -377,10 +383,16 @@ func zrangebyscoreGeneric(c *client, reverse bool) error { return nil } - if v, err := c.db.ZRangeByScoreGeneric(key, min, max, withScores, offset, count, reverse); err != nil { + if datas, err := c.db.ZRangeByScoreGeneric(key, min, max, withScores, offset, count, reverse); err != nil { return err } else { - c.writeArray(v) + if withScores { + for i := len(datas) - 1; i > 0; i -= 2 { + v, _ := datas[i].(int64) + datas[i] = ledis.StrPutInt64(v) + } + } + c.writeArray(datas) } return nil