《redis设计与实现》第四部分 (第21章 排序)

本章节主要介绍SORT命令的实现原理,包括ASC、DESC、ALPHA、LIMIT、STORE、BY、GET在内的所有SORT命令选项的实现原理

21.1 SORT

  • cmpobj: 排序带有BY选项的字符串值时使用
  • 比如要排序numbers
    • 创建等长的数组;数组每一项都是redisSortObject结构
    • 将数组numbers的每一项转换成double类型的浮点数存储在score中;
    • 根据score排序;
    • 最后返回排好序的列表(redisSortObject结构中的obj变量返回给客户端)
//code0 server.h
typedef struct _redisSortObject {
    robj *obj;
    union {
        double score;
        robj *cmpobj;
    } u;
} redisSortObject;

typedef struct redisObject {
    unsigned type:4;
    unsigned encoding:4;
    unsigned lru:LRU_BITS; /* LRU time (relative to global lru_clock) or
                            * LFU data (least significant 8 bits frequency
                            * and most significant 16 bits access time). */
    int refcount;
    void *ptr;
} robj;

21.2 APLHA选项的实现

  • SORT ALPHA: 对字符串的键进行排序
  • 比如要排序字符串集合键值
    • 创建等长的数组;数组每一项都是redisSortObject结构
    • 将数组obj的每一项转换成:字符串集合键值的各个元素
    • 根据obj指向的集合元素,对数组进行字符串排序
    • 最后返回排好序的数组(redisSortObject结构中的obj指向的元素返回给客户端)

21.3 ASC和DESC选项

  • SORT ASC
  • SORT DESC
  • 默认情况下,SORT命令执行升序排列,从小到大;
  • 如果使用DESC,可以让命令降序排列,从大到小

21.4 BY选项的实现

  • command
    • SADD fruits “apple” “watermelon” “orange”
    • SORT fruits ALPHA
    • MSET apple-price 4 watermelon-price 1 orange-price 5
    • SORT fruits BY *-price
  • SORT命令可以指定某些字符串键、或者某个哈希键所包含的某些域field作为元素的权重
  • 步骤
    • 创建等长的数组;数组每一项都是redisSortObject结构
    • 将数组obj的每一项转换成:字符串集合键值的各个元素
    • 遍历数组,根据obj指向的集合元素,以及BY选项给定的模式*-price,查找对应的权重键,把权重键的值转换成double类型的浮点数,保存在对应的score中
    • 根据score对数组进行排序
    • 遍历数组,依次将redisSortObject结构中的obj指向的元素返回给客户端

21.5 带有ALPHA选项的BY选项的实现

  • command
    • SADD fruits “apple” “watermelon” “orange”
    • SORT fruits ALPHA
    • MSET apple-id “4” watermelon-id “1” orange-id “5”
    • SORT fruits BY *-id ALPHA
  • BY选项默认假设权重键保存的值为数字值,如果权重键保存的是字符串值,那需要ALPHA和BY一起用

21.6 LIMIT选项

  • LIMIT
  • SORT alphabet ALPHA LIMIT 0 4
    • 创建等长的数组;数组每一项都是redisSortObject结构
    • 将数组obj的每一项转换成:字符串集合键值的各个元素
    • 根据obj指向的集合元素,对数组进行字符串排序
    • 最后根据LIMIT 将指针移动到offset索引上,依次访问count个元素,返回给客户端

21.7 GET选项

  • command
    • SADD students “peter” “ming” “tim”
    • SORT students ALPHA
    • SET peter-name “Peter White”
    • SET ming-name “Ming Li”
    • SET tim-name “Tim Smith”
    • SORT students ALPHA GET *-name
      • “Ming Li”
      • “Peter White”
      • “Time Smith”
  • 步骤:
    • 创建等长的数组;数组每一项都是redisSortObject结构
    • 将数组obj的每一项转换成:studens集合的各个元素
    • 根据obj指向的集合元素,对数组进行字符串排序
    • 遍历数组,根据数组项obj指针所指向的集合元素,以及GET选项所指定的*-name模式,找到对应的键
    • 根据找到的键,返回值
  • 一个SORT命令可以带有多个GET选项

21.8 STORE选项

  • SORT命令只向客户端返回排序结果,并不保存排序结果。可以使用STORE选项,将排序结果保存在指定的键里面
  • SORT students ALPHA STORE sorted_students

21.9 多个选项的执行顺序

21.9.1 选项的执行顺序

  • 排序:ALPHA、ASC/DESC、BY
  • 限制结果集的长度:LIMIT
  • 获取外部键:GET
  • 保存排序结果集:STOORE
  • 向客户端返回结果

21.9.2 选项的摆放顺序

  • 改变选项的摆放顺序并不影响SORT命令执行选项的顺序(多个GET的顺序还是有关系的)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值