change the type of return score

This commit is contained in:
silentsai 2014-06-04 18:32:23 +08:00
parent bd38e693f2
commit 4a5f105449
3 changed files with 54 additions and 22 deletions

View File

@ -10,6 +10,7 @@ import (
const ( const (
MinScore int64 = -1<<63 + 1 MinScore int64 = -1<<63 + 1
MaxScore int64 = 1<<63 - 1 MaxScore int64 = 1<<63 - 1
InvalidScore int64 = -1 << 63
) )
type ScorePair struct { type ScorePair struct {
@ -21,6 +22,7 @@ var errZSizeKey = errors.New("invalid zsize key")
var errZSetKey = errors.New("invalid zset key") var errZSetKey = errors.New("invalid zset key")
var errZScoreKey = errors.New("invalid zscore key") var errZScoreKey = errors.New("invalid zscore key")
var errScoreOverflow = errors.New("zset score overflow") var errScoreOverflow = errors.New("zset score overflow")
var errScoreMiss = errors.New("zset score miss")
const ( const (
zsetNScoreSep byte = '<' zsetNScoreSep byte = '<'
@ -311,19 +313,25 @@ func (db *DB) ZCard(key []byte) (int64, error) {
return Int64(db.db.Get(sk)) 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 { if err := checkZSetKMSize(key, member); err != nil {
return nil, err return InvalidScore, err
} }
var score int64 = InvalidScore
k := db.zEncodeSetKey(key, member) k := db.zEncodeSetKey(key, member)
if v, err := db.db.Get(k); err != nil {
score, err := Int64(db.db.Get(k)) return InvalidScore, err
if err != nil { } else if v == nil {
return nil, err 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) { 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 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 { if err := checkZSetKMSize(key, member); err != nil {
return nil, err return InvalidScore, err
} }
t := db.zsetTx 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) v, err := db.db.Get(ek)
if err != nil { if err != nil {
return nil, err return InvalidScore, err
} else if v != nil { } else if v != nil {
if s, err := Int64(v, err); err != nil { if s, err := Int64(v, err); err != nil {
return nil, err return InvalidScore, err
} else { } else {
sk := db.zEncodeScoreKey(key, member, s) sk := db.zEncodeScoreKey(key, member, s)
t.Delete(sk) t.Delete(sk)
score = s + delta score = s + delta
if score >= MaxScore || score <= MinScore { if score >= MaxScore || score <= MinScore {
return nil, errScoreOverflow return InvalidScore, errScoreOverflow
} }
} }
} else { } else {
@ -395,7 +402,7 @@ func (db *DB) ZIncrBy(key []byte, delta int64, member []byte) ([]byte, error) {
t.Put(sk, []byte{}) t.Put(sk, []byte{})
err = t.Commit() err = t.Commit()
return StrPutInt64(score), err return score, err
} }
func (db *DB) ZCount(key []byte, min int64, max int64) (int64, error) { 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 continue
} }
v = append(v, m)
if withScores { if withScores {
v = append(v, StrPutInt64(s)) v = append(v, m, s)
} else {
v = append(v, m)
} }
} }

View File

@ -71,6 +71,16 @@ func TestDBZSet(t *testing.T) {
t.Fatal(n) 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} // {c':2, 'd':3}
if n, err := db.ZRem(key, bin("a"), bin("b")); err != nil { if n, err := db.ZRem(key, bin("a"), bin("b")); err != nil {
t.Fatal(err) t.Fatal(err)
@ -179,8 +189,10 @@ func TestZSetOrder(t *testing.T) {
} }
// {'a':0, 'b':1, 'c':2, 'd':999, 'e':6, 'f':5} // {'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) t.Fatal(err)
} else if s != 6 {
t.Fatal(s)
} }
if pos, _ := db.ZRank(key, bin("e")); int(pos) != 4 { 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 { if pos, _ := db.ZRevRank(key, bin("e")); int(pos) != 1 {
t.Fatal(pos) 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) { func TestDBZScan(t *testing.T) {

View File

@ -66,10 +66,10 @@ func zscoreCommand(c *client) error {
return ErrCmdParams 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 return err
} else { } else {
c.writeBulk(v) c.writeInteger(s)
} }
return nil return nil