redis五大类型分析--list(2)

此篇为对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类型的操作。

你可能感兴趣的:(redis源码,redis,list,bootstrap)