1关于书签
typedef struct quicklistBookmark {
quicklistNode *node; 书签指向的快排列表的节点
char *name; 书签名字
} quicklistBookmark;
删除快排列表节点的逻辑中有关于更新书签,如果删除了书签关联的节点,那么需要更新对应的书签(如果存在)
/* Update the bookmark if any */ 如果存在书签就更新它
quicklistBookmark *bm = _quicklistBookmarkFindByNode(quicklist, node); 通过节点查找书签
if (bm) {如果存在
bm->node = node->next;把当前节点的下一个节点赋值给书签
/* if the bookmark was to the last node, delete it. */ 如果书签节点就是最后一个节点,删除之
if (!bm->node)
_quicklistBookmarkDelete(quicklist, bm);
}
2关于 关于压缩深度和填充因子 unsigned int compress : QL_COMP_BITS; int fill : QL_FILL_BITS;
在结构体quicklist中
typedef struct quicklist {
quicklistNode *head; 列表的头节点
quicklistNode *tail; 列表的尾节点
unsigned long count; /* total count of all entries in all ziplists */ 在所有压缩列表中的总实体元素数目
unsigned long len; /* number of quicklistNodes */ 快排列表节点的数目
int fill : QL_FILL_BITS; /* fill factor for individual nodes */ 单个节点的填充因子
这个填充因子如果是负数,有一个数组保存的字节数来限制,如果为正数就是元素个数限制,两种不同的限制方式
unsigned int compress : QL_COMP_BITS; /* depth of end nodes not to compress;0=off */ 不压缩的结束节点的深度,0关闭,意味全部不压缩
这个意思就是在这个深度之内的都是不压缩的,在这个深度里面的,才是需要压缩的
unsigned int bookmark_count: QL_BM_BITS; 书签数组的最大长度
quicklistBookmark bookmarks[]; 书签使用的数组
} quicklist;
compress表示的意思是
当前quicklist首尾两端不压缩节点的个数,所以这个深度最多值需要所有节点的一半取上整即可 覆盖整个列表不被压缩
当然为了整个列表不压缩,只需要取0即可
若取0,则表示整个链表不压缩;
若取1,则两端各有1个节点不进行压缩,
若取2,则两端各有2个节点不进行压缩
以此类推...
fill表示的意思是 具体填充多少内容,两个不同的衡量标准 一个是字节数 一个是元素个数
首先通过字节数判断时候,采用了一个数组,这个时候传入的fill为负数,显然必须在-1到-5之间,通过数组获取对应的大小
/* Optimization levels for size-based filling */ 基于大小填充的优化等级
static const size_t optimization_level[] = {4096, 8192, 16384, 32768, 65536};
如果没有满足字节数的条件,但是小于SIZE_SAFETY_LIMIT时,还可以进行元素个数判断
/* Maximum size in bytes of any multi-element ziplist.
* Larger values will live in their own isolated ziplists. */
#define SIZE_SAFETY_LIMIT 8192
判断代码如下:
if (likely(_quicklistNodeSizeMeetsOptimizationRequirement(merge_sz, fill))) 先判断字节数
return 1;
else if (!sizeMeetsSafetyLimit(merge_sz)) 再判断是否到安全字节数值
return 0;
else if ((int)(a->count + b->count) <= fill) 再判断个数
return 1;
else
return 0;