Repository: valkey-io/valkey
File: src/db.c (C)

Code before:
    /* Make sure the WATCHed keys are affected by the FLUSH* commands.
     * Note that we need to call the function while the keys are still
     * there. */
    signalFlushedDb(dbnum, async);

    /* Empty the database structure. */
    removed = emptyDbStructure(server.db, dbnum, async, callback);

    if (dbnum == -1) flushReplicaKeysWithExpireList();

    if (with_functions) {
        serverAssert(dbnum == -1);
        /* TODO: fix this callback incompatibility. The arg is not used. */
        functionsLibCtxClearCurrent(async, (void (*)(dict *))callback);
    }

    /* Also fire the end event. Note that this event will fire almost
     * immediately after the start event if the flush is asynchronous. */
    moduleFireServerEvent(VALKEYMODULE_EVENT_FLUSHDB, VALKEYMODULE_SUBEVENT_FLUSHDB_END, &fi);

    return removed;
}

/* Discard tempDb, it's always async. */
void discardTempDb(serverDb **tempDb) {
    /* Release temp DBs. */
    emptyDbStructure(tempDb, -1, 1, NULL);
    for (int i = 0; i < server.dbnum; i++) {
        if (tempDb[i]) {
            kvstoreRelease(tempDb[i]->keys);
            kvstoreRelease(tempDb[i]->expires);

            /* These are expected to be empty on temporary databases */
            serverAssert(dictSize(tempDb[i]->blocking_keys) == 0);
            serverAssert(dictSize(tempDb[i]->blocking_keys_unblock_on_nokey) == 0);
            serverAssert(dictSize(tempDb[i]->ready_keys) == 0);
            serverAssert(dictSize(tempDb[i]->watched_keys) == 0);

            dictRelease(tempDb[i]->blocking_keys);
            dictRelease(tempDb[i]->blocking_keys_unblock_on_nokey);
            dictRelease(tempDb[i]->ready_keys);
            dictRelease(tempDb[i]->watched_keys);
            zfree(tempDb[i]);
            tempDb[i] = NULL;
        }
    }
    zfree(tempDb);
}

int selectDb(client *c, int id) {
    if (id < 0 || id >= server.dbnum) return C_ERR;

Review comment (suggestion):
When we change the type here, we should update the comment to make it more clear.

Idea: Empty and release all databases in the temp db array and set them to NULL.

Code after:

    /* Make sure the WATCHed keys are affected by the FLUSH* commands.
     * Note that we need to call the function while the keys are still
     * there. */
    signalFlushedDb(dbnum, async);

    /* Empty the database structure. */
    removed = emptyDbStructure(server.db, dbnum, async, callback);

    if (dbnum == -1) flushReplicaKeysWithExpireList();

    if (with_functions) {
        serverAssert(dbnum == -1);
        /* TODO: fix this callback incompatibility. The arg is not used. */
        functionsLibCtxClearCurrent(async, (void (*)(dict *))callback);
    }

    /* Also fire the end event. Note that this event will fire almost
     * immediately after the start event if the flush is asynchronous. */
    moduleFireServerEvent(VALKEYMODULE_EVENT_FLUSHDB, VALKEYMODULE_SUBEVENT_FLUSHDB_END, &fi);

    return removed;
}

/* Discard tempDb array. It's always async. */
void discardTempDb(serverDb **tempDb) {
    /* Release temp DBs. */
    emptyDbStructure(tempDb, -1, 1, NULL);
    for (int i = 0; i < server.dbnum; i++) {
        if (tempDb[i]) {
            kvstoreRelease(tempDb[i]->keys);
            kvstoreRelease(tempDb[i]->expires);

            /* These are expected to be empty on temporary databases */
            serverAssert(dictSize(tempDb[i]->blocking_keys) == 0);
            serverAssert(dictSize(tempDb[i]->blocking_keys_unblock_on_nokey) == 0);
            serverAssert(dictSize(tempDb[i]->ready_keys) == 0);
            serverAssert(dictSize(tempDb[i]->watched_keys) == 0);

            dictRelease(tempDb[i]->blocking_keys);
            dictRelease(tempDb[i]->blocking_keys_unblock_on_nokey);
            dictRelease(tempDb[i]->ready_keys);
            dictRelease(tempDb[i]->watched_keys);
            zfree(tempDb[i]);
            tempDb[i] = NULL;
        }
    }
    zfree(tempDb);
}

int selectDb(client *c, int id) {