Esempio n. 1
0
    def zrangebyscore(self,
                      key,
                      min_score,
                      max_score,
                      withscores=False,
                      offset=0,
                      count=float('+inf')):
        result = []
        num_elems_read = 0
        if withscores:
            num_elems_per_entry = 2
        else:
            num_elems_per_entry = 1

        score_range = ScoreRange(min_score, max_score)
        for db_key in self._db.iterator(
                prefix=KEY_CODEC.get_min_zset_score(key), include_value=False):
            if len(result) / num_elems_per_entry >= count:
                return result
            db_score = KEY_CODEC.decode_zset_score(db_key)
            if score_range.above_max(db_score):
                break
            if score_range.check(db_score):
                num_elems_read += 1
                if len(result) / num_elems_per_entry >= count:
                    return result
                if num_elems_read > offset:
                    db_value = KEY_CODEC.decode_zset_value(db_key)
                    result.append(db_value)
                    if withscores:
                        result.append(db_score)
        return result
Esempio n. 2
0
    def zrange(self, key, start, stop, with_scores):
        result = []

        zset_length = int(self._db.get(KEY_CODEC.encode_zset(key), '0'))
        if stop < 0:
            end = zset_length + stop
        else:
            end = stop

        if start < 0:
            begin = max(0, zset_length + start)
        else:
            begin = start
        for i, (db_key, _) in enumerate(
                self._get_db_iterator(KEY_CODEC.get_min_zset_score(key))):
            if i < begin:
                continue
            if i > end:
                break
            db_score = KEY_CODEC.decode_zset_score(db_key)
            db_value = KEY_CODEC.decode_zset_value(db_key)
            result.append(db_value)
            if with_scores:
                result.append(db_score)

        return result
Esempio n. 3
0
    def zrank(self, key, member):
        score = self._db.get(KEY_CODEC.encode_zset_value(key, member))
        if score is None:
            return None

        rank = 0
        for db_key, _ in self._get_db_iterator(
                KEY_CODEC.get_min_zset_score(key)):
            db_score = KEY_CODEC.decode_zset_score(db_key)
            db_value = KEY_CODEC.decode_zset_value(db_key)
            if db_score < float(score):
                rank += 1
            elif db_score == float(score) and db_value < member:
                rank += 1
            else:
                break
        return rank
Esempio n. 4
0
    def zcount(self, key, min_score, max_score):
        # TODO: optimize for performance. it's probably possible to create a new entry only for scores
        # like:
        #     <prefix>myzset<score> = number of elements with that score
        #
        #     ZADD myzset 10 a
        #     <prefix>_myzset_10 = 1  ; one element with score 10
        #
        #     ZADD myzset 10 b
        #     <prefix>_myzset_10 = 2  ; two elements with score 10

        score_range = ScoreRange(min_score, max_score)
        count = 0
        for db_key, _ in self._get_db_iterator(
                KEY_CODEC.get_min_zset_score(key)):
            db_score = KEY_CODEC.decode_zset_score(db_key)
            if score_range.check(db_score):
                count += 1
            if score_range.above_max(db_score):
                break
        return count
Esempio n. 5
0
 def get_key_value_pair(db_key, db_value):
     field = KEY_CODEC.decode_zset_value(db_key)
     value = KEY_CODEC.decode_zset_score(db_key)
     return field, value