Redis dig deep del

Time:2020-3-24

Command Brief

Usage:

DEL key [key ...]

Delete one or more given keys.

Keys that do not exist are ignored.

Return value:

Number of deleted keys.

Example:

redis> SET name huangz
OK

redis> DEL name
(integer) 1


#Delete a key that does not exist

redis> EXISTS phone
(integer) 0

Redis > del phone failed, no key was deleted
(integer) 0

Source code analysis

Command file:src/db.c

delandunlinkBe similar,unlinkAnother thread (in bio. C) will be started (conditionally) for space reclamation. andDELIt will block.

  • delGenericCommand
void delCommand(client *c) {
    delGenericCommand(c,0);
}


void unlinkCommand(client *c) {
    delGenericCommand(c,1);
}


.
.
.

//Del parameter ` lazy '= 0
void delGenericCommand(client *c, int lazy) {
    int numdel = 0, j;
    for (j = 1; j < c->argc; j++) {
        //Check whether it is expired. If the expired server. Lazyfree? Lazy? Expire = 1 is also an asynchronous deletion
        expireIfNeeded(c->db,c->argv[j]);
        //If lazy is 1 asynchronous delete
        int deleted  = lazy ? dbAsyncDelete(c->db,c->argv[j]) :
                              dbSyncDelete(c->db,c->argv[j]);
        if (deleted) {
            signalModifiedKey(c->db,c->argv[j]);
            notifyKeyspaceEvent(NOTIFY_GENERIC,
                "del",c->argv[j],c->db->id);
            server.dirty++;
            numdel++;
        }
    }
    addReplyLongLong(c,numdel);
}
  • dbAsyncDelete

In fact, there are conditions for asynchrony here

/* Delete a key, value, and associated expiration entry if any, from the DB.
 * If there are enough allocations to free the value object may be put into
 * a lazy free list instead of being freed synchronously. The lazy free list
 * will be reclaimed in a different bio.c thread. */
#define LAZYFREE_THRESHOLD 64
int dbAsyncDelete(redisDb *db, robj *key) {
    /* Deleting an entry from the expires dict will not free the sds of
    o
     * the key, because it is shared with the main dictionary. */
    if (dictSize(db->expires) > 0) dictDelete(db->expires,key->ptr);

    /* If the value is composed of a few allocations, to free in a lazy way
     * is actually just slower... So under a certain limit we just free
     * the object synchronously. */
    dictEntry *de = dictUnlink(db->dict,key->ptr);
    if (de) {
        robj *val = dictGetVal(de);
        size_t free_effort = lazyfreeGetFreeEffort(val);

        /* If releasing the object is too much work, do it in the background
         * by adding the object to the lazy free list.
         * Note that if the object is shared, to reclaim it now it is not
         * possible. This rarely happens, however sometimes the implementation
         * of parts of the Redis core may call incrRefCount() to protect
         * objects, and then call dbDelete(). In this case we'll fall
         * through and reach the dictFreeUnlinkedEntry() call, that will be
         * equivalent to just calling decrRefCount(). */
        if (free_effort > LAZYFREE_THRESHOLD && val->refcount == 1) {
            atomicIncr(lazyfree_objects,1);
            //Too much background processing released
            bioCreateBackgroundJob(BIO_LAZY_FREE,val,NULL,NULL);
            dictSetVal(db->dict,de,NULL);
        }
    }

    /* Release the key-val pair, or just the key if we set the val
     * field to NULL in order to lazy free it later. */
    if (de) {
        dictFreeUnlinkedEntry(db->dict,de);
        if (server.cluster_enabled) slotToKeyDel(key);
        return 1;
    } else {
        return 0;
    }
}
  • dbSyncDelete
/* Delete a key, value, and associated expiration entry if any, from the DB */
int dbSyncDelete(redisDb *db, robj *key) {
    /* Deleting an entry from the expires dict will not free the sds of
     * the key, because it is shared with the main dictionary. */
    if (dictSize(db->expires) > 0) dictDelete(db->expires,key->ptr);
    if (dictDelete(db->dict,key->ptr) == DICT_OK) {
        if (server.cluster_enabled) slotToKeyDel(key);
        return 1;
    } else {
        return 0;
    }
}

Recommended Today

Using html2canvas to write HTML content to canvas to generate pictures

Before that, we had a brief understanding of the basic usage of canvas. Here, we will learn how to write HTML content into canvas to generate images. Here, I used the html2canvas plug-in, which is based on the implementation of canvas Http://html2canvas.hertzen.com/ 1: Download the html2canvas plug-in 1: Download html2canvas plug-in directly Click html2canvas.min.js directly, […]