bugfix for lrange

adjust start and end to be same as redid
This commit is contained in:
siddontang 2014-07-01 09:21:14 +08:00
parent 1e6bcc6a50
commit b13ce1329a
2 changed files with 35 additions and 28 deletions

View File

@ -322,46 +322,41 @@ func (db *DB) LRange(key []byte, start int32, stop int32) ([][]byte, error) {
return nil, err return nil, err
} }
var startSeq int32
var stopSeq int32
if start > stop {
return [][]byte{}, nil
}
v := make([][]byte, 0, 16)
var headSeq int32 var headSeq int32
var tailSeq int32 var llen int32
var err error var err error
metaKey := db.lEncodeMetaKey(key) 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 return nil, err
} }
if start >= 0 && stop >= 0 { if start < 0 {
startSeq = headSeq + start start = llen + start
stopSeq = headSeq + stop }
} else if start < 0 && stop < 0 { if stop < 0 {
startSeq = tailSeq + start + 1 stop = llen + stop
stopSeq = tailSeq + stop + 1 }
} else { if start < 0 {
//start < 0 && stop > 0 start = 0
startSeq = tailSeq + start + 1
stopSeq = headSeq + stop
} }
if startSeq < listMinSeq { if start > stop || start >= llen {
startSeq = listMinSeq return [][]byte{}, nil
} else if stopSeq > listMaxSeq {
stopSeq = listMaxSeq
} }
startKey := db.lEncodeListKey(key, startSeq) if stop >= llen {
stopKey := db.lEncodeListKey(key, stopSeq) stop = llen - 1
it := db.db.RangeLimitIterator(startKey, stopKey, leveldb.RangeClose, 0, -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() { for ; it.Valid(); it.Next() {
v = append(v, it.Value()) v = append(v, it.Value())
} }

View File

@ -37,6 +37,18 @@ func TestDBList(t *testing.T) {
t.Fatal(n) 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 { if k, err := db.RPop(key); err != nil {
t.Fatal(err) t.Fatal(err)
} else if string(k) != "3" { } else if string(k) != "3" {