Repository: valkey-io/valkey
File: src/server.h (C/C++)

Code before:
 * after the propagation of the executed command. */
typedef struct serverOp {
    robj **argv;
    int argc, dbid, target, slot;
} serverOp;

/* Defines an array of Operations. There is an API to add to this
 * structure in an easy way.
 *
 * int serverOpArrayAppend(serverOpArray *oa, int dbid, robj **argv, int argc, int target);
 * void serverOpArrayFree(serverOpArray *oa);
 */
typedef struct serverOpArray {
    serverOp *ops;
    int numops;
    int capacity;
} serverOpArray;

/* This structure is returned by the getMemoryOverheadData() function in
 * order to return memory overhead information. */
struct serverMemOverhead {
    size_t peak_allocated;
    size_t total_allocated;
    size_t startup_allocated;
    size_t repl_backlog;
    size_t clients_replicas;
    size_t clients_normal;
    size_t cluster_links;
    size_t cluster_slot_import;
    size_t cluster_slot_export;
    size_t aof_buffer;
    size_t lua_caches;
    size_t functions_caches;
    size_t overhead_total;
    size_t dataset;
    size_t total_keys;
    size_t bytes_per_key;
    float dataset_perc;
    float peak_perc;
    float total_frag;
    ssize_t total_frag_bytes;
    float allocator_frag;
    ssize_t allocator_frag_bytes;
    float allocator_rss;
    ssize_t allocator_rss_bytes;
    float rss_extra;
    size_t rss_extra_bytes;
    size_t num_dbs;
    size_t overhead_db_hashtable_lut;
    size_t overhead_db_hashtable_rehashing;
    unsigned long db_dict_rehashing_count;

Review comment (suggestion):
I fear about this blocking us from changing/extending the skiplist metadata because it might later impact the size of every skiplist node.
Maybe an alternative would be to keep the zskiplistNode as is and embed a node as part of it like this:
```
typedef struct zskiplist {
    union {
          struct {
               unsigned long length; /* Number of elements in the skiplist */
               struct zskiplistNode *tail; /* Tail element of the skiplist */
          };
          struct zskiplistNode header;
    };
} zskiplist;
```

Code after:
        *bgsaveerr_variants[2],
        *execaborterr, *noautherr, *noreplicaserr, *busykeyerr, *oomerr, *plus, *messagebulk, *pmessagebulk,
        *subscribebulk, *unsubscribebulk, *psubscribebulk, *punsubscribebulk, *del, *unlink, *rpop, *lpop, *lpush, *zadd,
        *rpoplpush, *lmove, *blmove, *zpopmin, *zpopmax, *emptyscan, *multi, *exec, *left, *right, *hset, *hdel, *hpexpireat, *hpersist, *srem,
        *xgroup, *xclaim, *script, *replconf, *eval, *cluster, *syncslots, *persist, *set, *pexpireat, *pexpire, *time, *pxat, *absttl,
        *retrycount, *force, *justid, *entriesread, *lastid, *ping, *setid, *keepttl, *load, *createconsumer, *getack,
        *special_asterisk, *special_equals, *default_username, *redacted, *ssubscribebulk, *sunsubscribebulk, *fields,
        *finish, *state, *success, *failed, *name, *message,
        *smessagebulk, *select[PROTO_SHARED_SELECT_CMDS], *integers[OBJ_SHARED_INTEGERS],
        *mbulkhdr[OBJ_SHARED_BULKHDR_LEN], /* "*<value>\r\n" */
        *bulkhdr[OBJ_SHARED_BULKHDR_LEN],  /* "$<value>\r\n" */
        *maphdr[OBJ_SHARED_BULKHDR_LEN],   /* "%<value>\r\n" */
        *sethdr[OBJ_SHARED_BULKHDR_LEN];
    sds minstring, maxstring;
};

/* ZSETs use a specialized version of Skiplists */
typedef struct zskiplistNode {
    union {
        double score;         /* Sorting score for node ordering. */
        unsigned long length; /* Number of elements in the skiplist. */
    };
    union {
        struct zskiplistNode *backward; /* Pointer to previous node for reverse traversal. */
        struct zskiplistNode *tail;     /* Tail element of the skiplist. */
    };
    struct zskiplistLevel {
        struct zskiplistNode *forward;
        /* At each level we keep the span, which is the number of elements which are on the "subtree"
         * from this node at this level to the next node at the same level.
         * One exception is the value at level 0. In level 0 the span can only be 1 or 0 (in case the last elements in the list)
         * So we use it in order to hold the height of the node, which is the number of levels. */
        unsigned long span;
    } level[1]; /* Flexible array member - actual levels determined at node creation. */
    /* For non-header nodes, after the level[], sds header length (1 byte) and an embedded sds element are stored. */
} zskiplistNode;

/* The header node does not store actual data (no score, no backward pointer,
 * and its node height is fixed at ZSKIPLIST_MAXLEVEL).
 * To save memory, we reuse the memory space of these fields in the header node to store:
 *   - skiplist length (number of elements)
 *   - tail pointer to the last element
 *   - maximum current level of the skiplist
 * For detailed memory layout, refer to the zskiplistNode struct definition. */
typedef struct zskiplist {
    zskiplistNode header;
} zskiplist;

typedef struct zset {
    hashtable *ht;
    zskiplist *zsl;