redis 中sort实现原理

redis客户端发送sort 操作时调用函数为sortCommand,sortCommand函数对参数进行解析,之后调用pqsort函数,pqsort函数在pqsort.c文件中,此文件提供给外部只有一个函数qsort(),内部调用_pqsort()实现的,文件中一些其他的静态函数和宏也是辅助作用的。

void pqsort(void *a, size_t n, size_t es,    int (*cmp) (const void *, const void *), size_t lrange, size_t rrange)

参数a:待排序数组的首地址。n:待排序元素的个数 。es:element size 每个元素的字节大小 。cmp:回调函数,定义了比较的规则 。lrange:待排序的左边界。rrange:待排序的右边界。


排序函数

内部调用 _pqsort,二者差别是psort()的参数中左右边界值含义是下标;_pqsort()参数中的左右边界值,其含义是指针。

辅助函数:


SWAPINIT

    该宏的目的在于给swaptype赋值,swaptype = 2,数组a中元素的大小不是sizeof(long)的倍数;swaptype = 0 ,每个元素大小是sizeof(long);swaptype=1,是sizeof(long)的倍数但是不等于sizeof(long)。


med3

    根据回调函数cmp指定的比较规则,求出变量a,b,c中处于中间大小的变量,也就是求出中位数。

_pqsort流程:


元素个数小于7

排序的元素个数小于7的时候,采用了冒泡排序。


元素个数大于7

pm指向数组中间位置索引,pl指向数组首位置索引,pn执向数组末位置索引,然后求出三个数中的中位数。

元素个数大于40的时候,将元素分为8个子区间,pl左边三个区间首部中的中位数索引,pm中间三个区间首部中的中位数索引。pr右边三个区间首部中的中位数索引。

pm理解为快排中所选择的基准(key),每次排序后保证基准左边小于它,基准右边大于它,并且左右区间长度大致相同,接下来排序效率就会更高。


快排操作

把基准(key)放在第一元素中,从前面位置(pa,pb)开始向后遍历,找到比基准的的数字,从后向前找到比基准小的数字,然后交换。


基准交换到中间


开始下一轮排序

新排序开始使用循环(goto loop),而不是使用递归,文中给出的注释是节省栈空间。

你可能感兴趣的:(redis 中sort实现原理)