【Redis】对通用双向链表实现的理解(三)
2014-11-24 15:45:44
·
作者:
·
浏览: 3
g->match;
iter = listGetIterator(orig, AL_START_HEAD);
while((node = listNext(iter)) != NULL) {
void *value;
if (copy->dup) {
value = copy->dup(node->value);
if (value == NULL) {
listRelease(copy);
listReleaseIterator(iter);
return NULL;
}
} else
value = node->value;
if (listAddNodeTail(copy, value) == NULL) {
listRelease(copy);
listReleaseIterator(iter);
return NULL;
}
}
listReleaseIterator(iter);
return copy;
}
/* 通过指定key来查找节点.
* 查找节点的匹配方法可以通过listSetMatchMethod()来指定.
* 如果外部调用模块没有指定匹配方法, 则直接比较key值和链表中节点指针指向的值.
*
* 如果正常将返回第一个匹配的节点指针,如果找不到匹配元素则返回NULL. */
listNode *listSearchKey(list *list, void *key)
{
listIter *iter;
listNode *node;
iter = listGetIterator(list, AL_START_HEAD);
while((node = listNext(iter)) != NULL) {
if (list->match) { // 使用自定义的match方法
if (list->match(node->value, key)) {
listReleaseIterator(iter);
return node;
}
} else { // 直接比较值
if (key == node->
value) {
listReleaseIterator(iter);
return node;
}
}
}
listReleaseIterator(iter); // 释放iter对象
return NULL;
}
/* 根据index来获取元素。
* 如果传入index为非负值,说明为正向迭代: 0为头节点,1为下一个节点,以此类推.
* 如果为负值,则说明为反向迭代: -1为尾节点, -2为倒数第二个节点, 以此类推
* 如果index越界则返回NULL. */
listNode *listIndex(list *list, long index) {
listNode *n;
if (index < 0) {
index = (-index)-1;
n = list->tail;
while(index-- && n) n = n->prev;
} else {
n = list->head;
while(index-- && n) n = n->next;
}
return n;
}
/* 翻转链表, 将尾节点插入到链表头. */
void listRotate(list *list) {
listNode *tail = list->tail;
if (listLength(list) <= 1) return;
/* 将当前末节点从链表中摘除 */
list->tail = tail->prev;
list->tail->next = NULL;
/* 将末节点插入链表头 */
list->head->prev = tail;
tail->prev = NULL;
tail->next = list->head;
list->head = tail;
} 有两点还需要继续了解:
1)既然源码中list空间的创建及销毁是通过zmalloc模块的zmalloc和zfree来完成, zmalloc又是怎么实现的呢
2)很好奇这么多对象指针都没有const作为限制, 是什么原因可以省略了它呢