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

Code before:
        new_argv = zmalloc(sizeof(robj *) * (num_fields + 2));
        new_argv[new_argc++] = shared.hdel;
        incrRefCount(shared.hdel);
        new_argv[new_argc++] = c->argv[1];
        incrRefCount(c->argv[1]);
    } else if (need_rewrite_for_nx_xx_fnx_fxx) {
        /* We use new_argv for rewrite */
        new_argv = zmalloc(sizeof(robj *) * c->argc);
        int j = 0;
        // Command
        new_argv[j++] = c->argv[0];
        incrRefCount(c->argv[0]);
        // Key
        new_argv[j++] = c->argv[1];
        incrRefCount(c->argv[1]);
        // Copy optional args (skip NX/XX/FNX/FXX)
        for (int i = 2; i < fields_index; i++) {
            if (strcmp(c->argv[i]->ptr, "NX") &&
                strcmp(c->argv[i]->ptr, "XX") &&
                strcmp(c->argv[i]->ptr, "FNX") &&
                strcmp(c->argv[i]->ptr, "FXX")) {
                new_argv[j++] = c->argv[i];
                incrRefCount(c->argv[i]);
            }
        }
        new_argc = j;
    }

    for (i = fields_index; i < c->argc; i += 2) {
        if (set_expired) {
            if (hashTypeDelete(o, c->argv[i]->ptr)) {
                new_argv[new_argc++] = c->argv[i];
                incrRefCount(c->argv[i]);
                /* we treat this case exactly as active expiration. */
                server.stat_expiredfields++;
                changes++;
            }
        } else {
            hashTypeSet(o, c->argv[i]->ptr, c->argv[i + 1]->ptr, when, set_flags);
            changes++;
            if (need_rewrite_for_nx_xx_fnx_fxx) {
                new_argv[new_argc++] = c->argv[i];
                incrRefCount(c->argv[i]);
            }
        }
    }


    if (changes) {
        if (has_volatile_fields != hashTypeHasVolatileFields(o)) {
            dbUpdateObjectWithVolatileItemsTracking(c->db, o);

Review comment (suggestion):
```suggestion
        // Copy optional args (skip NX/XX/FNX/FXX)
        for (int i = 0; i < fields_index; i++) {
            if (strcmp(c->argv[i]->ptr, "NX") &&
                strcmp(c->argv[i]->ptr, "XX") &&
                strcmp(c->argv[i]->ptr, "FNX") &&
                strcmp(c->argv[i]->ptr, "FXX")) {
                new_argv[j++] = c->argv[i];
                incrRefCount(c->argv[i]);
            }
        }
        new_argc = j;
```

Code after:
     * copy the command, key, and optional arguments, skipping the NX/XX/FNX/FXX flags. */
    if (set_expired) {
        new_argv = zmalloc(sizeof(robj *) * (num_fields + 2));
        new_argv[new_argc++] = shared.hdel;
        incrRefCount(shared.hdel);
        new_argv[new_argc++] = c->argv[1];
        incrRefCount(c->argv[1]);
    } else if (need_rewrite_argv) {
        /* We use new_argv for rewrite */
        new_argv = zmalloc(sizeof(robj *) * c->argc);
        // Copy optional args (skip NX/XX/FNX/FXX)
        for (int i = 0; i < fields_index; i++) {
            if (strcmp(c->argv[i]->ptr, "NX") &&
                strcmp(c->argv[i]->ptr, "XX") &&
                strcmp(c->argv[i]->ptr, "FNX") &&
                strcmp(c->argv[i]->ptr, "FXX")) {
                /* Propagate as HSETEX Key Value PXAT millisecond-timestamp if there is
                 * EX/PX/EXAT flag. */
                if (expire && !(flags & ARGS_PXAT) && c->argv[i + 1] == expire) {
                    robj *milliseconds_obj = createStringObjectFromLongLong(when);
                    new_argv[new_argc++] = shared.pxat;
                    new_argv[new_argc++] = milliseconds_obj;
                    i++; // skip the original expire argument
                } else {
                    new_argv[new_argc++] = c->argv[i];
                    incrRefCount(c->argv[i]);
                }
            }
        }
    }

    for (i = fields_index; i < c->argc; i += 2) {
        if (set_expired) {
            if (hashTypeDelete(o, c->argv[i]->ptr)) {
                new_argv[new_argc++] = c->argv[i];
                incrRefCount(c->argv[i]);
                /* we treat this case exactly as active expiration. */
                server.stat_expiredfields++;
                changes++;
            }
        } else {
            hashTypeSet(o, c->argv[i]->ptr, c->argv[i + 1]->ptr, when, set_flags);
            changes++;
            if (need_rewrite_argv) {
                new_argv[new_argc++] = c->argv[i];
                incrRefCount(c->argv[i]);
                new_argv[new_argc++] = c->argv[i + 1];
                incrRefCount(c->argv[i + 1]);
            }
        }
    }