func (a *App) zset_rank(key []byte, member []byte, reverse bool) (int64, error) { k := encode_zset_key(key, member) if v, err := a.db.Get(k); err != nil { return 0, err } else if v == nil { return -1, nil } else { if s, err := Int64(v, err); err != nil { return 0, err } else { var it *leveldb.Iterator sk := encode_zscore_key(key, member, s) if !reverse { minKey := encode_start_zscore_key(key, MinScore) it = a.db.Iterator(minKey, sk, leveldb.RangeClose, 0, -1) } else { maxKey := encode_stop_zscore_key(key, MaxScore) it = a.db.RevIterator(sk, maxKey, leveldb.RangeClose, 0, -1) } var lastKey []byte = nil var n int64 = 0 for ; it.Valid(); it.Next() { n++ lastKey = it.Key() } it.Close() if _, m, _, err := decode_zscore_key(lastKey); err == nil && bytes.Equal(m, member) { n-- return n, nil } } } return -1, nil }
func (a *App) zset_range(key []byte, min int64, max int64, withScores bool, offset int, limit int, reverse bool) ([]interface{}, error) { nv := 64 if limit > 0 { nv = limit } if withScores { nv = 2 * nv } v := make([]interface{}, 0, nv) var it *leveldb.Iterator //if reverse and offset is 0, limit < 0, we may use forward iterator then reverse //because leveldb iterator prev is slower than next if !reverse || (offset == 0 && limit < 0) { it = a.zset_iterator(key, min, max, offset, limit, false) } else { it = a.zset_iterator(key, min, max, offset, limit, true) } for ; it.Valid(); it.Next() { _, m, s, err := decode_zscore_key(it.Key()) //may be we will check key equal? if err != nil { continue } v = append(v, m) if withScores { v = append(v, hack.Slice(strconv.FormatInt(s, 10))) } } if reverse && (offset == 0 && limit < 0) { v = a.zset_reverse(v, withScores) } return v, nil }