func (db *DB) zrank(key []byte, member []byte, reverse bool) (int64, error) { if err := checkZSetKMSize(key, member); err != nil { return 0, err } k := db.zEncodeSetKey(key, member) it := db.bucket.NewIterator() defer it.Close() if v := it.Find(k); v == nil { return -1, nil } else { if s, err := Int64(v, nil); err != nil { return 0, err } else { var rit *store.RangeLimitIterator sk := db.zEncodeScoreKey(key, member, s) if !reverse { minKey := db.zEncodeStartScoreKey(key, MinScore) rit = store.NewRangeIterator(it, &store.Range{minKey, sk, store.RangeClose}) } else { maxKey := db.zEncodeStopScoreKey(key, MaxScore) rit = store.NewRevRangeIterator(it, &store.Range{sk, maxKey, store.RangeClose}) } var lastKey []byte = nil var n int64 = 0 for ; rit.Valid(); rit.Next() { n++ lastKey = rit.BufKey(lastKey) } if _, m, _, err := db.zDecodeScoreKey(lastKey); err == nil && bytes.Equal(m, member) { n-- return n, nil } } } return -1, nil }
func (db *DB) zRange(key []byte, min int64, max int64, offset int, count int, reverse bool) ([]ScorePair, error) { if len(key) > MaxKeySize { return nil, errKeySize } if offset < 0 { return []ScorePair{}, nil } nv := count // count may be very large, so we must limit it for below mem make. if nv <= 0 || nv > 1024 { nv = 64 } v := make([]ScorePair, 0, nv) var it *store.RangeLimitIterator //if reverse and offset is 0, count < 0, we may use forward iterator then reverse //because store iterator prev is slower than next if !reverse || (offset == 0 && count < 0) { it = db.zIterator(key, min, max, offset, count, false) } else { it = db.zIterator(key, min, max, offset, count, true) } for ; it.Valid(); it.Next() { _, m, s, err := db.zDecodeScoreKey(it.Key()) //may be we will check key equal? if err != nil { continue } v = append(v, ScorePair{Member: m, Score: s}) } it.Close() if reverse && (offset == 0 && count < 0) { for i, j := 0, len(v)-1; i < j; i, j = i+1, j-1 { v[i], v[j] = v[j], v[i] } } return v, nil }