本章节主要介绍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的顺序还是有关系的)