此篇为对redis五大数据类型中list的分析,希望能有所帮助
List API
listTypeGet函数
robj *listTypeGet(listTypeEntry *entry) {robj *value = NULL;/* 检查编码类型是否为 quicklist (快速列表) */if (entry->li->encoding == OBJ_ENCODING_QUICKLIST) {/* 元素的值保存在 value 中 */if (entry->entry.value) {/* value = 使用当前元素创建的字符串对象 */value = createStringObject((char *)entry->entry.value,entry->entry.sz);/* 元素的值保存在 longval 中 */} else {/* value = 使用当前(整型)元素创建的字符串对象 */value = createStringObjectFromLongLong(entry->entry.longval);}} else {serverPanic("Unknown list encoding");}return value;
}
分析:
利用createStringObject函数和createStringObjectFromLongLong函数,检查编码类型并获取元素的值
listTypeInsert函数
void listTypeInsert(listTypeEntry *entry, robj *value, int where) {/* 检查编码类型是否为 quicklist (快速列表) */if (entry->li->encoding == OBJ_ENCODING_QUICKLIST) {/* 获取解码后的 value(实际上是让编码为INT的 value 转为字符串形式(raw 或 embstr))*/value = getDecodedObject(value);/* 令 str = value(字符串值),len = value 字符串长度 */sds str = value->ptr;size_t len = sdslen(str);/* 在 entry 后方插入元素 */if (where == LIST_TAIL) {quicklistInsertAfter(entry->li->iter, &entry->entry, str, len);/* 在 entry 前方插入元素 */} else if (where == LIST_HEAD) {quicklistInsertBefore(entry->li->iter, &entry->entry, str, len);}/* value 的被引用次数 -1 ,value 被引用次数为0时将被释放 */decrRefCount(value);} else {serverPanic("Unknown list encoding");}
}
分析:
对entry的插入操作,在 entry 的位置前或后方插入元素 value
listTypeReplace函数
void listTypeReplace(listTypeEntry *entry, robj *value) {/* 检查编码类型是否为 quicklist (快速列表) */if (entry->li->encoding == OBJ_ENCODING_QUICKLIST) {/* 获取解码后的 value(实际上是让编码为INT的 value 转为字符串形式(raw 或 embstr))*/value = getDecodedObject(value);/* 令 str = value(字符串值),len = value 字符串长度 */sds str = value->ptr;size_t len = sdslen(str);/* 用 value 替换 entry 中的元素 */quicklistReplaceEntry(entry->li->iter, &entry->entry, str, len);/* value 的被引用次数 -1 ,value 被引用次数为0时将被释放 */decrRefCount(value);} else {serverPanic("Unknown list encoding");}
}
分析:
替换 entry 中的元素
listTypeEqual函数
int listTypeEqual(listTypeEntry *entry, robj *o) {/* 检查编码类型是否为 quicklist (快速列表) */if (entry->li->encoding == OBJ_ENCODING_QUICKLIST) {/* 使用断言确保 o 内部编码为字符串(raw 或 embstr) */serverAssertWithInfo(NULL,o,sdsEncodedObject(o));/* 调用比较函数进行比较,相同返回1,不相同返回0 */return quicklistCompare(&entry->entry,o->ptr,sdslen(o->ptr));} else {serverPanic("Unknown list encoding");}
}
分析:
在当前位置比较两个元素是否相同
listTypeDelete函数
void listTypeDelete(listTypeIterator *iter, listTypeEntry *entry) {/* 检查编码类型是否为 quicklist (快速列表) */if (entry->li->encoding == OBJ_ENCODING_QUICKLIST) {/* 调用删除函数将元素删除 */quicklistDelEntry(iter->iter, &entry->entry);} else {serverPanic("Unknown list encoding");}
}
分析:
删除元素
listTypeDup函数
/* This is a helper function for the COPY command.* Duplicate a list object, with the guarantee that the returned object* has the same encoding as the original one.** The resulting object always has refcount set to 1 */robj *listTypeDup(robj *o) {robj *lobj;/* 使用断言确保 o 类型为列表 */serverAssert(o->type == OBJ_LIST);switch (o->encoding) {/* 检查编码类型是否为 quicklist (快速列表) */case OBJ_ENCODING_QUICKLIST:/* 创建 o 的副本 lobj */lobj = createObject(OBJ_LIST, quicklistDup(o->ptr));lobj->encoding = o->encoding;break;default:serverPanic("Unknown list encoding");break;}return lobj;
}
分析:
检查编码类型,辅助copy命令。复制一个列表对象,并保证返回的对象具有与原始对象相同的编码。返回的对象总是将 refcount 设置为1
listTypeDelRange函数
/* Delete a range of elements from the list. */int listTypeDelRange(robj *subject, long start, long count) {/* 检查编码类型是否为 quicklist (快速列表) */if (subject->encoding == OBJ_ENCODING_QUICKLIST) {/* 调用范围删除函数进行删除 */return quicklistDelRange(subject->ptr, start, count);} else {serverPanic("Unknown list encoding");}
}
分析:
在列表中删除一个指定范围内的元素
总结:
本篇分析了 listTypeGet函数、listTypeInsert函数、listTypeReplace函数、listTypeEqual函数等API,即将元素的增删改操作具体分析,有助于更好地理解list类型的操作。