Ziplist for redis source code parsing

Source: Internet
Author: User

Ziplist is a two-way linked list implemented by using strings. It is a waste of memory to create a complicated hash table for key-value pairs with smaller capacities, therefore, redis creates ziplist to store these key-value pairs, which reduces the space for storing node pointers. Therefore, it is used as the underlying implementation during hash table initialization. That is, the internal structure of ziplist.

Zlbytes is the space occupied by the whole ziplist and needs to be re-allocated if necessary.

Zltail facilitates quick access to the End Node of the table without traversing the whole ziplist.

Zllen indicates the number of included nodes.

Entries indicates the node added by the user.

Zlend is a value of 255, indicating the end of ziplist

Ziplist saves more memory than dict. Therefore, ziplist is used as its underlying implementation by default when hash is created. It is converted back when necessary.

For example, you can create a hash key with ziplist as the underlying layer:

Redis-cli> hset book name "programing"

First, go to the hashtypelookupwriteorcreate () function of the hsetcommand () function.

void hsetCommand(redisClient *c) {    int update;    robj *o;    if ((o = hashTypeLookupWriteOrCreate(c,c->argv[1])) == NULL) return;    hashTypeTryConversion(o,c->argv,2,3);    hashTypeTryObjectEncoding(o,&c->argv[2], &c->argv[3]);    update = hashTypeSet(o,c->argv[2],c->argv[3]);    addReply(c, update ? shared.czero : shared.cone);    signalModifiedKey(c->db,c->argv[1]);    notifyKeyspaceEvent(REDIS_NOTIFY_HASH,"hset",c->argv[1],c->db->id);    server.dirty++;}robj *hashTypeLookupWriteOrCreate(redisClient *c, robj *key) {    robj *o = lookupKeyWrite(c->db,key);    if (o == NULL) {        o = createHashObject();        dbAdd(c->db,key,o);    } else {        if (o->type != REDIS_HASH) {            addReply(c,shared.wrongtypeerr);            return NULL;        }    }    return o;}

First, create an empty ziplist. The encoding method is ziplist by default, and then add this key (book) to the database.

The main add operation is in hashtpyeset ().

/* Add an element, discard the old if the key already exists. * Return 0 on insert and 1 on update. * This function will take care of incrementing the reference count of the * retained fields and value objects. */int hashTypeSet(robj *o, robj *field, robj *value) {    int update = 0;    if (o->encoding == REDIS_ENCODING_ZIPLIST) {        unsigned char *zl, *fptr, *vptr;        field = getDecodedObject(field);        value = getDecodedObject(value);        zl = o->ptr;        fptr = ziplistIndex(zl, ZIPLIST_HEAD);        if (fptr != NULL) {            fptr = ziplistFind(fptr, field->ptr, sdslen(field->ptr), 1);            if (fptr != NULL) {                /* Grab pointer to the value (fptr points to the field) */                vptr = ziplistNext(zl, fptr);                redisAssert(vptr != NULL);                update = 1;                /* Delete value */                zl = ziplistDelete(zl, &vptr);                /* Insert new value */                zl = ziplistInsert(zl, vptr, value->ptr, sdslen(value->ptr));            }        }        if (!update) {            /* Push new field/value pair onto the tail of the ziplist */            zl = ziplistPush(zl, field->ptr, sdslen(field->ptr), ZIPLIST_TAIL);            zl = ziplistPush(zl, value->ptr, sdslen(value->ptr), ZIPLIST_TAIL);        }        o->ptr = zl;        decrRefCount(field);        decrRefCount(value);        /* Check if the ziplist needs to be converted to a hash table */        if (hashTypeLength(o) > server.hash_max_ziplist_entries)            hashTypeConvert(o, REDIS_ENCODING_HT);    } else if (o->encoding == REDIS_ENCODING_HT) {        if (dictReplace(o->ptr, field, value)) { /* Insert */            incrRefCount(field);        } else { /* Update */            update = 1;        }        incrRefCount(value);    } else {        redisPanic("Unknown hash encoding");    }    return update;}

First, ziplist will be searched. If the same key value is found, it will be replaced. If it cannot be found, the newly added key value will be pushed to the end of ziplist, in the source code, it can be found that when its length is greater than hash_max_ziplist_entries, it needs to be converted to the hash table encoding method.

After completing the preceding operations, you can use addreply () to save the results to the client in the buffer.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.