diff --git a/src/aof.c b/src/aof.c index 276dcbeee2..3ee5a5e54f 100644 --- a/src/aof.c +++ b/src/aof.c @@ -2328,11 +2328,11 @@ int rewriteModuleObject(rio *r, robj *key, robj *o, int dbid) { } static int rewriteFunctions(rio *aof) { - dict *functions = functionsLibGet(); - dictIterator *iter = dictGetIterator(functions); + hashtable *functions = functionsLibGet(); + hashtableIterator *iter = dictGetIterator(functions); dictEntry *entry = NULL; while ((entry = dictNext(iter))) { - functionLibInfo *li = dictGetVal(entry); + functionLibInfo *li = entry->v.val; if (rioWrite(aof, "*3\r\n", 4) == 0) goto werr; char function_load[] = "$8\r\nFUNCTION\r\n$4\r\nLOAD\r\n"; if (rioWrite(aof, function_load, sizeof(function_load) - 1) == 0) goto werr; diff --git a/src/blocked.c b/src/blocked.c index 9d081b643c..a44f125bb3 100644 --- a/src/blocked.c +++ b/src/blocked.c @@ -457,13 +457,13 @@ void blockForKeys(client *c, int btype, robj **keys, int numkeys, mstime_t timeo /* In case key[j] did not have blocking clients yet, we need to create a new list */ if (db_blocked_entry != NULL) { l = listCreate(); - dictSetVal(c->db->blocking_keys, db_blocked_entry, l); + db_blocked_entry->v.val = l; incrRefCount(keys[j]); } else { - l = dictGetVal(db_blocked_existing_entry); + l = db_blocked_existing_entry->v.val; } listAddNodeTail(l, c); - dictSetVal(c->bstate->keys, client_blocked_entry, listLast(l)); + client_blocked_entry->v.val = listLast(l); /* We need to add the key to blocking_keys_unblock_on_nokey, if the client * wants to be awakened if key is deleted (like XREADGROUP) */ @@ -471,9 +471,9 @@ void blockForKeys(client *c, int btype, robj **keys, int numkeys, mstime_t timeo db_blocked_entry = dictAddRaw(c->db->blocking_keys_unblock_on_nokey, keys[j], &db_blocked_existing_entry); if (db_blocked_entry) { incrRefCount(keys[j]); - dictSetUnsignedIntegerVal(db_blocked_entry, 1); + db_blocked_entry->v.u64 = 1; } else { - dictIncrUnsignedIntegerVal(db_blocked_existing_entry, 1); + db_blocked_existing_entry->v.u64 += 1; } } } @@ -489,7 +489,7 @@ void blockForKeys(client *c, int btype, robj **keys, int numkeys, mstime_t timeo * Internal function for unblockClient() */ static void unblockClientWaitingData(client *c) { dictEntry *de; - dictIterator *di; + hashtableIterator *di; if (dictSize(c->bstate->keys) == 0) return; @@ -582,8 +582,8 @@ static void releaseBlockedEntry(client *c, dictEntry *de, int remove_key) { void *key; dictEntry *unblock_on_nokey_entry; - key = dictGetKey(de); - pos = dictGetVal(de); + key = de->key; + pos = de->v.val; /* Remove this client from the list of clients waiting for this key. */ l = dictFetchValue(c->db->blocking_keys, key); serverAssertWithInfo(c, key, l != NULL); @@ -602,7 +602,7 @@ static void releaseBlockedEntry(client *c, dictEntry *de, int remove_key) { unblock_on_nokey_entry = dictFind(c->db->blocking_keys_unblock_on_nokey, key); /* it is not possible to have a client blocked on nokey with no matching entry */ serverAssertWithInfo(c, key, unblock_on_nokey_entry != NULL); - if (!dictIncrUnsignedIntegerVal(unblock_on_nokey_entry, -1)) { + if (!--unblock_on_nokey_entry->v.u64) { /* in case the count is zero, we can delete the entry */ dictDelete(c->db->blocking_keys_unblock_on_nokey, key); } @@ -627,7 +627,7 @@ static void handleClientsBlockedOnKey(readyList *rl) { dictEntry *de = dictFind(rl->db->blocking_keys, rl->key); if (de) { - list *clients = dictGetVal(de); + list *clients = de->v.val; listNode *ln; listIter li; listRewind(clients, &li); diff --git a/src/cluster.c b/src/cluster.c index ed2e51a92c..5857204e09 100644 --- a/src/cluster.c +++ b/src/cluster.c @@ -359,10 +359,10 @@ migrateCachedSocket *migrateGetSocket(client *c, robj *host, robj *port, long ti if (dictSize(server.migrate_cached_sockets) == MIGRATE_SOCKET_CACHE_ITEMS) { /* Too many items, drop one at random. */ dictEntry *de = dictGetRandomKey(server.migrate_cached_sockets); - cs = dictGetVal(de); + cs = de->v.val; connClose(cs->conn); zfree(cs); - dictDelete(server.migrate_cached_sockets, dictGetKey(de)); + dictDelete(server.migrate_cached_sockets, de->key); } /* Create the connection */ @@ -405,16 +405,16 @@ void migrateCloseSocket(robj *host, robj *port) { } void migrateCloseTimedoutSockets(void) { - dictIterator *di = dictGetSafeIterator(server.migrate_cached_sockets); + hashtableIterator *di = dictGetSafeIterator(server.migrate_cached_sockets); dictEntry *de; while ((de = dictNext(di)) != NULL) { - migrateCachedSocket *cs = dictGetVal(de); + migrateCachedSocket *cs = de->v.val; if ((server.unixtime - cs->last_use_time) > MIGRATE_SOCKET_CACHE_TTL) { connClose(cs->conn); zfree(cs); - dictDelete(server.migrate_cached_sockets, dictGetKey(de)); + dictDelete(server.migrate_cached_sockets, de->key); } } dictReleaseIterator(di); @@ -1353,7 +1353,7 @@ int clusterRedirectBlockedClientIfNeeded(client *c) { if (c->flag.blocked && (c->bstate->btype == BLOCKED_LIST || c->bstate->btype == BLOCKED_ZSET || c->bstate->btype == BLOCKED_STREAM || c->bstate->btype == BLOCKED_MODULE)) { dictEntry *de; - dictIterator *di; + hashtableIterator *di; /* If the client is blocked on module, but not on a specific key, * don't unblock it. */ @@ -1371,7 +1371,7 @@ int clusterRedirectBlockedClientIfNeeded(client *c) { /* All keys must belong to the same slot, so check first key only. */ di = dictGetIterator(c->bstate->keys); if ((de = dictNext(di)) != NULL) { - robj *key = dictGetKey(de); + robj *key = de->key; int slot = keyHashSlot((char *)objectGetVal(key), sdslen(objectGetVal(key))); serverAssert(slot == c->slot); clusterNode *node = getNodeBySlot(slot); diff --git a/src/cluster_legacy.c b/src/cluster_legacy.c index cd88cdf895..5f69e412ba 100644 --- a/src/cluster_legacy.c +++ b/src/cluster_legacy.c @@ -246,7 +246,7 @@ static_assert(offsetof(clusterMsg, type) + sizeof(uint16_t) == RCVBUF_MIN_READ_L /* Cluster nodes hash table, mapping nodes addresses 1.2.3.4:6379 to * clusterNode structures. */ -dictType clusterNodesDictType = { +hashtableType clusterNodesDictType = { .entryGetKey = dictEntryGetKey, .hashFunction = dictSdsHash, .keyCompare = dictSdsKeyCompare, @@ -256,7 +256,7 @@ dictType clusterNodesDictType = { /* Cluster re-addition blacklist. This maps node IDs to the time * we can re-add this node. The goal is to avoid reading a removed * node for some time. */ -dictType clusterNodesBlackListDictType = { +hashtableType clusterNodesBlackListDictType = { .entryGetKey = dictEntryGetKey, .hashFunction = dictSdsCaseHash, .keyCompare = dictSdsKeyCaseCompare, @@ -264,7 +264,7 @@ dictType clusterNodesBlackListDictType = { }; /* Cluster shards hash table, mapping shard id to list of nodes */ -dictType clusterSdsToListType = { +hashtableType clusterSdsToListType = { .entryGetKey = dictEntryGetKey, .hashFunction = dictSdsHash, .keyCompare = dictSdsKeyCompare, @@ -282,7 +282,7 @@ static int dictPtrCompare(const void *key1, const void *key2) { /* Dictionary type for mapping hash slots to cluster nodes. * Keys are slot numbers encoded directly as pointer values, values are clusterNode pointers. */ -dictType clusterSlotDictType = { +hashtableType clusterSlotDictType = { .entryGetKey = dictEntryGetKey, .hashFunction = dictPtrHash, .keyCompare = dictPtrCompare, @@ -296,7 +296,7 @@ typedef struct { ITER_NODE, } type; union { - dictIterator di; + hashtableIterator di; listIter li; clusterNode *node; }; @@ -325,7 +325,7 @@ static clusterNode *clusterNodeIterNext(ClusterNodeIterator *iter) { /* Get the next entry in the dictionary */ dictEntry *de = dictNext(&iter->di); /* Return the value associated with the entry, or NULL if no more entries */ - return de ? dictGetVal(de) : NULL; + return de ? de->v.val : NULL; } case ITER_LIST: { /* Get the next node in the list */ @@ -357,7 +357,7 @@ static void clusterNodeIterReset(ClusterNodeIterator *iter) { /* Helpers to access the migrating/importing slot dictionaries. */ clusterNode *getMigratingSlotDest(int slot) { dictEntry *de = dictFind(server.cluster->migrating_slots_to, (void *)(intptr_t)slot); - return de ? dictGetVal(de) : NULL; + return de ? de->v.val : NULL; } static void setMigratingSlotDest(int slot, clusterNode *node) { @@ -367,7 +367,7 @@ static void setMigratingSlotDest(int slot, clusterNode *node) { return; } if (de) { - dictSetVal(server.cluster->migrating_slots_to, de, node); + de->v.val = node; } else { dictAdd(server.cluster->migrating_slots_to, (void *)(intptr_t)slot, node); } @@ -375,7 +375,7 @@ static void setMigratingSlotDest(int slot, clusterNode *node) { clusterNode *getImportingSlotSource(int slot) { dictEntry *de = dictFind(server.cluster->importing_slots_from, (void *)(intptr_t)slot); - return de ? dictGetVal(de) : NULL; + return de ? de->v.val : NULL; } static void setImportingSlotSource(int slot, clusterNode *node) { @@ -385,7 +385,7 @@ static void setImportingSlotSource(int slot, clusterNode *node) { return; } if (de) { - dictSetVal(server.cluster->importing_slots_from, de, node); + de->v.val = node; } else { dictAdd(server.cluster->importing_slots_from, (void *)(intptr_t)slot, node); } @@ -672,7 +672,7 @@ int clusterLoadConfig(char *filename) { struct stat sb; char *line; int maxline, j; - dict *tmp_cluster_nodes; + hashtable *tmp_cluster_nodes; if (fp == NULL) { if (errno == ENOENT) { @@ -1649,7 +1649,7 @@ void clusterHandleServerShutdown(bool auto_failover) { * 7) If the node was a replica, the whole data set is flushed away. * 8) If it is a hard reset or the node was a replica: a new Shard ID is generated. */ void clusterReset(int hard) { - dictIterator *di; + hashtableIterator *di; dictEntry *de; int j; bool new_shard = false; @@ -1661,13 +1661,13 @@ void clusterReset(int hard) { /* Unassign all the slots. */ for (j = 0; j < CLUSTER_SLOTS; j++) clusterDelSlot(j); - /* Recreate shards dict */ + /* Recreate shards hashtable */ dictEmpty(server.cluster->shards, NULL); /* Forget all the nodes, but myself. */ di = dictGetSafeIterator(server.cluster->nodes); while ((de = dictNext(di)) != NULL) { - clusterNode *node = dictGetVal(de); + clusterNode *node = de->v.val; if (node == myself) continue; clusterDelNode(node); @@ -2229,7 +2229,7 @@ void clusterDelNode(clusterNode *delnode) { serverLog(LL_DEBUG, "Deleting node %.40s (%s) from cluster view", delnode->name, humanNodename(delnode)); int j; - dictIterator *di; + hashtableIterator *di; dictEntry *de; /* 1) Mark slots as unassigned. */ @@ -2242,7 +2242,7 @@ void clusterDelNode(clusterNode *delnode) { /* 2) Remove failure reports. */ di = dictGetSafeIterator(server.cluster->nodes); while ((de = dictNext(di)) != NULL) { - clusterNode *node = dictGetVal(de); + clusterNode *node = de->v.val; if (node == delnode) continue; clusterNodeDelFailureReport(node, delnode); @@ -2263,7 +2263,7 @@ clusterNode *clusterLookupNode(const char *name, int length) { dictEntry *de = dictFind(server.cluster->nodes, s); sdsfree(s); if (de == NULL) return NULL; - return dictGetVal(de); + return de->v.val; } /* Get all the nodes in my shard. @@ -2276,7 +2276,7 @@ list *clusterGetNodesInMyShard(clusterNode *node) { sds s = sdsnewlen(node->shard_id, CLUSTER_NAMELEN); dictEntry *de = dictFind(server.cluster->shards, s); sdsfree(s); - return (de != NULL) ? dictGetVal(de) : NULL; + return (de != NULL) ? de->v.val : NULL; } /* This is only used after the handshake. When we connect a given IP/PORT @@ -2304,7 +2304,7 @@ void clusterAddNodeToShard(const char *shard_id, clusterNode *node) { listAddNodeTail(l, node); serverAssert(dictAdd(server.cluster->shards, s, l) == DICT_OK); } else { - list *l = dictGetVal(de); + list *l = de->v.val; if (listSearchKey(l, node) == NULL) { listAddNodeTail(l, node); } @@ -2316,7 +2316,7 @@ void clusterRemoveNodeFromShard(clusterNode *node) { sds s = sdsnewlen(node->shard_id, CLUSTER_NAMELEN); dictEntry *de = dictFind(server.cluster->shards, s); if (de != NULL) { - list *l = dictGetVal(de); + list *l = de->v.val; listNode *ln = listSearchKey(l, node); if (ln != NULL) { listDelNode(l, ln); @@ -2336,12 +2336,12 @@ void clusterRemoveNodeFromShard(clusterNode *node) { * epoch if greater than any node configEpoch. */ uint64_t clusterGetMaxEpoch(void) { uint64_t max = 0; - dictIterator *di; + hashtableIterator *di; dictEntry *de; di = dictGetSafeIterator(server.cluster->nodes); while ((de = dictNext(di)) != NULL) { - clusterNode *node = dictGetVal(de); + clusterNode *node = de->v.val; if (node->configEpoch > max) max = node->configEpoch; } dictReleaseIterator(di); @@ -2481,14 +2481,14 @@ void clusterHandleConfigEpochCollision(clusterNode *sender) { * However without the cleanup during long uptime and with some automated * node add/removal procedures, entries could accumulate. */ void clusterBlacklistCleanup(void) { - dictIterator *di; + hashtableIterator *di; dictEntry *de; di = dictGetSafeIterator(server.cluster->nodes_black_list); while ((de = dictNext(di)) != NULL) { - int64_t expire = dictGetUnsignedIntegerVal(de); + int64_t expire = de->v.u64; - if (expire < server.unixtime) dictDelete(server.cluster->nodes_black_list, dictGetKey(de)); + if (expire < server.unixtime) dictDelete(server.cluster->nodes_black_list, de->key); } dictReleaseIterator(di); } @@ -2505,7 +2505,7 @@ void clusterBlacklistAddNode(clusterNode *node) { id = sdsdup(id); } de = dictFind(server.cluster->nodes_black_list, id); - dictSetUnsignedIntegerVal(de, time(NULL) + server.cluster_blacklist_ttl); + de->v.u64 = time(NULL) + server.cluster_blacklist_ttl; sdsfree(id); } @@ -2634,12 +2634,12 @@ void clearNodeFailureIfNeeded(clusterNode *node) { * specified ip address and port number. This function is used in order to * avoid adding a new handshake node for the same address multiple times. */ static int clusterHandshakeInProgress(char *ip, int port, int cport) { - dictIterator *di; + hashtableIterator *di; dictEntry *de; di = dictGetSafeIterator(server.cluster->nodes); while ((de = dictNext(di)) != NULL) { - clusterNode *node = dictGetVal(de); + clusterNode *node = de->v.val; if (!nodeInHandshake(node)) continue; if (!strcasecmp(node->ip, ip) && getNodeDefaultClientPort(node) == port && node->cport == cport) break; @@ -3435,16 +3435,16 @@ static uint32_t writePingExtensions(clusterMsg *hdr, int gossipcount) { /* Gossip forgotten nodes */ if (dictSize(server.cluster->nodes_black_list) > 0) { - dictIterator *di = dictGetIterator(server.cluster->nodes_black_list); + hashtableIterator *di = dictGetIterator(server.cluster->nodes_black_list); dictEntry *de; while ((de = dictNext(di)) != NULL) { if (cursor != NULL) { - uint64_t expire = dictGetUnsignedIntegerVal(de); + uint64_t expire = de->v.u64; if ((time_t)expire < server.unixtime) continue; /* already expired */ uint64_t ttl = expire - server.unixtime; clusterMsgPingExtForgottenNode *ext = preparePingExt(cursor, CLUSTERMSG_EXT_TYPE_FORGOTTEN_NODE, getForgottenNodeExtSize()); - memcpy(ext->name, dictGetKey(de), CLUSTER_NAMELEN); + memcpy(ext->name, de->key, CLUSTER_NAMELEN); ext->ttl = htonu64(ttl); /* Move the write cursor */ @@ -3521,12 +3521,12 @@ void clusterProcessPingExtensions(clusterMsg *hdr, clusterLink *link) { if (n && n != myself && !(nodeIsReplica(myself) && myself->replicaof == n)) { sds id = sdsnewlen(forgotten_node_ext->name, CLUSTER_NAMELEN); dictEntry *de = dictAddOrFind(server.cluster->nodes_black_list, id); - if (dictGetKey(de) != id) { + if (de->key != id) { /* The dict did not take ownership of the id string, so we need to free it. */ sdsfree(id); } uint64_t expire = server.unixtime + ntohu64(forgotten_node_ext->ttl); - dictSetUnsignedIntegerVal(de, expire); + de->v.u64 = expire; clusterDelNode(n); clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE | CLUSTER_TODO_SAVE_CONFIG); } @@ -4691,12 +4691,12 @@ void clusterSendMessage(clusterLink *link, clusterMsgSendBlock *msgblock) { * some node->link to be invalidated, so it is safe to call this function * from event handlers that will do stuff with node links later. */ void clusterBroadcastMessage(clusterMsgSendBlock *msgblock) { - dictIterator *di; + hashtableIterator *di; dictEntry *de; di = dictGetSafeIterator(server.cluster->nodes); while ((de = dictNext(di)) != NULL) { - clusterNode *node = dictGetVal(de); + clusterNode *node = de->v.val; if (node->flags & (CLUSTER_NODE_MYSELF | CLUSTER_NODE_HANDSHAKE)) continue; clusterSendMessage(node->link, msgblock); @@ -4892,7 +4892,7 @@ void clusterSendPing(clusterLink *link, int type) { unsigned int ncandidates = dictGetSomeKeys(server.cluster->nodes, candidates, candidates_wanted); for (unsigned int i = 0; i < ncandidates && gossipcount < wanted; i++) { - clusterNode *this = dictGetVal(candidates[i]); + clusterNode *this = ((dictEntry *)candidates[i])->v.val; /* Don't include this node: the whole packet header is about us * already, so we just gossip about other nodes. @@ -4925,12 +4925,12 @@ void clusterSendPing(clusterLink *link, int type) { /* If there are PFAIL nodes, add them at the end. */ if (pfail_wanted) { - dictIterator *di; + hashtableIterator *di; dictEntry *de; di = dictGetSafeIterator(server.cluster->nodes); while ((de = dictNext(di)) != NULL && pfail_wanted > 0) { - clusterNode *node = dictGetVal(de); + clusterNode *node = de->v.val; if (node->flags & CLUSTER_NODE_HANDSHAKE) continue; if (node->flags & CLUSTER_NODE_NOADDR) continue; if (!(node->flags & CLUSTER_NODE_PFAIL)) continue; @@ -4980,12 +4980,12 @@ void clusterSendPing(clusterLink *link, int type) { #define CLUSTER_BROADCAST_ALL 0 #define CLUSTER_BROADCAST_LOCAL_REPLICAS 1 void clusterBroadcastPong(int target) { - dictIterator *di; + hashtableIterator *di; dictEntry *de; di = dictGetSafeIterator(server.cluster->nodes); while ((de = dictNext(di)) != NULL) { - clusterNode *node = dictGetVal(de); + clusterNode *node = de->v.val; if (!node->link) continue; if (node == myself || nodeInHandshake(node)) continue; @@ -5432,12 +5432,12 @@ int clusterGetFailedPrimaryRank(void) { int rank = 0; mstime_t now = mstime(); - dictIterator *di; + hashtableIterator *di; dictEntry *de; di = dictGetSafeIterator(server.cluster->nodes); while ((de = dictNext(di)) != NULL) { - clusterNode *node = dictGetVal(de); + clusterNode *node = de->v.val; /* Skip nodes that do not need to participate in the rank. */ if (!nodeFailed(node) || !clusterNodeIsVotingPrimary(node) || node->num_replicas == 0) continue; @@ -5838,7 +5838,7 @@ void clusterHandleReplicaFailover(void) { void clusterHandleReplicaMigration(int max_replicas) { int j, ok_replicas = 0; clusterNode *my_primary = myself->replicaof, *target = NULL, *candidate = NULL; - dictIterator *di; + hashtableIterator *di; dictEntry *de; /* Step 1: Don't migrate if the cluster state is not ok. */ @@ -5864,7 +5864,7 @@ void clusterHandleReplicaMigration(int max_replicas) { candidate = myself; di = dictGetSafeIterator(server.cluster->nodes); while ((de = dictNext(di)) != NULL) { - clusterNode *node = dictGetVal(de); + clusterNode *node = de->v.val; int ok_replicas = 0, is_orphaned = 1; /* We want to migrate only if this primary is working, orphaned, and @@ -6141,7 +6141,7 @@ static long long maxConnectionAttemptsPerCron(void) { /* This is executed 10 times every second */ void clusterCron(void) { - dictIterator *di; + hashtableIterator *di; dictEntry *de; int update_state = 0; int orphaned_primaries; /* How many primaries there are without ok replicas. */ @@ -6163,7 +6163,7 @@ void clusterCron(void) { di = dictGetSafeIterator(server.cluster->nodes); long long cluster_node_conn_attempts = maxConnectionAttemptsPerCron(); while ((de = dictNext(di)) != NULL) { - clusterNode *node = dictGetVal(de); + clusterNode *node = de->v.val; /* We free the inbound or outbound link to the node if the link has an * oversized message send queue and immediately try reconnecting. */ clusterNodeCronFreeLinkOnBufferLimitReached(node); @@ -6183,7 +6183,7 @@ void clusterCron(void) { * pong_received time. */ for (j = 0; j < 5; j++) { de = dictGetRandomKey(server.cluster->nodes); - clusterNode *this = dictGetVal(de); + clusterNode *this = de->v.val; /* Don't ping nodes disconnected or with a ping currently active. */ if (this->link == NULL || this->ping_sent != 0) continue; @@ -6210,7 +6210,7 @@ void clusterCron(void) { this_replicas = 0; di = dictGetSafeIterator(server.cluster->nodes); while ((de = dictNext(di)) != NULL) { - clusterNode *node = dictGetVal(de); + clusterNode *node = de->v.val; now = mstime(); /* Use an updated time at every iteration. */ if (node->flags & (CLUSTER_NODE_MYSELF | CLUSTER_NODE_NOADDR | CLUSTER_NODE_HANDSHAKE)) continue; @@ -6416,11 +6416,11 @@ void bitmapClearBit(unsigned char *bitmap, int pos) { * Otherwise zero is returned. Used by clusterNodeSetSlotBit() to set the * MIGRATE_TO flag the when a primary gets the first slot. */ int clusterPrimariesHaveReplicas(void) { - dictIterator di; + hashtableIterator di; dictInitIterator(&di, server.cluster->nodes); dictEntry *de; while ((de = dictNext(&di)) != NULL) { - clusterNode *node = dictGetVal(de); + clusterNode *node = de->v.val; if (nodeIsReplica(node)) continue; if (node->num_replicas) return 1; @@ -6640,13 +6640,13 @@ void clusterUpdateState(void) { * At the same time count the number of reachable primaries having * at least one slot. */ { - dictIterator *di; + hashtableIterator *di; dictEntry *de; server.cluster->size = 0; di = dictGetSafeIterator(server.cluster->nodes); while ((de = dictNext(di)) != NULL) { - clusterNode *node = dictGetVal(de); + clusterNode *node = de->v.val; if (clusterNodeIsVotingPrimary(node)) { server.cluster->size++; @@ -7031,7 +7031,7 @@ void clusterFreeNodesSlotsInfo(clusterNode *n) { * configuration file (nodes.conf) for a given node. */ sds clusterGenNodesDescription(client *c, int filter, int tls_primary) { sds ci = sdsempty(), ni; - dictIterator *di; + hashtableIterator *di; dictEntry *de; /* Generate all nodes slots info firstly. */ @@ -7039,7 +7039,7 @@ sds clusterGenNodesDescription(client *c, int filter, int tls_primary) { di = dictGetSafeIterator(server.cluster->nodes); while ((de = dictNext(di)) != NULL) { - clusterNode *node = dictGetVal(de); + clusterNode *node = de->v.val; if (node->flags & filter) continue; ni = clusterGenNodeDescription(c, node, tls_primary); @@ -7094,7 +7094,7 @@ void addReplyClusterLinkDescription(client *c, clusterLink *link) { /* Add to the output buffer of the given client an array of cluster link descriptions, * with array entry being a description of a single current cluster link. */ void addReplyClusterLinksDescription(client *c) { - dictIterator *di; + hashtableIterator *di; dictEntry *de; void *arraylen_ptr = NULL; int num_links = 0; @@ -7103,7 +7103,7 @@ void addReplyClusterLinksDescription(client *c) { di = dictGetSafeIterator(server.cluster->nodes); while ((de = dictNext(di)) != NULL) { - clusterNode *node = dictGetVal(de); + clusterNode *node = de->v.val; if (node->link) { num_links++; addReplyClusterLinkDescription(c, node->link); @@ -7271,9 +7271,9 @@ void clusterCommandShards(client *c) { addReplyArrayLen(c, dictSize(server.cluster->shards)); /* This call will add slot_info_pairs to all nodes */ clusterGenNodesSlotsInfo(0); - dictIterator *di = dictGetSafeIterator(server.cluster->shards); + hashtableIterator *di = dictGetSafeIterator(server.cluster->shards); for (dictEntry *de = dictNext(di); de != NULL; de = dictNext(di)) { - list *nodes = dictGetVal(de); + list *nodes = de->v.val; serverAssert(listLength(nodes) > 0); addReplyMapLen(c, 3); addReplyBulkCString(c, "slots"); @@ -7309,7 +7309,7 @@ void clusterCommandShards(client *c) { clusterFreeNodesSlotsInfo(n); } addReplyBulkCString(c, "id"); - addReplyBulkCBuffer(c, dictGetKey(de), CLUSTER_NAMELEN); + addReplyBulkCBuffer(c, de->key, CLUSTER_NAMELEN); } dictReleaseIterator(di); } @@ -7319,11 +7319,11 @@ sds genClusterInfoString(sds info) { int slots_assigned = 0, slots_ok = 0, slots_pfail = 0, slots_fail = 0; uint64_t my_epoch = myself ? nodeEpoch(myself) : 0; - dictIterator *di = dictGetIterator(server.cluster->nodes); + hashtableIterator *di = dictGetIterator(server.cluster->nodes); dictEntry *de; unsigned nodes_pfail = 0, nodes_fail = 0, voting_nodes_pfail = 0, voting_nodes_fail = 0; while ((de = dictNext(di)) != NULL) { - clusterNode *node = dictGetVal(de); + clusterNode *node = de->v.val; if (node->numslots) { slots_assigned += node->numslots; if (nodeFailed(node)) { @@ -7498,11 +7498,11 @@ int getMyShardSlotCount(void) { char **getClusterNodesList(size_t *numnodes) { size_t count = dictSize(server.cluster->nodes); char **ids = zmalloc((count + 1) * sizeof(char *)); - dictIterator *di = dictGetIterator(server.cluster->nodes); + hashtableIterator *di = dictGetIterator(server.cluster->nodes); dictEntry *de; int j = 0; while ((de = dictNext(di)) != NULL) { - clusterNode *node = dictGetVal(de); + clusterNode *node = de->v.val; if (node->flags & (CLUSTER_NODE_NOADDR | CLUSTER_NODE_HANDSHAKE)) continue; ids[j] = zmalloc(CLUSTER_NAMELEN); memcpy(ids[j], node->name, CLUSTER_NAMELEN); @@ -8399,13 +8399,13 @@ void clusterPromoteSelfToPrimary(void) { } int detectAndUpdateCachedNodeHealth(void) { - dictIterator di; + hashtableIterator di; dictInitIterator(&di, server.cluster->nodes); dictEntry *de; clusterNode *node; int overall_health_changed = 0; while ((de = dictNext(&di)) != NULL) { - node = dictGetVal(de); + node = de->v.val; int present_is_node_healthy = isNodeAvailable(node); if (present_is_node_healthy != node->is_node_healthy) { overall_health_changed = 1; @@ -8426,12 +8426,12 @@ sds clusterEncodeOpenSlotsAuxField(int rdbflags) { sds s = NULL; for (int i = 0; i < 2; i++) { - dict *d = (i == 0) ? server.cluster->importing_slots_from : server.cluster->migrating_slots_to; - dictIterator *di = dictGetIterator(d); + hashtable *d = (i == 0) ? server.cluster->importing_slots_from : server.cluster->migrating_slots_to; + hashtableIterator *di = dictGetIterator(d); dictEntry *de; while ((de = dictNext(di)) != NULL) { - int slot = (int)(uintptr_t)dictGetKey(de); - clusterNode *node = dictGetVal(de); + int slot = (int)(uintptr_t)de->key; + clusterNode *node = de->v.val; if (s == NULL) s = sdsempty(); s = sdscatfmt(s, "%i%s", slot, (i == 0) ? "<" : ">"); s = sdscatlen(s, node->name, CLUSTER_NAMELEN); diff --git a/src/cluster_legacy.h b/src/cluster_legacy.h index 7703f071de..79baa16d14 100644 --- a/src/cluster_legacy.h +++ b/src/cluster_legacy.h @@ -432,15 +432,15 @@ typedef struct slotRange { struct clusterState { clusterNode *myself; /* This node */ uint64_t currentEpoch; - int state; /* CLUSTER_OK, CLUSTER_FAIL, ... */ - int fail_reason; /* Why the cluster state changes to fail. */ - int safe_to_join; /* Can the restarted node safely join the cluster? */ - int size; /* Num of primary nodes with at least one slot */ - dict *nodes; /* Hash table of name -> clusterNode structures */ - dict *shards; /* Hash table of shard_id -> list (of nodes) structures */ - dict *nodes_black_list; /* Nodes we don't re-add for a few seconds. */ - dict *migrating_slots_to; - dict *importing_slots_from; + int state; /* CLUSTER_OK, CLUSTER_FAIL, ... */ + int fail_reason; /* Why the cluster state changes to fail. */ + int safe_to_join; /* Can the restarted node safely join the cluster? */ + int size; /* Num of primary nodes with at least one slot */ + hashtable *nodes; /* Hash table of name -> clusterNode structures */ + hashtable *shards; /* Hash table of shard_id -> list (of nodes) structures */ + hashtable *nodes_black_list; /* Nodes we don't re-add for a few seconds. */ + hashtable *migrating_slots_to; + hashtable *importing_slots_from; clusterNode *slots[CLUSTER_SLOTS]; list *slot_migration_jobs; /* List storing all slot migration jobs. Stored * in order from most recent to least recently diff --git a/src/config.c b/src/config.c index 8cd049e69e..0246b42657 100644 --- a/src/config.c +++ b/src/config.c @@ -306,13 +306,13 @@ struct standardConfig { void *privdata; /* privdata for this config, for module configs this is a ModuleConfig struct */ }; -static dict *configs = NULL; /* Runtime config values */ +static hashtable *configs = NULL; /* Runtime config values */ /* Lookup a config by the provided sds string name, or return NULL * if the config does not exist */ static standardConfig *lookupConfig(sds name) { dictEntry *de = dictFind(configs, name); - return de ? dictGetVal(de) : NULL; + return de ? de->v.val : NULL; } /*----------------------------------------------------------------------------- @@ -971,9 +971,9 @@ static int configKeyCompare(const void *a, const void *b) { void configGetCommand(client *c) { int i; dictEntry *de; - dictIterator *di; + hashtableIterator *di; /* Create a dictionary to store the matched configs */ - dict *matches = dictCreate(&externalStringType); + hashtable *matches = dictCreate(&externalStringType); for (i = 0; i < c->argc - 2; i++) { robj *o = c->argv[2 + i]; sds name = objectGetVal(o); @@ -994,12 +994,12 @@ void configGetCommand(client *c) { di = dictGetIterator(configs); while ((de = dictNext(di)) != NULL) { - standardConfig *config = dictGetVal(de); + standardConfig *config = de->v.val; /* Note that hidden configs require an exact match (not a pattern) */ if (config->flags & HIDDEN_CONFIG) continue; if (dictFind(matches, config->name)) continue; - if (stringmatch(name, dictGetKey(de), 1)) { - dictAdd(matches, dictGetKey(de), config); + if (stringmatch(name, de->key, 1)) { + dictAdd(matches, de->key, config); } } dictReleaseIterator(di); @@ -1016,8 +1016,8 @@ void configGetCommand(client *c) { i = 0; while ((de = dictNext(di)) != NULL) { - standardConfig *config = (standardConfig *)dictGetVal(de); - sorted[i].key = dictGetKey(de); + standardConfig *config = (standardConfig *)de->v.val; + sorted[i].key = de->key; sorted[i].value = config->interface.get(config); i++; } @@ -1046,14 +1046,14 @@ void rewriteConfigSentinelOption(struct rewriteConfigState *state); * option is mentioned in the old configuration file, so it's * like "maxmemory" -> list of line numbers (first line is zero). */ -dictType optionToLineDictType = { +hashtableType optionToLineDictType = { .entryGetKey = dictEntryGetKey, .hashFunction = dictSdsCaseHash, .keyCompare = dictSdsKeyCaseCompare, .entryDestructor = dictEntryDestructorSdsKeyListValue, }; -dictType optionSetDictType = { +hashtableType optionSetDictType = { .entryGetKey = dictEntryGetKey, .hashFunction = dictSdsCaseHash, .keyCompare = dictSdsKeyCaseCompare, @@ -1062,15 +1062,15 @@ dictType optionSetDictType = { /* The config rewrite state. */ struct rewriteConfigState { - dict *option_to_line; /* Option -> list of config file lines map */ - dict *rewritten; /* Dictionary of already processed options */ - int numlines; /* Number of lines in current config */ - sds *lines; /* Current lines as an array of sds strings */ - int needs_signature; /* True if we need to append the rewrite - signature. */ - int force_write; /* True if we want all keywords to be force - written. Currently only used for testing - and debug information. */ + hashtable *option_to_line; /* Option -> list of config file lines map */ + hashtable *rewritten; /* Dictionary of already processed options */ + int numlines; /* Number of lines in current config */ + sds *lines; /* Current lines as an array of sds strings */ + int needs_signature; /* True if we need to append the rewrite + signature. */ + int force_write; /* True if we want all keywords to be force + written. Currently only used for testing + and debug information. */ }; /* Free the configuration rewrite state. */ @@ -1615,10 +1615,10 @@ static void rewriteConfigSocketBindOption(standardConfig *config, const char *na void rewriteConfigLoadmoduleOption(struct rewriteConfigState *state) { sds line; - dictIterator *di = dictGetIterator(modules); + hashtableIterator *di = dictGetIterator(modules); dictEntry *de; while ((de = dictNext(di)) != NULL) { - struct ValkeyModule *module = dictGetVal(de); + struct ValkeyModule *module = de->v.val; if (module->is_static_module) continue; line = moduleLoadQueueEntryToLoadmoduleOptionStr(module, "loadmodule"); rewriteConfigRewriteLine(state, "loadmodule", line, 1); @@ -1657,12 +1657,12 @@ sds rewriteConfigGetContentFromState(struct rewriteConfigState *state) { * This function does just this, iterating all the option names and * blanking all the lines still associated. */ void rewriteConfigRemoveOrphaned(struct rewriteConfigState *state) { - dictIterator *di = dictGetIterator(state->option_to_line); + hashtableIterator *di = dictGetIterator(state->option_to_line); dictEntry *de; while ((de = dictNext(di)) != NULL) { - list *l = dictGetVal(de); - sds option = dictGetKey(de); + list *l = de->v.val; + sds option = de->key; /* Don't blank lines about options the rewrite process * don't understand. */ @@ -1692,10 +1692,10 @@ sds getConfigDebugInfo(void) { /* Iterate the configs and "rewrite" the ones that have * the debug flag. */ - dictIterator *di = dictGetIterator(configs); + hashtableIterator *di = dictGetIterator(configs); dictEntry *de; while ((de = dictNext(di)) != NULL) { - standardConfig *config = dictGetVal(de); + standardConfig *config = de->v.val; if (!(config->flags & DEBUG_CONFIG)) continue; config->interface.rewrite(config, config->name, state); } @@ -1792,13 +1792,13 @@ int rewriteConfig(char *path, int force_write) { * the rewrite state. */ /* Iterate the configs that are standard */ - dictIterator *di = dictGetIterator(configs); + hashtableIterator *di = dictGetIterator(configs); dictEntry *de; while ((de = dictNext(di)) != NULL) { - standardConfig *config = dictGetVal(de); + standardConfig *config = de->v.val; /* Only rewrite the primary names */ if (config->flags & ALIAS_CONFIG) continue; - if (config->interface.rewrite) config->interface.rewrite(config, dictGetKey(de), state); + if (config->interface.rewrite) config->interface.rewrite(config, de->key, state); } dictReleaseIterator(di); diff --git a/src/db.c b/src/db.c index fed77e8a63..ee4bb26a2a 100644 --- a/src/db.c +++ b/src/db.c @@ -687,7 +687,7 @@ long long emptyData(int dbnum, int flags, void(callback)(hashtable *)) { if (with_functions) { serverAssert(dbnum == -1); /* TODO: fix this callback incompatibility. The arg is not used. */ - functionReset(async, (void (*)(dict *))callback); + functionReset(async, (void (*)(hashtable *))callback); } /* Also fire the end event. Note that this event will fire almost @@ -981,7 +981,7 @@ void keysCommand(client *c) { /* Data used by the dict scan callback. */ typedef struct { - vector *result; /* elements that collect from dict */ + vector *result; /* elements that collect from hashtable */ robj *o; /* o must be a hash/set/zset object, NULL means current db */ serverDb *db; /* database currently being scanned */ long long type; /* the particular type when scan the db */ @@ -1256,7 +1256,7 @@ void scanGenericCommandWithOptions(client *c, robj *o, unsigned long long cursor } else if (o->type == OBJ_ZSET && o->encoding == OBJ_ENCODING_SKIPLIST) { zset *zs = objectGetVal(o); ht = zs->ht; - /* scanning ZSET allocates temporary strings even though it's a dict */ + /* scanning ZSET allocates temporary strings even though it's a hashtable */ free_callback = sdsfree; } vectorInit(&result, SCAN_VECTOR_INITIAL_ALLOC, sizeof(stringRef)); @@ -1708,9 +1708,9 @@ void copyCommand(client *c) { * where the function is used for more info. */ void scanDatabaseForReadyKeys(serverDb *db) { dictEntry *de; - dictIterator *di = dictGetSafeIterator(db->blocking_keys); + hashtableIterator *di = dictGetSafeIterator(db->blocking_keys); while ((de = dictNext(di)) != NULL) { - robj *key = dictGetKey(de); + robj *key = de->key; robj *value = dbFind(db, objectGetVal(key)); if (value) { signalKeyAsReady(db, key, value->type); @@ -1724,9 +1724,9 @@ void scanDatabaseForReadyKeys(serverDb *db) { * database was flushed/swapped. */ void scanDatabaseForDeletedKeys(serverDb *emptied, serverDb *replaced_with) { dictEntry *de; - dictIterator *di = dictGetSafeIterator(emptied->blocking_keys); + hashtableIterator *di = dictGetSafeIterator(emptied->blocking_keys); while ((de = dictNext(di)) != NULL) { - robj *key = dictGetKey(de); + robj *key = de->key; int existed = 0, exists = 0; int original_type = -1, curr_type = -1; diff --git a/src/debug.c b/src/debug.c index c0a760d58f..e0038b4b45 100644 --- a/src/debug.c +++ b/src/debug.c @@ -1996,7 +1996,7 @@ void logServerInfo(void) { int all = 0, everything = 0; robj *argv[1]; argv[0] = createStringObject("all", strlen("all")); - dict *section_dict = genInfoSectionDict(argv, 1, NULL, &all, &everything); + hashtable *section_dict = genInfoSectionDict(argv, 1, NULL, &all, &everything); infostring = genValkeyInfoString(section_dict, all, everything); if (server.cluster_enabled) { infostring = genClusterDebugString(infostring); diff --git a/src/defrag.c b/src/defrag.c index 670f83bee7..cfbb034d80 100644 --- a/src/defrag.c +++ b/src/defrag.c @@ -331,7 +331,7 @@ static void activeDefragDictCallback(void *privdata, void *entry_ref) { } /* Defrag a dict with sds key and optional value (either ptr, sds or robj string) */ -static void activeDefragSdsDict(dict *d, int val_type) { +static void activeDefragSdsDict(hashtable *d, int val_type) { unsigned long cursor = 0; dictDefragFunctions defragfns = { .defragKey = (dictDefragAllocFunction *)activeDefragSds, diff --git a/src/dict.h b/src/dict.h index e552926c84..b6724cd3eb 100644 --- a/src/dict.h +++ b/src/dict.h @@ -1,34 +1,17 @@ -/* Dict, a key-value hashtable API. - * - * This file implements the dict API as a thin wrapper of the newer hashtable - * API. The dictEntry struct is used as the entry type in underlying hashtable. - * - * Copyright (c) 2006-2012, Redis Ltd. +/* + * Copyright Valkey Contributors. * All rights reserved. + * SPDX-License-Identifier: BSD 3-Clause + */ + +/* Dict — convenience helpers for using hashtable as a key-value store. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Redis nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. + * dict is a typedef for hashtable. dictEntry is a transparent struct that + * callers allocate and access directly (de->key, de->v.val, de->v.u64, etc.). * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * The helpers in this file handle dictEntry allocation and hashtable + * insertion/lookup/deletion so callers don't need to manage the two-step + * FindPositionForInsert + InsertAtPosition dance themselves. */ #ifndef __DICT_H @@ -41,12 +24,13 @@ #define DICT_OK 0 #define DICT_ERR 1 -/* dict is now an alias for hashtable */ -typedef hashtable dict; -typedef hashtableType dictType; -typedef hashtableIterator dictIterator; - -/* dictEntry represents a key-value pair for use with hashtable */ +/* dictEntry is a transparent key-value pair. Access fields directly: + * de->key - the key pointer + * de->v.val - value as void* + * de->v.u64 - value as uint64_t + * de->v.s64 - value as int64_t + * de->v.d - value as double + */ typedef struct dictEntry { void *key; union { @@ -79,122 +63,60 @@ typedef struct dictEntry { /* Expand the hash table if needed. Returns DICT_OK if expand was performed * or if the dictionary is already large enough, DICT_ERR if expand was not * performed. */ -static inline int dictExpand(dict *d, unsigned long size) { +static inline int dictExpand(hashtable *d, unsigned long size) { return hashtableExpand(d, size) ? DICT_OK : DICT_ERR; } -/* Entry accessor functions */ -static inline void dictSetKey(dict *d, dictEntry *de, void *key) { - UNUSED(d); - de->key = key; -} - -static inline void dictSetVal(dict *d, dictEntry *de, void *val) { - UNUSED(d); - de->v.val = val; -} - -static inline void dictSetSignedIntegerVal(dictEntry *de, int64_t val) { - de->v.s64 = val; -} - -static inline void dictSetUnsignedIntegerVal(dictEntry *de, uint64_t val) { - de->v.u64 = val; -} - -static inline void dictSetDoubleVal(dictEntry *de, double val) { - de->v.d = val; -} - -static inline int64_t dictIncrSignedIntegerVal(dictEntry *de, int64_t val) { - de->v.s64 += val; - return de->v.s64; -} - -static inline uint64_t dictIncrUnsignedIntegerVal(dictEntry *de, uint64_t val) { - de->v.u64 += val; - return de->v.u64; -} - -static inline double dictIncrDoubleVal(dictEntry *de, double val) { - de->v.d += val; - return de->v.d; -} - -static inline void *dictGetKey(const dictEntry *de) { - return de->key; -} - -/* Callback for dictType.entryGetKey, which expects void pointers. */ +/* Callback for hashtableType.entryGetKey, which expects void pointers. */ static inline const void *dictEntryGetKey(const void *entry) { - return dictGetKey((const dictEntry *)entry); -} - -static inline void *dictGetVal(const dictEntry *de) { - return de->v.val; -} - -static inline int64_t dictGetSignedIntegerVal(const dictEntry *de) { - return de->v.s64; -} - -static inline uint64_t dictGetUnsignedIntegerVal(const dictEntry *de) { - return de->v.u64; -} - -static inline double dictGetDoubleVal(const dictEntry *de) { - return de->v.d; -} - -static inline double *dictGetDoubleValPtr(dictEntry *de) { - return &de->v.d; + return ((const dictEntry *)entry)->key; } static inline size_t dictEntryMemUsage(dictEntry *de) { return sizeof(*de); } -static inline size_t dictMemUsage(const dict *d) { +static inline size_t dictMemUsage(const hashtable *d) { return hashtableMemUsage(d) + hashtableSize(d) * sizeof(dictEntry); } /* Search for a key in the dictionary. Returns the dictEntry if found, * or NULL if the key doesn't exist. */ -static inline dictEntry *dictFind(dict *d, const void *key) { +static inline dictEntry *dictFind(hashtable *d, const void *key) { void *found = NULL; return hashtableFind(d, key, &found) ? (dictEntry *)found : NULL; } /* Fetch the value associated with a key. Returns the value if the key exists, * or NULL if the key doesn't exist. */ -static inline void *dictFetchValue(dict *d, const void *key) { +static inline void *dictFetchValue(hashtable *d, const void *key) { dictEntry *de = dictFind(d, key); return de ? de->v.val : NULL; } /* Remove a key from the dictionary. Returns DICT_OK if the key was found * and removed, DICT_ERR if the key was not found. */ -static inline int dictDelete(dict *d, const void *key) { +static inline int dictDelete(hashtable *d, const void *key) { return hashtableDelete(d, key) ? DICT_OK : DICT_ERR; } /* Free an entry that was previously unlinked with dictUnlink(). * It's safe to call this function with de = NULL. */ -static inline void dictFreeUnlinkedEntry(dict *d, dictEntry *de) { +static inline void dictFreeUnlinkedEntry(hashtable *d, dictEntry *de) { if (de == NULL) return; hashtableType *type = hashtableGetType(d); type->entryDestructor(de); } /* Return a random entry from the hash table. */ -static inline dictEntry *dictGetRandomKey(dict *d) { +static inline dictEntry *dictGetRandomKey(hashtable *d) { void *entry = NULL; return hashtableRandomEntry(d, &entry) ? (dictEntry *)entry : NULL; } /* A more fair random entry selection that considers chain lengths. * This provides better distribution than dictGetRandomKey(). */ -static inline dictEntry *dictGetFairRandomKey(dict *d) { +static inline dictEntry *dictGetFairRandomKey(hashtable *d) { void *entry = NULL; return hashtableFairRandomEntry(d, &entry) ? (dictEntry *)entry : NULL; } @@ -208,13 +130,13 @@ static inline dictEntry *dictGetFairRandomKey(dict *d) { * This function is useful when we want to remove something from the hash * table but want to use its value before actually deleting the entry. * Without this function the pattern would require two lookups. */ -static inline dictEntry *dictUnlink(dict *d, const void *key) { +static inline dictEntry *dictUnlink(hashtable *d, const void *key) { void *entry = NULL; return hashtablePop(d, key, &entry) ? (dictEntry *)entry : NULL; } /* Add an entry to the dictionary. */ -static inline int dictAdd(dict *d, void *key, void *val) { +static inline int dictAdd(hashtable *d, void *key, void *val) { hashtablePosition pos; void *existing = NULL; @@ -236,7 +158,7 @@ static inline int dictAdd(dict *d, void *key, void *val) { * * If key was added, the dictEntry is returned to be manipulated by the * caller. */ -static inline dictEntry *dictAddRaw(dict *d, void *key, dictEntry **existing) { +static inline dictEntry *dictAddRaw(hashtable *d, void *key, dictEntry **existing) { hashtablePosition pos; void *existing_entry = NULL; @@ -254,7 +176,7 @@ static inline dictEntry *dictAddRaw(dict *d, void *key, dictEntry **existing) { /* Adds a key to the dictionary if it doesn't already exists. Returns the * dictEntry of the key, whether it was just added or not. */ -static inline dictEntry *dictAddOrFind(dict *d, void *key) { +static inline dictEntry *dictAddOrFind(hashtable *d, void *key) { dictEntry *existing = NULL; dictEntry *entry = dictAddRaw(d, key, &existing); return entry ? entry : existing; @@ -265,7 +187,7 @@ static inline dictEntry *dictAddOrFind(dict *d, void *key) { * * Always returns 1 to indicate the key was consumed (either added or used * to replace). The caller should not free the key after calling this. */ -static inline int dictReplace(dict *d, void *key, void *val) { +static inline int dictReplace(hashtable *d, void *key, void *val) { dictEntry *entry = (dictEntry *)zmalloc(sizeof(*entry)); entry->key = key; entry->v.val = val; @@ -287,7 +209,7 @@ static inline int dictReplace(dict *d, void *key, void *val) { } /* Iterator operations */ -static inline dictEntry *dictNext(dictIterator *iter) { +static inline dictEntry *dictNext(hashtableIterator *iter) { void *entry = NULL; if (hashtableNext(iter, &entry)) { return (dictEntry *)entry; diff --git a/src/eval.c b/src/eval.c index 8e2839ae8a..fc098cbb3d 100644 --- a/src/eval.c +++ b/src/eval.c @@ -74,13 +74,13 @@ static void dictScriptDestructor(void *val) { /* Helper functions for eval.c */ static void dictEntryDestructorSdsKeyScriptValue(void *entry) { dictEntry *de = entry; - dictSdsDestructor(dictGetKey(de)); - dictScriptDestructor(dictGetVal(de)); + dictSdsDestructor(de->key); + dictScriptDestructor(de->v.val); zfree(de); } /* evalCtx.scripts sha (as sds string) -> scripts (as evalScript) cache. */ -dictType shaScriptObjectDictType = { +hashtableType shaScriptObjectDictType = { .entryGetKey = dictEntryGetKey, .hashFunction = dictCStrCaseHash, .keyCompare = dictSdsKeyCaseCompare, @@ -89,7 +89,7 @@ dictType shaScriptObjectDictType = { /* Eval context */ struct evalCtx { - dict *scripts; /* A dictionary of SHA1 -> evalScript */ + hashtable *scripts; /* A dictionary of SHA1 -> evalScript */ list *scripts_lru_list; /* A list of SHA1, first in first out LRU eviction. */ unsigned long long scripts_mem; /* Cached scripts' memory + oh */ } evalCtx; @@ -139,7 +139,7 @@ void sha1hex(char *digest, char *script, size_t len) { } /* Free lua_scripts dict and close lua interpreter. */ -void freeEvalScripts(dict *scripts, list *scripts_lru_list, list *engine_callbacks) { +void freeEvalScripts(hashtable *scripts, list *scripts_lru_list, list *engine_callbacks) { dictRelease(scripts); listRelease(scripts_lru_list); @@ -185,12 +185,12 @@ void evalRelease(int async) { * Called when a scripting engine is unregistered to avoid dangling engine * pointers in the eval script cache. */ void evalRemoveScriptsFromEngine(scriptingEngine *engine) { - dictIterator *iter = dictGetSafeIterator(evalCtx.scripts); + hashtableIterator *iter = dictGetSafeIterator(evalCtx.scripts); dictEntry *entry; while ((entry = dictNext(iter))) { - evalScript *es = dictGetVal(entry); + evalScript *es = entry->v.val; if (es->engine == engine) { - sds sha = dictGetKey(entry); + sds sha = entry->key; evalCtx.scripts_mem -= sdsAllocSize(sha) + getStringObjectSdsUsedMemory(es->body); if (es->node) { listDelNode(evalCtx.scripts_lru_list, es->node); @@ -318,7 +318,7 @@ uint64_t evalGetCommandFlags(client *c, uint64_t cmd_flags) { if (evalsha) return cmd_flags; if (evalExtractShebangFlags(objectGetVal(c->argv[1]), NULL, &script_flags, NULL, NULL) == C_ERR) return cmd_flags; } else { - evalScript *es = dictGetVal(c->cur_script); + evalScript *es = c->cur_script->v.val; script_flags = es->flags; } if (script_flags & SCRIPT_FLAG_EVAL_COMPAT_MODE) return cmd_flags; @@ -333,7 +333,7 @@ static void evalDeleteScript(client *c, sds sha) { /* Delete the script from server. */ dictEntry *de = dictUnlink(evalCtx.scripts, sha); serverAssertWithInfo(c, NULL, de); - evalScript *es = dictGetVal(de); + evalScript *es = de->v.val; evalCtx.scripts_mem -= sdsAllocSize(sha) + getStringObjectSdsUsedMemory(es->body); dictFreeUnlinkedEntry(evalCtx.scripts, de); } @@ -380,7 +380,7 @@ static int evalRegisterNewScript(client *c, robj *body, char **sha) { * SCRIPT LOAD, prevent it from being evicted later. */ dictEntry *entry = dictFind(evalCtx.scripts, *sha); if (entry != NULL) { - evalScript *es = dictGetVal(entry); + evalScript *es = entry->v.val; if (es->node) { listDelNode(evalCtx.scripts_lru_list, es->node); es->node = NULL; @@ -486,7 +486,7 @@ static void evalGenericCommand(client *c, int evalsha) { } if (c->cur_script) { - memcpy(sha, dictGetKey(c->cur_script), 40); + memcpy(sha, c->cur_script->key, 40); sha[40] = '\0'; } else { evalCalcScriptHash(evalsha, objectGetVal(c->argv[1]), sha); @@ -511,7 +511,7 @@ static void evalGenericCommand(client *c, int evalsha) { serverAssert(entry != NULL); } - evalScript *es = dictGetVal(entry); + evalScript *es = entry->v.val; int ro = c->cmd->proc == evalRoCommand || c->cmd->proc == evalShaRoCommand; scriptRunCtx rctx; @@ -675,7 +675,7 @@ void scriptCommand(client *c) { evalScript *es; if (sdslen(objectGetVal(c->argv[2])) == 40 && (de = dictFind(evalCtx.scripts, objectGetVal(c->argv[2])))) { - es = dictGetVal(de); + es = de->v.val; addReplyBulk(c, es->body); } else { addReplyErrorObject(c, shared.noscripterr); @@ -697,7 +697,7 @@ unsigned long evalMemory(void) { return memory; } -dict *evalScriptsDict(void) { +hashtable *evalScriptsDict(void) { return evalCtx.scripts; } diff --git a/src/expire.c b/src/expire.c index 7a070a7588..ab97dbe9a9 100644 --- a/src/expire.c +++ b/src/expire.c @@ -541,7 +541,7 @@ ustime_t activeExpireCycle(int type) { * with a DB id > 63 are not expired, but a trivial fix is to set the bitmap * to the max 64 bit unsigned value when we know there is a key with a DB * ID greater than 63, and check all the configured DBs in such a case. */ -dict *replicaKeysWithExpire = NULL; +hashtable *replicaKeysWithExpire = NULL; /* Check the set of keys created by the primary with an expire set in order to * check if they should be evicted. */ @@ -552,8 +552,8 @@ void expireReplicaKeys(void) { mstime_t start = mstime(); while (1) { dictEntry *de = dictGetRandomKey(replicaKeysWithExpire); - sds keyname = dictGetKey(de); - uint64_t dbids = dictGetUnsignedIntegerVal(de); + sds keyname = de->key; + uint64_t dbids = de->v.u64; uint64_t new_dbids = 0; /* Check the key against every database corresponding to the @@ -590,7 +590,7 @@ void expireReplicaKeys(void) { * of keys with an expire set directly in the writable replica. Otherwise * if the bitmap is zero, we no longer need to keep track of it. */ if (new_dbids) - dictSetUnsignedIntegerVal(de, new_dbids); + de->v.u64 = new_dbids; else dictDelete(replicaKeysWithExpire, keyname); @@ -608,7 +608,7 @@ void expireReplicaKeys(void) { void rememberReplicaKeyWithExpire(serverDb *db, robj *key) { if (replicaKeysWithExpire == NULL) { - static dictType dt = { + static hashtableType dt = { .entryGetKey = dictEntryGetKey, .hashFunction = dictSdsHash, .keyCompare = dictSdsKeyCompare, @@ -618,19 +618,17 @@ void rememberReplicaKeyWithExpire(serverDb *db, robj *key) { } if (db->id > 63) return; - dictEntry *de = dictAddOrFind(replicaKeysWithExpire, objectGetVal(key)); - /* If the entry was just created, set it to a copy of the SDS string - * representing the key: we don't want to need to take those keys - * in sync with the main DB. The keys will be removed by expireReplicaKeys() - * as it scans to find keys to remove. */ - if (dictGetKey(de) == objectGetVal(key)) { - dictSetKey(replicaKeysWithExpire, de, sdsdup(objectGetVal(key))); - dictSetUnsignedIntegerVal(de, 0); + dictEntry *existing = NULL; + dictEntry *de = dictAddRaw(replicaKeysWithExpire, objectGetVal(key), &existing); + if (de) { + /* New entry: own the key and initialize the bitmap. */ + de->key = sdsdup(objectGetVal(key)); + de->v.u64 = 0; + } else { + de = existing; } - uint64_t dbids = dictGetUnsignedIntegerVal(de); - dbids |= (uint64_t)1 << db->id; - dictSetUnsignedIntegerVal(de, dbids); + de->v.u64 |= (uint64_t)1 << db->id; } /* Return the number of keys we are tracking. */ diff --git a/src/expire.h b/src/expire.h index cb6103f01e..acb84df851 100644 --- a/src/expire.h +++ b/src/expire.h @@ -71,6 +71,6 @@ void rememberReplicaKeyWithExpire(serverDb *db, robj *key); void flushReplicaKeysWithExpireList(int async); size_t getReplicaKeyWithExpireCount(void); bool timestampIsExpired(mstime_t when); -void freeReplicaKeysWithExpireAsync(dict *replica_keys_with_expire); +void freeReplicaKeysWithExpireAsync(hashtable *replica_keys_with_expire); #endif diff --git a/src/functions.c b/src/functions.c index f8b8bc39a2..e2e1055edb 100644 --- a/src/functions.c +++ b/src/functions.c @@ -57,10 +57,10 @@ typedef struct functionsLibEngineStats { } functionsLibEngineStats; struct functionsLibCtx { - dict *libraries; /* Library name -> Library object */ - dict *functions; /* Function name -> Function object that can be used to run the function */ - size_t cache_memory; /* Overhead memory (structs, dictionaries, ..) used by all the functions */ - dict *engines_stats; /* Per engine statistics */ + hashtable *libraries; /* Library name -> Library object */ + hashtable *functions; /* Function name -> Function object that can be used to run the function */ + size_t cache_memory; /* Overhead memory (structs, dictionaries, ..) used by all the functions */ + hashtable *engines_stats; /* Per engine statistics */ }; typedef struct functionsLibMetaData { @@ -69,7 +69,7 @@ typedef struct functionsLibMetaData { sds code; } functionsLibMetaData; -dictType functionDictType = { +hashtableType functionDictType = { .entryGetKey = dictEntryGetKey, .hashFunction = dictCStrCaseHash, .keyCompare = dictSdsKeyCaseCompare, @@ -78,12 +78,12 @@ dictType functionDictType = { static void dictEntryDestructorSdsKeyEngineStatsValue(void *entry) { dictEntry *de = entry; - dictSdsDestructor(dictGetKey(de)); - engineStatsDispose(dictGetVal(de)); + dictSdsDestructor(de->key); + engineStatsDispose(de->v.val); zfree(de); } -dictType engineStatsDictType = { +hashtableType engineStatsDictType = { .entryGetKey = dictEntryGetKey, .hashFunction = dictSdsCaseHash, .keyCompare = dictSdsKeyCaseCompare, @@ -92,12 +92,12 @@ dictType engineStatsDictType = { static void dictEntryDestructorSdsKeyEngineFunctionValue(void *entry) { dictEntry *de = entry; - dictSdsDestructor(dictGetKey(de)); - engineFunctionDispose(dictGetVal(de)); + dictSdsDestructor(de->key); + engineFunctionDispose(de->v.val); zfree(de); } -dictType libraryFunctionDictType = { +hashtableType libraryFunctionDictType = { .entryGetKey = dictEntryGetKey, .hashFunction = dictSdsHash, .keyCompare = dictSdsKeyCompare, @@ -106,12 +106,12 @@ dictType libraryFunctionDictType = { static void dictEntryDestructorSdsKeyEngineLibraryValue(void *entry) { dictEntry *de = entry; - dictSdsDestructor(dictGetKey(de)); - engineLibraryDispose(dictGetVal(de)); + dictSdsDestructor(de->key); + engineLibraryDispose(de->v.val); zfree(de); } -dictType librariesDictType = { +hashtableType librariesDictType = { .entryGetKey = dictEntryGetKey, .hashFunction = dictSdsHash, .keyCompare = dictSdsKeyCompare, @@ -160,13 +160,13 @@ static void engineLibraryDispose(void *obj) { } /* Clear all the functions from the given library ctx */ -void functionsLibCtxClear(functionsLibCtx *lib_ctx, void(callback)(dict *)) { +void functionsLibCtxClear(functionsLibCtx *lib_ctx, void(callback)(hashtable *)) { dictEmpty(lib_ctx->functions, callback); dictEmpty(lib_ctx->libraries, callback); - dictIterator *iter = dictGetIterator(lib_ctx->engines_stats); + hashtableIterator *iter = dictGetIterator(lib_ctx->engines_stats); dictEntry *entry = NULL; while ((entry = dictNext(iter))) { - functionsLibEngineStats *stats = dictGetVal(entry); + functionsLibEngineStats *stats = entry->v.val; stats->n_functions = 0; stats->n_lib = 0; } @@ -184,7 +184,7 @@ static void resetEngineOrCollectResetCallbacks(scriptingEngine *engine, void *co } } -void functionsLibCtxReleaseCurrent(int async, void(callback)(dict *)) { +void functionsLibCtxReleaseCurrent(int async, void(callback)(hashtable *)) { if (async) { list *engine_callbacks = listCreate(); scriptingEngineManagerForEachEngine(resetEngineOrCollectResetCallbacks, engine_callbacks); @@ -204,13 +204,13 @@ static void functionsLibCtxFreeGeneric(functionsLibCtx *functions_lib_ctx, int a } } -void functionReset(int async, void(callback)(dict *)) { +void functionReset(int async, void(callback)(hashtable *)) { functionsLibCtxReleaseCurrent(async, callback); functionsInit(); } /* Free the given functions ctx */ -void functionsLibCtxFree(functionsLibCtx *functions_lib_ctx, void(callback)(dict *), list *engine_callbacks) { +void functionsLibCtxFree(functionsLibCtx *functions_lib_ctx, void(callback)(hashtable *), list *engine_callbacks) { functionsLibCtxClear(functions_lib_ctx, callback); dictRelease(functions_lib_ctx->functions); dictRelease(functions_lib_ctx->libraries); @@ -323,10 +323,10 @@ static functionLibInfo *engineLibraryCreate(sds name, scriptingEngine *e, sds co } static void libraryUnlink(functionsLibCtx *lib_ctx, functionLibInfo *li) { - dictIterator *iter = dictGetIterator(li->functions); + hashtableIterator *iter = dictGetIterator(li->functions); dictEntry *entry = NULL; while ((entry = dictNext(iter))) { - functionInfo *fi = dictGetVal(entry); + functionInfo *fi = entry->v.val; int ret = dictDelete(lib_ctx->functions, objectGetVal(fi->compiled_function->name)); serverAssert(ret == DICT_OK); @@ -334,7 +334,7 @@ static void libraryUnlink(functionsLibCtx *lib_ctx, functionLibInfo *li) { } dictReleaseIterator(iter); entry = dictUnlink(lib_ctx->libraries, li->name); - dictSetVal(lib_ctx->libraries, entry, NULL); + entry->v.val = NULL; dictFreeUnlinkedEntry(lib_ctx->libraries, entry); lib_ctx->cache_memory -= libraryMallocSize(li); @@ -347,10 +347,10 @@ static void libraryUnlink(functionsLibCtx *lib_ctx, functionLibInfo *li) { } static void libraryLink(functionsLibCtx *lib_ctx, functionLibInfo *li) { - dictIterator *iter = dictGetIterator(li->functions); + hashtableIterator *iter = dictGetIterator(li->functions); dictEntry *entry = NULL; while ((entry = dictNext(iter))) { - functionInfo *fi = dictGetVal(entry); + functionInfo *fi = entry->v.val; dictAdd(lib_ctx->functions, sdsnew(objectGetVal(fi->compiled_function->name)), fi); @@ -377,14 +377,14 @@ static void libraryLink(functionsLibCtx *lib_ctx, functionLibInfo *li) { static int libraryJoin(functionsLibCtx *functions_lib_ctx_dst, functionsLibCtx *functions_lib_ctx_src, int replace, sds *err) { int ret = C_ERR; - dictIterator *iter = NULL; + hashtableIterator *iter = NULL; /* Stores the libraries we need to replace in case a revert is required. * Only initialized when needed */ list *old_libraries_list = NULL; dictEntry *entry = NULL; iter = dictGetIterator(functions_lib_ctx_src->libraries); while ((entry = dictNext(iter))) { - functionLibInfo *li = dictGetVal(entry); + functionLibInfo *li = entry->v.val; functionLibInfo *old_li = dictFetchValue(functions_lib_ctx_dst->libraries, li->name); if (old_li) { if (!replace) { @@ -407,7 +407,7 @@ libraryJoin(functionsLibCtx *functions_lib_ctx_dst, functionsLibCtx *functions_l /* Make sure no functions collision */ iter = dictGetIterator(functions_lib_ctx_src->functions); while ((entry = dictNext(iter))) { - functionInfo *fi = dictGetVal(entry); + functionInfo *fi = entry->v.val; if (dictFetchValue(functions_lib_ctx_dst->functions, objectGetVal(fi->compiled_function->name))) { *err = sdscatfmt(sdsempty(), @@ -422,9 +422,9 @@ libraryJoin(functionsLibCtx *functions_lib_ctx_dst, functionsLibCtx *functions_l /* No collision, it is safe to link all the new libraries. */ iter = dictGetIterator(functions_lib_ctx_src->libraries); while ((entry = dictNext(iter))) { - functionLibInfo *li = dictGetVal(entry); + functionLibInfo *li = entry->v.val; libraryLink(functions_lib_ctx_dst, li); - dictSetVal(functions_lib_ctx_src->libraries, entry, NULL); + entry->v.val = NULL; } dictReleaseIterator(iter); iter = NULL; @@ -465,10 +465,10 @@ static void replyEngineStats(scriptingEngine *engine, void *context) { } void functionsRemoveLibFromEngine(scriptingEngine *engine) { - dictIterator *iter = dictGetSafeIterator(curr_functions_lib_ctx->libraries); + hashtableIterator *iter = dictGetSafeIterator(curr_functions_lib_ctx->libraries); dictEntry *entry = NULL; while ((entry = dictNext(iter))) { - functionLibInfo *li = dictGetVal(entry); + functionLibInfo *li = entry->v.val; if (li->engine == engine) { libraryUnlink(curr_functions_lib_ctx, li); engineLibraryFree(li); @@ -569,10 +569,10 @@ void functionListCommand(client *c) { /* If no pattern is asked we know the reply len and we can just set it */ addReplyArrayLen(c, dictSize(curr_functions_lib_ctx->libraries)); } - dictIterator *iter = dictGetIterator(curr_functions_lib_ctx->libraries); + hashtableIterator *iter = dictGetIterator(curr_functions_lib_ctx->libraries); dictEntry *entry = NULL; while ((entry = dictNext(iter))) { - functionLibInfo *li = dictGetVal(entry); + functionLibInfo *li = entry->v.val; if (library_name) { if (!stringmatchlen(library_name, sdslen(library_name), li->name, sdslen(li->name), 1)) { continue; @@ -588,10 +588,10 @@ void functionListCommand(client *c) { addReplyBulkCString(c, "functions"); addReplyArrayLen(c, dictSize(li->functions)); - dictIterator *functions_iter = dictGetIterator(li->functions); + hashtableIterator *functions_iter = dictGetIterator(li->functions); dictEntry *function_entry = NULL; while ((function_entry = dictNext(functions_iter))) { - functionInfo *fi = dictGetVal(function_entry); + functionInfo *fi = function_entry->v.val; addReplyMapLen(c, 3); addReplyBulkCString(c, "name"); addReplyBulkCString(c, objectGetVal(fi->compiled_function->name)); @@ -647,7 +647,7 @@ uint64_t fcallGetCommandFlags(client *c, uint64_t cmd_flags) { robj *function_name = c->argv[1]; c->cur_script = dictFind(curr_functions_lib_ctx->functions, objectGetVal(function_name)); if (!c->cur_script) return cmd_flags; - functionInfo *fi = dictGetVal(c->cur_script); + functionInfo *fi = c->cur_script->v.val; uint64_t script_flags = fi->compiled_function->f_flags; return scriptFlagsToCmdFlags(cmd_flags, script_flags); } @@ -663,7 +663,7 @@ static void fcallCommandGeneric(client *c, int ro) { addReplyError(c, "Function not found"); return; } - functionInfo *fi = dictGetVal(de); + functionInfo *fi = de->v.val; scriptingEngine *engine = fi->li->engine; long long numkeys; @@ -1007,7 +1007,7 @@ static void freeCompiledFunctions(scriptingEngine *engine, /* Compile and save the given library, return the loaded library name on success * and NULL on failure. In case on failure the err out param is set with relevant error message */ sds functionsCreateWithLibraryCtx(sds code, int replace, sds *err, functionsLibCtx *lib_ctx, size_t timeout) { - dictIterator *iter = NULL; + hashtableIterator *iter = NULL; dictEntry *entry = NULL; functionLibInfo *old_li = NULL; functionsLibMetaData md = {0}; @@ -1083,7 +1083,7 @@ sds functionsCreateWithLibraryCtx(sds code, int replace, sds *err, functionsLibC /* Verify no duplicate functions */ iter = dictGetIterator(new_li->functions); while ((entry = dictNext(iter))) { - functionInfo *fi = dictGetVal(entry); + functionInfo *fi = entry->v.val; if (dictFetchValue(lib_ctx->functions, objectGetVal(fi->compiled_function->name))) { /* functions name collision, abort. */ @@ -1189,7 +1189,7 @@ unsigned long functionsLibNum(void) { return dictSize(curr_functions_lib_ctx->libraries); } -dict *functionsLibGet(void) { +hashtable *functionsLibGet(void) { return curr_functions_lib_ctx->libraries; } diff --git a/src/functions.h b/src/functions.h index 8dc2164537..8111927cf0 100644 --- a/src/functions.h +++ b/src/functions.h @@ -76,7 +76,7 @@ typedef struct functionInfo { * Used on rdb.c so it must be declared here. */ struct functionLibInfo { sds name; /* Library name */ - dict *functions; /* Functions dictionary */ + hashtable *functions; /* Functions dictionary */ scriptingEngine *engine; /* Pointer to the scripting engine */ sds code; /* Library code */ }; @@ -86,14 +86,14 @@ unsigned long functionsMemory(void); unsigned long functionsMemoryOverhead(void); unsigned long functionsNum(void); unsigned long functionsLibNum(void); -dict *functionsLibGet(void); +hashtable *functionsLibGet(void); size_t functionsLibCtxFunctionsLen(functionsLibCtx *functions_ctx); functionsLibCtx *functionsLibCtxGetCurrent(void); functionsLibCtx *functionsLibCtxCreate(void); -void functionsLibCtxFree(functionsLibCtx *functions_lib_ctx, void(callback)(dict *), list *engine_callbacks); -void functionsLibCtxClear(functionsLibCtx *lib_ctx, void(callback)(dict *)); +void functionsLibCtxFree(functionsLibCtx *functions_lib_ctx, void(callback)(hashtable *), list *engine_callbacks); +void functionsLibCtxClear(functionsLibCtx *lib_ctx, void(callback)(hashtable *)); void functionsLibCtxSwapWithCurrent(functionsLibCtx *new_lib_ctx, int async); -void functionReset(int async, void(callback)(dict *)); +void functionReset(int async, void(callback)(hashtable *)); void functionsRemoveLibFromEngine(scriptingEngine *engine); diff --git a/src/fuzzer_command_generator.c b/src/fuzzer_command_generator.c index 05117fbbbe..d9637a8c55 100644 --- a/src/fuzzer_command_generator.c +++ b/src/fuzzer_command_generator.c @@ -99,7 +99,7 @@ typedef struct { size_t commandRegistrySize; CommandEntry *subscribeCommandRegistry; size_t subscribeCommandRegistrySize; - dict *configDict; + hashtable *configDict; sds *aclCategories; size_t aclCategoriesCount; int max_keys; @@ -301,20 +301,20 @@ static uint64_t sdsHash(const void *key) { static void dictEntryDestructorSdsKeyConfigVal(void *entry) { dictEntry *de = entry; - sdsfree(dictGetKey(de)); - configDictValDestructor(dictGetVal(de)); + sdsfree(de->key); + configDictValDestructor(de->v.val); zfree(de); } /* Dictionary type for config entries */ -static dictType configDictType = { +static hashtableType configDictType = { .entryGetKey = dictEntryGetKey, .hashFunction = sdsHash, .keyCompare = sdsKeyCompare, .entryDestructor = dictEntryDestructorSdsKeyConfigVal, }; -dict *initConfigDict(void) { +hashtable *initConfigDict(void) { return dictCreate(&configDictType); } @@ -413,7 +413,7 @@ static int shouldFilterConfig(const char *key) { return 0; } -void addConfigEntry(dict *configDict, const char *key, const char *value) { +void addConfigEntry(hashtable *configDict, const char *key, const char *value) { ConfigEntry *entry = zmalloc(sizeof(ConfigEntry)); entry->value = sdsnew(value); @@ -581,12 +581,12 @@ void generateRandomConfigValue(FuzzerCommand *cmd, ConfigEntry *entry) { } void generateConfigSetCommand(FuzzerCommand *cmd) { - dict *configDict = fuzz_ctx->configDict; + hashtable *configDict = fuzz_ctx->configDict; /* Get a random key from the dictionary */ dictEntry *randomEntry = dictGetRandomKey(configDict); - const char *key = dictGetKey(randomEntry); - ConfigEntry *entry = dictGetVal(randomEntry); + const char *key = randomEntry->key; + ConfigEntry *entry = randomEntry->v.val; /* Build the CONFIG SET command */ appendArg(cmd, sdsnew("CONFIG")); @@ -618,8 +618,8 @@ static void freeAclCategories(void) { fuzz_ctx->aclCategoriesCount = 0; } -dict *parseConfigOutput(valkeyReply *reply) { - dict *configDict = initConfigDict(); +hashtable *parseConfigOutput(valkeyReply *reply) { + hashtable *configDict = initConfigDict(); /* `CONFIG GET *` returns an array of key-value pairs */ for (size_t i = 0; i < reply->elements; i += 2) { diff --git a/src/latency.c b/src/latency.c index f71094c394..8582d1c89b 100644 --- a/src/latency.c +++ b/src/latency.c @@ -40,12 +40,12 @@ static void dictEntryDestructorHeapKeyValue(void *entry) { dictEntry *de = entry; - zfree(dictGetKey(de)); - zfree(dictGetVal(de)); + zfree(de->key); + zfree(de->v.val); zfree(de); } -dictType latencyTimeSeriesDictType = { +hashtableType latencyTimeSeriesDictType = { .entryGetKey = dictEntryGetKey, .hashFunction = dictCStrHash, .keyCompare = dictCStrKeyCompare, @@ -116,13 +116,13 @@ void latencyAddSample(const char *event, ustime_t latency_us) { * Note: this is O(N) even when event_to_reset is not NULL because makes * the code simpler and we have a small fixed max number of events. */ int latencyResetEvent(char *event_to_reset) { - dictIterator *di; + hashtableIterator *di; dictEntry *de; int resets = 0; di = dictGetSafeIterator(server.latency_events); while ((de = dictNext(di)) != NULL) { - char *event = dictGetKey(de); + char *event = de->key; if (event_to_reset == NULL || strcasecmp(event, event_to_reset) == 0) { dictDelete(server.latency_events, event); @@ -225,14 +225,14 @@ sds createLatencyReport(void) { /* Show all the events stats and add for each event some event-related * comment depending on the values. */ - dictIterator *di; + hashtableIterator *di; dictEntry *de; int eventnum = 0; di = dictGetSafeIterator(server.latency_events); while ((de = dictNext(di)) != NULL) { - char *event = dictGetKey(de); - struct latencyTimeSeries *ts = dictGetVal(de); + char *event = de->key; + struct latencyTimeSeries *ts = de->v.val; struct latencyStats ls; if (ts == NULL) continue; @@ -605,14 +605,14 @@ void latencyCommandReplyWithSamples(client *c, struct latencyTimeSeries *ts) { /* latencyCommand() helper to produce the reply for the LATEST subcommand, * listing the last latency sample for every event type registered so far. */ void latencyCommandReplyWithLatestEvents(client *c) { - dictIterator *di; + hashtableIterator *di; dictEntry *de; addReplyArrayLen(c, dictSize(server.latency_events)); di = dictGetIterator(server.latency_events); while ((de = dictNext(di)) != NULL) { - char *event = dictGetKey(de); - struct latencyTimeSeries *ts = dictGetVal(de); + char *event = de->key; + struct latencyTimeSeries *ts = de->v.val; int last = (ts->idx + LATENCY_TS_LEN - 1) % LATENCY_TS_LEN; addReplyArrayLen(c, 6); @@ -698,8 +698,8 @@ void latencyCommand(client *c) { de = dictFind(server.latency_events, objectGetVal(c->argv[2])); if (de == NULL) goto nodataerr; - ts = dictGetVal(de); - event = dictGetKey(de); + ts = de->v.val; + event = de->key; graph = latencyCommandGenSparkeline(event, ts); addReplyVerbatim(c, graph, sdslen(graph), "txt"); diff --git a/src/lazyfree.c b/src/lazyfree.c index ef33895863..9c74acc164 100644 --- a/src/lazyfree.c +++ b/src/lazyfree.c @@ -54,7 +54,7 @@ void lazyFreeErrors(void *args[]) { /* Release the eval scripts data structures. */ void lazyFreeEvalScripts(void *args[]) { - dict *scripts = args[0]; + hashtable *scripts = args[0]; list *scripts_lru_list = args[1]; list *engine_callbacks = args[2]; long long len = dictSize(scripts); @@ -87,7 +87,7 @@ void lazyFreeReplicationBacklogRefMem(void *args[]) { /* Release the replicaKeysWithExpire dict. */ void lazyFreeReplicaKeysWithExpire(void *args[]) { - dict *replica_keys_with_expire = args[0]; + hashtable *replica_keys_with_expire = args[0]; size_t len = dictSize(replica_keys_with_expire); dictRelease(replica_keys_with_expire); atomic_fetch_sub_explicit(&lazyfree_objects, len, memory_order_relaxed); @@ -248,7 +248,7 @@ void freeErrorsRadixTreeAsync(rax *errors) { /* Free scripts dict, and lru list, if the dict is huge enough, free them in * async way. * Close lua interpreter, if there are a lot of lua scripts, close it in async way. */ -void freeEvalScriptsAsync(dict *scripts, list *scripts_lru_list, list *engine_callbacks) { +void freeEvalScriptsAsync(hashtable *scripts, list *scripts_lru_list, list *engine_callbacks) { if (dictSize(scripts) > LAZYFREE_THRESHOLD) { atomic_fetch_add_explicit(&lazyfree_objects, dictSize(scripts), memory_order_relaxed); bioCreateLazyFreeJob(lazyFreeEvalScripts, 3, scripts, scripts_lru_list, engine_callbacks); @@ -280,7 +280,7 @@ void freeReplicationBacklogRefMemAsync(list *blocks, rax *index) { } /* Free replicaKeysWithExpire dict, if the dict is huge enough, free it in async way. */ -void freeReplicaKeysWithExpireAsync(dict *replica_keys_with_expire) { +void freeReplicaKeysWithExpireAsync(hashtable *replica_keys_with_expire) { if (dictSize(replica_keys_with_expire) > LAZYFREE_THRESHOLD) { atomic_fetch_add_explicit(&lazyfree_objects, dictSize(replica_keys_with_expire), memory_order_relaxed); bioCreateLazyFreeJob(lazyFreeReplicaKeysWithExpire, 1, replica_keys_with_expire); diff --git a/src/module.c b/src/module.c index 4342144016..22fe9debaa 100644 --- a/src/module.c +++ b/src/module.c @@ -89,11 +89,11 @@ struct moduleLoadQueueEntry { struct ValkeyModuleInfoCtx { struct ValkeyModule *module; - dict *requested_sections; + hashtable *requested_sections; sds info; /* info string we collected so far */ int sections; /* number of sections we collected so far */ int in_section; /* indication if we're in an active section or not */ - int in_dict_field; /* indication that we're currently appending to a dict */ + int in_dict_field; /* indication that we're currently appending to a hashtable */ }; /* This represents a shared API. Shared APIs will be used to populate @@ -106,7 +106,7 @@ struct ValkeyModuleSharedAPI { }; typedef struct ValkeyModuleSharedAPI ValkeyModuleSharedAPI; -dict *modules; /* Hash table of modules. SDS -> ValkeyModule ptr.*/ +hashtable *modules; /* Hash table of modules. SDS -> ValkeyModule ptr.*/ /* Entries in the context->amqueue array, representing objects to free * when the callback returns. */ @@ -865,7 +865,7 @@ int VM_GetApi(const char *funcname, void **targetPtrPtr) { * used implicitly by including valkeymodule.h. */ dictEntry *he = dictFind(server.moduleapi, funcname); if (!he) return VALKEYMODULE_ERR; - *targetPtrPtr = dictGetVal(he); + *targetPtrPtr = he->v.val; return VALKEYMODULE_OK; } @@ -7195,11 +7195,11 @@ uint64_t moduleTypeEncodeId(const char *name, int encver) { * a type with the same name as the one given. Returns the moduleType * structure pointer if such a module is found, or NULL otherwise. */ moduleType *moduleTypeLookupModuleByNameInternal(const char *name, int ignore_case) { - dictIterator *di = dictGetIterator(modules); + hashtableIterator *di = dictGetIterator(modules); dictEntry *de; while ((de = dictNext(di)) != NULL) { - struct ValkeyModule *module = dictGetVal(de); + struct ValkeyModule *module = de->v.val; listIter li; listNode *ln; @@ -7244,11 +7244,11 @@ moduleType *moduleTypeLookupModuleByID(uint64_t id) { /* Slow module by module lookup. */ moduleType *mt = NULL; - dictIterator *di = dictGetIterator(modules); + hashtableIterator *di = dictGetIterator(modules); dictEntry *de; while ((de = dictNext(di)) != NULL && mt == NULL) { - struct ValkeyModule *module = dictGetVal(de); + struct ValkeyModule *module = de->v.val; listIter li; listNode *ln; @@ -7589,11 +7589,11 @@ void moduleRDBLoadError(ValkeyModuleIO *io) { * VALKEYMODULE_OPTIONS_HANDLE_IO_ERRORS, in which case diskless loading should * be avoided since it could cause data loss. */ int moduleAllDatatypesHandleErrors(void) { - dictIterator *di = dictGetIterator(modules); + hashtableIterator *di = dictGetIterator(modules); dictEntry *de; while ((de = dictNext(di)) != NULL) { - struct ValkeyModule *module = dictGetVal(de); + struct ValkeyModule *module = de->v.val; if (listLength(module->types) && !(module->options & VALKEYMODULE_OPTIONS_HANDLE_IO_ERRORS)) { dictReleaseIterator(di); return 0; @@ -7607,11 +7607,11 @@ int moduleAllDatatypesHandleErrors(void) { * diskless async loading should be avoided because module doesn't know there can be traffic during * database full resynchronization. */ int moduleAllModulesHandleReplAsyncLoad(void) { - dictIterator *di = dictGetIterator(modules); + hashtableIterator *di = dictGetIterator(modules); dictEntry *de; while ((de = dictNext(di)) != NULL) { - struct ValkeyModule *module = dictGetVal(de); + struct ValkeyModule *module = de->v.val; if (!(module->options & VALKEYMODULE_OPTIONS_HANDLE_REPL_ASYNC_LOAD)) { dictReleaseIterator(di); return 0; @@ -7622,11 +7622,11 @@ int moduleAllModulesHandleReplAsyncLoad(void) { } int moduleVerifyAllAllowAtomicSlotMigrationOrReply(client *c) { - dictIterator *di = dictGetIterator(modules); + hashtableIterator *di = dictGetIterator(modules); dictEntry *de; while ((de = dictNext(di)) != NULL) { - struct ValkeyModule *module = dictGetVal(de); + struct ValkeyModule *module = de->v.val; if (!(module->options & VALKEYMODULE_OPTIONS_HANDLE_ATOMIC_SLOT_MIGRATION)) { addReplyErrorFormat(c, "The module %s does not support atomic slot migrations. " "Please ensure all modules have declared support for " @@ -7898,11 +7898,11 @@ long double VM_LoadLongDouble(ValkeyModuleIO *io) { * who asked for it. */ ssize_t rdbSaveModulesAux(rio *rdb, int when) { size_t total_written = 0; - dictIterator *di = dictGetIterator(modules); + hashtableIterator *di = dictGetIterator(modules); dictEntry *de; while ((de = dictNext(di)) != NULL) { - struct ValkeyModule *module = dictGetVal(de); + struct ValkeyModule *module = de->v.val; listIter li; listNode *ln; @@ -11152,12 +11152,12 @@ int VM_RegisterInfoFunc(ValkeyModuleCtx *ctx, ValkeyModuleInfoFunc cb) { return VALKEYMODULE_OK; } -sds modulesCollectInfo(sds info, dict *sections_dict, int for_crash_report, int sections) { - dictIterator *di = dictGetIterator(modules); +sds modulesCollectInfo(sds info, hashtable *sections_dict, int for_crash_report, int sections) { + hashtableIterator *di = dictGetIterator(modules); dictEntry *de; while ((de = dictNext(di)) != NULL) { - struct ValkeyModule *module = dictGetVal(de); + struct ValkeyModule *module = de->v.val; if (!module->info_cb) continue; ValkeyModuleInfoCtx info_ctx = {module, sections_dict, info, sections, 0, 0}; module->info_cb(&info_ctx, for_crash_report); @@ -11183,7 +11183,7 @@ ValkeyModuleServerInfoData *VM_GetServerInfo(ValkeyModuleCtx *ctx, const char *s int all = 0, everything = 0; robj *argv[1]; argv[0] = section ? createStringObject(section, strlen(section)) : NULL; - dict *section_dict = genInfoSectionDict(argv, section ? 1 : 0, NULL, &all, &everything); + hashtable *section_dict = genInfoSectionDict(argv, section ? 1 : 0, NULL, &all, &everything); sds info = genValkeyInfoString(section_dict, all, everything); int totlines, i; sds *lines = sdssplitlen(info, sdslen(info), "\r\n", 2, &totlines); @@ -11372,7 +11372,7 @@ int VM_ExportSharedAPI(ValkeyModuleCtx *ctx, const char *apiname, void *func) { void *VM_GetSharedAPI(ValkeyModuleCtx *ctx, const char *apiname) { dictEntry *de = dictFind(server.sharedapi, apiname); if (de == NULL) return NULL; - ValkeyModuleSharedAPI *sapi = dictGetVal(de); + ValkeyModuleSharedAPI *sapi = de->v.val; if (listSearchKey(sapi->module->usedby, ctx->module) == NULL) { listAddNodeTail(sapi->module->usedby, ctx->module); listAddNodeTail(ctx->module->using, sapi->module); @@ -11388,11 +11388,11 @@ void *VM_GetSharedAPI(ValkeyModuleCtx *ctx, const char *apiname) { * The number of unregistered APIs is returned. */ int moduleUnregisterSharedAPI(ValkeyModule *module) { int count = 0; - dictIterator *di = dictGetSafeIterator(server.sharedapi); + hashtableIterator *di = dictGetSafeIterator(server.sharedapi); dictEntry *de; while ((de = dictNext(di)) != NULL) { - const char *apiname = dictGetKey(de); - ValkeyModuleSharedAPI *sapi = dictGetVal(de); + const char *apiname = de->key; + ValkeyModuleSharedAPI *sapi = de->v.val; if (sapi->module == module) { dictDelete(server.sharedapi, apiname); zfree(sapi); @@ -12985,7 +12985,7 @@ size_t moduleGetMemUsage(robj *key, robj *val, size_t sample_size, int dbid) { /* server.moduleapi dictionary type. Only uses plain C strings since * this gets queries from modules. */ -dictType moduleAPIDictType = { +hashtableType moduleAPIDictType = { .entryGetKey = dictEntryGetKey, .hashFunction = dictCStrHash, .keyCompare = dictCStrKeyCompare, @@ -13012,7 +13012,7 @@ void moduleRegisterCoreAPI(void); void moduleInitModulesSystemLast(void) { } -dictType sdsKeyValueHashDictType = { +hashtableType sdsKeyValueHashDictType = { .entryGetKey = dictEntryGetKey, .hashFunction = dictSdsCaseHash, .keyCompare = dictSdsKeyCaseCompare, @@ -13143,10 +13143,10 @@ void moduleLoadFromQueue(void) { listDelNode(server.loadmodule_queue, ln); } if (dictSize(server.module_configs_queue)) { - dictIterator *di = dictGetSafeIterator(server.module_configs_queue); + hashtableIterator *di = dictGetSafeIterator(server.module_configs_queue); dictEntry *de; while ((de = dictNext(di)) != NULL) { - const char *moduleConfigName = dictGetKey(de); + const char *moduleConfigName = de->key; serverLog(LL_WARNING, "Unused Module Configuration: %s", moduleConfigName); } dictReleaseIterator(di); @@ -13649,11 +13649,11 @@ int moduleUnload(sds name, const char **errmsg) { * by module unload failures. */ void moduleUnloadAllModules(void) { - dictIterator *di = dictGetSafeIterator(modules); + hashtableIterator *di = dictGetSafeIterator(modules); dictEntry *de; while ((de = dictNext(di)) != NULL) { - struct ValkeyModule *module = dictGetVal(de); + struct ValkeyModule *module = de->v.val; const char *errmsg = NULL; if (moduleUnloadInternal(module, &errmsg) == C_ERR) { @@ -13679,13 +13679,13 @@ void modulePipeReadable(aeEventLoop *el, int fd, void *privdata, int mask) { /* Helper function for the MODULE and HELLO command: send the list of the * loaded modules to the client. */ void addReplyLoadedModules(client *c) { - dictIterator *di = dictGetIterator(modules); + hashtableIterator *di = dictGetIterator(modules); dictEntry *de; addReplyArrayLen(c, dictSize(modules)); while ((de = dictNext(di)) != NULL) { - sds name = dictGetKey(de); - struct ValkeyModule *module = dictGetVal(de); + sds name = de->key; + struct ValkeyModule *module = de->v.val; sds path = module->loadmod->path; addReplyMapLen(c, 4); addReplyBulkCString(c, "name"); @@ -13742,12 +13742,12 @@ sds genModulesInfoStringRenderModuleOptions(struct ValkeyModule *module) { * * references must be substituted with the new pointer returned by the call. */ sds genModulesInfoString(sds info) { - dictIterator *di = dictGetIterator(modules); + hashtableIterator *di = dictGetIterator(modules); dictEntry *de; while ((de = dictNext(di)) != NULL) { - sds name = dictGetKey(de); - struct ValkeyModule *module = dictGetVal(de); + sds name = de->key; + struct ValkeyModule *module = de->v.val; sds usedby = genModulesInfoStringRenderModulesList(module->usedby); sds using = genModulesInfoStringRenderModulesList(module->using); @@ -13896,8 +13896,8 @@ int loadModuleConfigs(ValkeyModule *module) { sds config_name = sdscatfmt(sdsempty(), "%s.%s", module->name, module_config->name); dictEntry *config_argument = dictFind(server.module_configs_queue, config_name); if (config_argument) { - if (!performModuleConfigSetFromName(dictGetKey(config_argument), dictGetVal(config_argument), &err)) { - serverLog(LL_WARNING, "Issue during loading of configuration %s : %s", (sds)dictGetKey(config_argument), + if (!performModuleConfigSetFromName(config_argument->key, config_argument->v.val, &err)) { + serverLog(LL_WARNING, "Issue during loading of configuration %s : %s", (sds)config_argument->key, err); sdsfree(config_name); dictEmpty(server.module_configs_queue, NULL); @@ -15019,11 +15019,11 @@ int moduleDefragValue(robj *key, robj *value, int dbid) { /* Call registered module API defrag functions */ void moduleDefragGlobals(void) { - dictIterator *di = dictGetIterator(modules); + hashtableIterator *di = dictGetIterator(modules); dictEntry *de; while ((de = dictNext(di)) != NULL) { - struct ValkeyModule *module = dictGetVal(de); + struct ValkeyModule *module = de->v.val; if (!module->defrag_cb) continue; ValkeyModuleDefragCtx defrag_ctx = {0, NULL, NULL, -1}; module->defrag_cb(&defrag_ctx); diff --git a/src/module.h b/src/module.h index f6ec2c4ebb..82db2f1629 100644 --- a/src/module.h +++ b/src/module.h @@ -228,7 +228,7 @@ ssize_t rdbSaveModulesAux(rio *rdb, int when); int moduleAllDatatypesHandleErrors(void); int moduleAllModulesHandleReplAsyncLoad(void); int moduleVerifyAllAllowAtomicSlotMigrationOrReply(client *c); -sds modulesCollectInfo(sds info, dict *sections_dict, int for_crash_report, int sections); +sds modulesCollectInfo(sds info, hashtable *sections_dict, int for_crash_report, int sections); void moduleFireServerEvent(uint64_t eid, int subid, void *data); void processModuleLoadingProgressEvent(int is_aof); int moduleTryServeClientBlockedOnKey(client *c, robj *key); diff --git a/src/multi.c b/src/multi.c index 9d35c5fe1d..2ccc2a351b 100644 --- a/src/multi.c +++ b/src/multi.c @@ -505,12 +505,12 @@ void touchAllWatchedKeysInDb(serverDb *emptied, serverDb *replaced_with) { if (dictSize(emptied->watched_keys) == 0) return; - dictIterator *di = dictGetSafeIterator(emptied->watched_keys); + hashtableIterator *di = dictGetSafeIterator(emptied->watched_keys); while ((de = dictNext(di)) != NULL) { - robj *key = dictGetKey(de); + robj *key = de->key; int exists_in_emptied = dbFind(emptied, objectGetVal(key)) != NULL; if (exists_in_emptied || (replaced_with && dbFind(replaced_with, objectGetVal(key)) != NULL)) { - list *clients = dictGetVal(de); + list *clients = de->v.val; if (!clients) continue; listRewind(clients, &li); while ((ln = listNext(&li))) { diff --git a/src/pubsub.c b/src/pubsub.c index ca45855b35..888d4c714a 100644 --- a/src/pubsub.c +++ b/src/pubsub.c @@ -410,7 +410,7 @@ bool pubsubSubscribePattern(client *c, robj *pattern) { dictAdd(server.pubsub_patterns, pattern, clients); incrRefCount(pattern); } else { - clients = dictGetVal(de); + clients = de->v.val; } serverAssert(hashtableAdd(clients, c)); } @@ -430,7 +430,7 @@ int pubsubUnsubscribePattern(client *c, robj *pattern, int notify) { /* Remove the client from the pattern -> clients list hash table */ dictEntry *de = dictFind(server.pubsub_patterns, pattern); serverAssertWithInfo(c, NULL, de != NULL); - hashtable *clients = dictGetVal(de); + hashtable *clients = de->v.val; serverAssertWithInfo(c, NULL, hashtableDelete(clients, c)); if (hashtableSize(clients) == 0) { /* Free the clients hashtable if this was the last client. */ @@ -509,7 +509,7 @@ int pubsubPublishMessageInternal(robj *channel, robj *message, pubsubtype type) int receivers = 0; void *element; dictEntry *de; - dictIterator *di; + hashtableIterator *di; int slot = -1; /* Send to clients listening for that channel */ @@ -540,8 +540,8 @@ int pubsubPublishMessageInternal(robj *channel, robj *message, pubsubtype type) if (di) { channel = getDecodedObject(channel); while ((de = dictNext(di)) != NULL) { - robj *pattern = dictGetKey(de); - hashtable *clients = dictGetVal(de); + robj *pattern = de->key; + hashtable *clients = de->v.val; if (!stringmatchlen((char *)objectGetVal(pattern), sdslen(objectGetVal(pattern)), (char *)objectGetVal(channel), sdslen(objectGetVal(channel)), 0)) continue; @@ -687,7 +687,7 @@ void pubsubCommand(client *c) { for (j = 2; j < c->argc; j++) { void *found = NULL; kvstoreHashtableFind(server.pubsub_channels, 0, c->argv[j], &found); - dict *d = found; + hashtable *d = found; addReplyBulk(c, c->argv[j]); addReplyLongLong(c, d ? dictSize(d) : 0); } diff --git a/src/rdb.c b/src/rdb.c index 054f594444..97cb655350 100644 --- a/src/rdb.c +++ b/src/rdb.c @@ -146,19 +146,19 @@ typedef struct { static void dictEntryDestructorSdsKeyHeapValue(void *entry) { dictEntry *de = entry; - dictSdsDestructor(dictGetKey(de)); - dictVanillaFree(dictGetVal(de)); + dictSdsDestructor(de->key); + dictVanillaFree(de->v.val); zfree(de); } -dictType rdbAuxFieldDictType = { +hashtableType rdbAuxFieldDictType = { .entryGetKey = dictEntryGetKey, .hashFunction = dictSdsCaseHash, .keyCompare = dictSdsKeyCaseCompare, .entryDestructor = dictEntryDestructorSdsKeyHeapValue, }; -dict *rdbAuxFields = NULL; +hashtable *rdbAuxFields = NULL; int rdbRegisterAuxField(char *auxfield, rdbAuxFieldEncoder encoder, rdbAuxFieldDecoder decoder) { if (rdbAuxFields == NULL) rdbAuxFields = dictCreate(&rdbAuxFieldDictType); @@ -1278,14 +1278,14 @@ int rdbSaveInfoAuxFields(rio *rdb, int rdbflags, rdbSaveInfo *rsi) { /* Handle additional dynamic aux fields */ if (rdbAuxFields != NULL) { - dictIterator di; + hashtableIterator di; dictInitIterator(&di, rdbAuxFields); dictEntry *de; while ((de = dictNext(&di)) != NULL) { - rdbAuxFieldCodec *codec = (rdbAuxFieldCodec *)dictGetVal(de); + rdbAuxFieldCodec *codec = (rdbAuxFieldCodec *)de->v.val; sds s = codec->encoder(rdbflags); if (s == NULL) continue; - if (rdbSaveAuxFieldStrStr(rdb, dictGetKey(de), s) == -1) { + if (rdbSaveAuxFieldStrStr(rdb, de->key, s) == -1) { sdsfree(s); return -1; } @@ -1363,15 +1363,15 @@ ssize_t rdbSaveSingleModuleAux(rio *rdb, int when, moduleType *mt) { } ssize_t rdbSaveFunctions(rio *rdb) { - dict *functions = functionsLibGet(); - dictIterator *iter = dictGetIterator(functions); + hashtable *functions = functionsLibGet(); + hashtableIterator *iter = dictGetIterator(functions); dictEntry *entry = NULL; ssize_t written = 0; ssize_t ret; while ((entry = dictNext(iter))) { if ((ret = rdbSaveType(rdb, RDB_OPCODE_FUNCTION2)) < 0) goto werr; written += ret; - functionLibInfo *li = dictGetVal(entry); + functionLibInfo *li = entry->v.val; if ((ret = rdbSaveRawString(rdb, (unsigned char *)li->code, sdslen(li->code))) < 0) goto werr; written += ret; } @@ -3353,7 +3353,7 @@ int rdbLoadRioWithLoadingCtx(rio *rdb, int rdbflags, rdbSaveInfo *rsi, rdbLoadin dictEntry *de = dictFind(rdbAuxFields, objectGetVal(auxkey)); if (de != NULL) { handled = 1; - rdbAuxFieldCodec *codec = (rdbAuxFieldCodec *)dictGetVal(de); + rdbAuxFieldCodec *codec = (rdbAuxFieldCodec *)de->v.val; if (codec->decoder(rdbflags, objectGetVal(auxval)) == C_ERR) { decrRefCount(auxkey); decrRefCount(auxval); diff --git a/src/scripting_engine.c b/src/scripting_engine.c index 1f2a7ba2cb..1cd7fa554e 100644 --- a/src/scripting_engine.c +++ b/src/scripting_engine.c @@ -56,7 +56,7 @@ typedef struct scriptingEngine { typedef struct engineManager { - dict *engines; /* engines dictionary */ + hashtable *engines; /* engines dictionary */ size_t total_memory_overhead; /* the sum of the memory overhead of all registered scripting engines */ } engineManager; @@ -66,7 +66,7 @@ static engineManager engineMgr = { .total_memory_overhead = 0, }; -dictType engineDictType = { +hashtableType engineDictType = { .entryGetKey = dictEntryGetKey, .hashFunction = dictCStrCaseHash, .keyCompare = dictSdsKeyCaseCompare, @@ -176,7 +176,7 @@ int scriptingEngineManagerUnregister(const char *engine_name) { return C_ERR; } - scriptingEngine *e = dictGetVal(entry); + scriptingEngine *e = entry->v.val; functionsRemoveLibFromEngine(e); evalRemoveScriptsFromEngine(e); @@ -214,7 +214,7 @@ int scriptingEngineManagerUnregister(const char *engine_name) { scriptingEngine *scriptingEngineManagerFind(const char *engine_name) { dictEntry *entry = dictFind(engineMgr.engines, engine_name); if (entry) { - return dictGetVal(entry); + return entry->v.val; } return NULL; } @@ -239,10 +239,10 @@ uint64_t scriptingEngineGetAbiVersion(scriptingEngine *engine) { */ void scriptingEngineManagerForEachEngine(engineIterCallback callback, void *context) { - dictIterator *iter = dictGetIterator(engineMgr.engines); + hashtableIterator *iter = dictGetIterator(engineMgr.engines); dictEntry *entry = NULL; while ((entry = dictNext(iter))) { - scriptingEngine *e = dictGetVal(entry); + scriptingEngine *e = entry->v.val; callback(e, context); } dictReleaseIterator(iter); diff --git a/src/sentinel.c b/src/sentinel.c index 7340527d65..714a148faa 100644 --- a/src/sentinel.c +++ b/src/sentinel.c @@ -207,10 +207,10 @@ typedef struct sentinelValkeyInstance { mstime_t primary_reboot_down_after_period; /* Consider primary down after that period. */ mstime_t primary_reboot_since_time; /* primary reboot time since time. */ mstime_t info_refresh; /* Time at which we received INFO output from it. */ - dict *renamed_commands; /* Commands renamed in this instance: - Sentinel will use the alternative commands - mapped on this table to send things like - REPLICAOF, CONFIG, INFO, ... */ + hashtable *renamed_commands; /* Commands renamed in this instance: + Sentinel will use the alternative commands + mapped on this table to send things like + REPLICAOF, CONFIG, INFO, ... */ /* Role and the first time we observed it. * This is useful in order to delay replacing what the instance reports @@ -225,12 +225,12 @@ typedef struct sentinelValkeyInstance { mstime_t monitored_instance_failover_change_time; /* Last time monitored_instance_failover_state changed. */ /* Primary specific. */ - dict *sentinels; /* Other sentinels monitoring the same primary. */ - dict *replicas; /* Replicas for this primary instance. */ - unsigned int quorum; /* Number of sentinels that need to agree on failure. */ - int parallel_syncs; /* How many replicas to reconfigure at same time. */ - char *auth_pass; /* Password to use for AUTH against primary & replica. */ - char *auth_user; /* Username for ACLs AUTH against primary & replica. */ + hashtable *sentinels; /* Other sentinels monitoring the same primary. */ + hashtable *replicas; /* Replicas for this primary instance. */ + unsigned int quorum; /* Number of sentinels that need to agree on failure. */ + int parallel_syncs; /* How many replicas to reconfigure at same time. */ + char *auth_pass; /* Password to use for AUTH against primary & replica. */ + char *auth_user; /* Username for ACLs AUTH against primary & replica. */ /* Replica specific. */ mstime_t primary_link_down_time; /* Replica replication link down time. */ @@ -267,9 +267,9 @@ typedef struct sentinelValkeyInstance { struct sentinelState { char myid[CONFIG_RUN_ID_SIZE + 1]; /* This sentinel ID. */ uint64_t current_epoch; /* Current epoch. */ - dict *primaries; /* Dictionary of primary sentinelValkeyInstances. - Key is the instance name, value is the - sentinelValkeyInstance structure pointer. */ + hashtable *primaries; /* Dictionary of primary sentinelValkeyInstances. + Key is the instance name, value is the + sentinelValkeyInstance structure pointer. */ int tilt; /* Are we in TILT mode? */ int total_tilt; /* Number of tilt. */ int running_scripts; /* Number of scripts in execution right now. */ @@ -423,7 +423,7 @@ int sentinelFlushConfig(void); void sentinelGenerateInitialMonitorEvents(void); int sentinelSendPing(sentinelValkeyInstance *ri); int sentinelForceHelloUpdateForPrimary(sentinelValkeyInstance *primary); -sentinelValkeyInstance *getSentinelValkeyInstanceByAddrAndRunID(dict *instances, char *ip, int port, char *runid); +sentinelValkeyInstance *getSentinelValkeyInstanceByAddrAndRunID(hashtable *instances, char *ip, int port, char *runid); void sentinelSimFailureCrash(void); void sentinelAskPrimaryStateToOtherSentinels(sentinelValkeyInstance *primary, int flags); @@ -442,11 +442,11 @@ void dictInstancesValDestructor(void *obj) { static void dictEntryDestructorInstancesValue(void *entry) { dictEntry *de = entry; - dictInstancesValDestructor(dictGetVal(de)); + dictInstancesValDestructor(de->v.val); zfree(de); } -dictType instancesDictType = { +hashtableType instancesDictType = { .entryGetKey = dictEntryGetKey, .hashFunction = dictSdsHash, .keyCompare = dictSdsKeyCompare, @@ -457,7 +457,7 @@ dictType instancesDictType = { * * This is useful into sentinelGetObjectiveLeader() function in order to * count the votes and understand who is the leader. */ -dictType leaderVotesDictType = { +hashtableType leaderVotesDictType = { .entryGetKey = dictEntryGetKey, .hashFunction = dictSdsHash, .keyCompare = dictSdsKeyCompare, @@ -465,7 +465,7 @@ dictType leaderVotesDictType = { }; /* Instance renamed commands table. */ -dictType renamedCommandsDictType = { +hashtableType renamedCommandsDictType = { .entryGetKey = dictEntryGetKey, .hashFunction = dictSdsCaseHash, .keyCompare = dictSdsKeyCaseCompare, @@ -731,12 +731,12 @@ void sentinelEvent(int level, char *type, sentinelValkeyInstance *ri, const char * generated when a primary to monitor is added at runtime via the * SENTINEL MONITOR command. */ void sentinelGenerateInitialMonitorEvents(void) { - dictIterator *di; + hashtableIterator *di; dictEntry *de; di = dictGetIterator(sentinel.primaries); while ((de = dictNext(di)) != NULL) { - sentinelValkeyInstance *ri = dictGetVal(de); + sentinelValkeyInstance *ri = de->v.val; sentinelEvent(LL_WARNING, "+monitor", ri, "%@ quorum %d", ri->quorum); } dictReleaseIterator(di); @@ -1097,7 +1097,7 @@ instanceLink *releaseInstanceLink(instanceLink *link, sentinelValkeyInstance *ri * is returned. */ int sentinelTryConnectionSharing(sentinelValkeyInstance *ri) { serverAssert(ri->flags & SRI_SENTINEL); - dictIterator *di; + hashtableIterator *di; dictEntry *de; if (ri->runid == NULL) return C_ERR; /* No way to identify it. */ @@ -1105,7 +1105,7 @@ int sentinelTryConnectionSharing(sentinelValkeyInstance *ri) { di = dictGetIterator(sentinel.primaries); while ((de = dictNext(di)) != NULL) { - sentinelValkeyInstance *primary = dictGetVal(de), *match; + sentinelValkeyInstance *primary = de->v.val, *match; /* We want to share with the same physical Sentinel referenced * in other primaries, so skip our primary. */ if (primary == ri->primary) continue; @@ -1134,12 +1134,12 @@ void dropInstanceConnections(sentinelValkeyInstance *ri) { instanceLinkCloseConnection(ri->link, ri->link->pc); /* Disconnect with all replicas. */ - dictIterator *di; + hashtableIterator *di; dictEntry *de; sentinelValkeyInstance *repl_ri; di = dictGetIterator(ri->replicas); while ((de = dictNext(di)) != NULL) { - repl_ri = dictGetVal(de); + repl_ri = de->v.val; instanceLinkCloseConnection(repl_ri->link, repl_ri->link->cc); instanceLinkCloseConnection(repl_ri->link, repl_ri->link->pc); } @@ -1149,19 +1149,19 @@ void dropInstanceConnections(sentinelValkeyInstance *ri) { /* Drop all connections to other sentinels. Returns the number of connections * dropped.*/ int sentinelDropConnections(void) { - dictIterator *di; + hashtableIterator *di; dictEntry *de; int dropped = 0; di = dictGetIterator(sentinel.primaries); while ((de = dictNext(di)) != NULL) { - dictIterator *sdi; + hashtableIterator *sdi; dictEntry *sde; - sentinelValkeyInstance *ri = dictGetVal(de); + sentinelValkeyInstance *ri = de->v.val; sdi = dictGetIterator(ri->sentinels); while ((sde = dictNext(sdi)) != NULL) { - sentinelValkeyInstance *si = dictGetVal(sde); + sentinelValkeyInstance *si = sde->v.val; if (!si->link->disconnected) { instanceLinkCloseConnection(si->link, si->link->pc); instanceLinkCloseConnection(si->link, si->link->cc); @@ -1183,13 +1183,13 @@ int sentinelDropConnections(void) { * Return the number of updated Sentinel addresses. */ int sentinelUpdateSentinelAddressInAllPrimaries(sentinelValkeyInstance *ri) { serverAssert(ri->flags & SRI_SENTINEL); - dictIterator *di; + hashtableIterator *di; dictEntry *de; int reconfigured = 0; di = dictGetIterator(sentinel.primaries); while ((de = dictNext(di)) != NULL) { - sentinelValkeyInstance *primary = dictGetVal(de), *match; + sentinelValkeyInstance *primary = de->v.val, *match; match = getSentinelValkeyInstanceByAddrAndRunID(primary->sentinels, NULL, 0, ri->runid); /* If there is no match, this primary does not know about this * Sentinel, try with the next one. */ @@ -1276,7 +1276,7 @@ sentinelValkeyInstance *createSentinelValkeyInstance(char *name, sentinelValkeyInstance *primary) { sentinelValkeyInstance *ri; sentinelAddr *addr; - dict *table = NULL; + hashtable *table = NULL; sds sdsname; serverAssert(flags & (SRI_PRIMARY | SRI_REPLICA | SRI_SENTINEL)); @@ -1448,7 +1448,7 @@ const char *sentinelValkeyInstanceTypeStr(sentinelValkeyInstance *ri) { * The function returns 1 if the matching Sentinel was removed, otherwise * 0 if there was no Sentinel with this ID. */ int removeMatchingSentinelFromPrimary(sentinelValkeyInstance *primary, char *runid) { - dictIterator *di; + hashtableIterator *di; dictEntry *de; int removed = 0; @@ -1456,7 +1456,7 @@ int removeMatchingSentinelFromPrimary(sentinelValkeyInstance *primary, char *run di = dictGetSafeIterator(primary->sentinels); while ((de = dictNext(di)) != NULL) { - sentinelValkeyInstance *ri = dictGetVal(de); + sentinelValkeyInstance *ri = de->v.val; if (ri->runid && strcmp(ri->runid, runid) == 0) { dictDelete(primary->sentinels, ri->name); @@ -1473,8 +1473,8 @@ int removeMatchingSentinelFromPrimary(sentinelValkeyInstance *primary, char *run * * runid or addr can be NULL. In such a case the search is performed only * by the non-NULL field. */ -sentinelValkeyInstance *getSentinelValkeyInstanceByAddrAndRunID(dict *instances, char *addr, int port, char *runid) { - dictIterator *di; +sentinelValkeyInstance *getSentinelValkeyInstanceByAddrAndRunID(hashtable *instances, char *addr, int port, char *runid) { + hashtableIterator *di; dictEntry *de; sentinelValkeyInstance *instance = NULL; sentinelAddr *ri_addr = NULL; @@ -1489,7 +1489,7 @@ sentinelValkeyInstance *getSentinelValkeyInstanceByAddrAndRunID(dict *instances, } di = dictGetIterator(instances); while ((de = dictNext(di)) != NULL) { - sentinelValkeyInstance *ri = dictGetVal(de); + sentinelValkeyInstance *ri = de->v.val; if (runid && !ri->runid) continue; if ((runid == NULL || strcmp(ri->runid, runid) == 0) && @@ -1561,13 +1561,13 @@ void sentinelResetPrimary(sentinelValkeyInstance *ri, int flags) { /* Call sentinelResetPrimary() on every primary with a name matching the specified * pattern. */ int sentinelResetPrimariesByPattern(char *pattern, int flags) { - dictIterator *di; + hashtableIterator *di; dictEntry *de; int reset = 0; di = dictGetIterator(sentinel.primaries); while ((de = dictNext(di)) != NULL) { - sentinelValkeyInstance *ri = dictGetVal(de); + sentinelValkeyInstance *ri = de->v.val; if (ri->name) { if (stringmatch(pattern, ri->name, 0)) { @@ -1591,7 +1591,7 @@ int sentinelResetPrimaryAndChangeAddress(sentinelValkeyInstance *primary, char * sentinelAddr *oldaddr, *newaddr; sentinelAddr **replicas = NULL; int num_replicas = 0, j; - dictIterator *di; + hashtableIterator *di; dictEntry *de; newaddr = createSentinelAddr(hostname, port, 0); @@ -1605,7 +1605,7 @@ int sentinelResetPrimaryAndChangeAddress(sentinelValkeyInstance *primary, char * /* Don't include the one having the address we are switching to. */ di = dictGetIterator(primary->replicas); while ((de = dictNext(di)) != NULL) { - sentinelValkeyInstance *replica = dictGetVal(de); + sentinelValkeyInstance *replica = de->v.val; if (sentinelAddrOrHostnameEqual(replica->addr, newaddr)) continue; replicas[num_replicas++] = dupSentinelAddr(replica->addr); @@ -1673,15 +1673,15 @@ sentinelAddr *sentinelGetCurrentPrimaryAddress(sentinelValkeyInstance *primary) /* This function sets the down_after_period field value in 'primary' to all * the replicas and sentinel instances connected to this primary. */ void sentinelPropagateDownAfterPeriod(sentinelValkeyInstance *primary) { - dictIterator *di; + hashtableIterator *di; dictEntry *de; int j; - dict *d[] = {primary->replicas, primary->sentinels, NULL}; + hashtable *d[] = {primary->replicas, primary->sentinels, NULL}; for (j = 0; d[j]; j++) { di = dictGetIterator(d[j]); while ((de = dictNext(di)) != NULL) { - sentinelValkeyInstance *ri = dictGetVal(de); + sentinelValkeyInstance *ri = de->v.val; ri->down_after_period = primary->down_after_period; } dictReleaseIterator(di); @@ -1991,7 +1991,7 @@ const char *sentinelHandleConfiguration(char **argv, int argc) { * Sentinel across restarts: config epoch of primaries, associated replicas * and sentinel instances, and so forth. */ void rewriteConfigSentinelOption(struct rewriteConfigState *state) { - dictIterator *di, *di2; + hashtableIterator *di, *di2; dictEntry *de; sds line; @@ -2024,7 +2024,7 @@ void rewriteConfigSentinelOption(struct rewriteConfigState *state) { sentinelAddr *primary_addr; /* sentinel monitor */ - primary = dictGetVal(de); + primary = de->v.val; primary_addr = sentinelGetCurrentPrimaryAddress(primary); line = sdscatprintf(sdsempty(), "sentinel monitor %s %s %d %d", primary->name, announceSentinelAddr(primary_addr), primary_addr->port, primary->quorum); @@ -2109,7 +2109,7 @@ void rewriteConfigSentinelOption(struct rewriteConfigState *state) { while ((de = dictNext(di2)) != NULL) { sentinelAddr *replica_addr; - ri = dictGetVal(de); + ri = de->v.val; replica_addr = ri->addr; /* If primary_addr (obtained using sentinelGetCurrentPrimaryAddress() @@ -2133,7 +2133,7 @@ void rewriteConfigSentinelOption(struct rewriteConfigState *state) { /* sentinel known-sentinel */ di2 = dictGetIterator(primary->sentinels); while ((de = dictNext(di2)) != NULL) { - ri = dictGetVal(de); + ri = de->v.val; if (ri->runid == NULL) continue; line = sdscatprintf(sdsempty(), "sentinel known-sentinel %s %s %d %s", primary->name, announceSentinelAddr(ri->addr), ri->addr->port, ri->runid); @@ -2145,8 +2145,8 @@ void rewriteConfigSentinelOption(struct rewriteConfigState *state) { /* sentinel rename-command */ di2 = dictGetIterator(primary->renamed_commands); while ((de = dictNext(di2)) != NULL) { - sds oldname = dictGetKey(de); - sds newname = dictGetVal(de); + sds oldname = de->key; + sds newname = de->v.val; line = sdscatprintf(sdsempty(), "sentinel rename-command %s %s %s", primary->name, oldname, newname); rewriteConfigRewriteLine(state, "sentinel rename-command", line, 1); /* rewriteConfigMarkAsProcessed is handled after the loop */ @@ -2802,7 +2802,7 @@ void sentinelProcessHelloMessage(char *hello, int hello_len) { /* If there is already other sentinel with same address (but * different runid) then remove the old one across all primaries */ sentinelEvent(LL_NOTICE, "+sentinel-invalid-addr", other, "%@"); - dictIterator *di; + hashtableIterator *di; dictEntry *de; /* Keep a copy of runid. 'other' about to be deleted in loop. */ @@ -2810,7 +2810,7 @@ void sentinelProcessHelloMessage(char *hello, int hello_len) { di = dictGetIterator(sentinel.primaries); while ((de = dictNext(di)) != NULL) { - sentinelValkeyInstance *primary = dictGetVal(de); + sentinelValkeyInstance *primary = de->v.val; removeMatchingSentinelFromPrimary(primary, runid_obsolete); } dictReleaseIterator(di); @@ -2950,13 +2950,13 @@ int sentinelSendHello(sentinelValkeyInstance *ri) { /* Reset last_pub_time in all the instances in the specified dictionary * in order to force the delivery of a Hello update ASAP. */ -void sentinelForceHelloUpdateDictOfValkeyInstances(dict *instances) { - dictIterator *di; +void sentinelForceHelloUpdateDictOfValkeyInstances(hashtable *instances) { + hashtableIterator *di; dictEntry *de; di = dictGetSafeIterator(instances); while ((de = dictNext(di)) != NULL) { - sentinelValkeyInstance *ri = dictGetVal(de); + sentinelValkeyInstance *ri = de->v.val; if (ri->last_pub_time >= (sentinel_publish_period + 1)) ri->last_pub_time -= (sentinel_publish_period + 1); } dictReleaseIterator(di); @@ -3065,7 +3065,7 @@ void sentinelSendPeriodicCommands(sentinelValkeyInstance *ri) { } /* =========================== SENTINEL command ============================= */ -static void populateDict(dict *options_dict, char **options) { +static void populateDict(hashtable *options_dict, char **options) { for (int i = 0; options[i]; i++) { sds option = sdsnew(options[i]); if (dictAdd(options_dict, option, NULL) == DICT_ERR) sdsfree(option); @@ -3099,12 +3099,12 @@ void sentinelConfigSetCommand(client *c) { "loglevel", NULL, }; - static dict *options_dict = NULL; + static hashtable *options_dict = NULL; if (!options_dict) { options_dict = dictCreate(&stringSetDictType); populateDict(options_dict, options); } - dict *set_configs = dictCreate(&stringSetDictType); + hashtable *set_configs = dictCreate(&stringSetDictType); /* Validate arguments are valid */ for (int i = 3; i < c->argc; i++) { @@ -3213,7 +3213,7 @@ void sentinelConfigGetCommand(client *c) { void *replylen = addReplyDeferredLen(c); int matches = 0; /* Create a dictionary to store the input configs,to avoid adding duplicate twice */ - dict *d = dictCreate(&externalStringType); + hashtable *d = dictCreate(&externalStringType); for (int i = 3; i < c->argc; i++) { pattern = objectGetVal(c->argv[i]); /* If the string doesn't contain glob patterns and available in dictionary, don't look further, just continue. */ @@ -3680,15 +3680,15 @@ void addReplySentinelDebugInfo(client *c) { /* Output a number of instances contained inside a dictionary as * RESP. */ -void addReplyDictOfValkeyInstances(client *c, dict *instances) { - dictIterator *di; +void addReplyDictOfValkeyInstances(client *c, hashtable *instances) { + hashtableIterator *di; dictEntry *de; long replicas = 0; void *replylen = addReplyDeferredLen(c); di = dictGetIterator(instances); while ((de = dictNext(di)) != NULL) { - sentinelValkeyInstance *ri = dictGetVal(de); + sentinelValkeyInstance *ri = de->v.val; /* don't announce unannounced replicas */ if (ri->flags & SRI_REPLICA && !ri->replica_announced) continue; @@ -3717,7 +3717,7 @@ sentinelValkeyInstance *sentinelGetPrimaryByNameOrReplyError(client *c, robj *na #define SENTINEL_ISQR_NOQUORUM (1 << 0) #define SENTINEL_ISQR_NOAUTH (1 << 1) int sentinelIsQuorumReachable(sentinelValkeyInstance *primary, int *usableptr) { - dictIterator *di; + hashtableIterator *di; dictEntry *de; int usable = 1; /* Number of usable Sentinels. Init to 1 to count myself. */ int result = SENTINEL_ISQR_OK; @@ -3725,7 +3725,7 @@ int sentinelIsQuorumReachable(sentinelValkeyInstance *primary, int *usableptr) { di = dictGetIterator(primary->sentinels); while ((de = dictNext(di)) != NULL) { - sentinelValkeyInstance *ri = dictGetVal(de); + sentinelValkeyInstance *ri = de->v.val; if (ri->flags & (SRI_S_DOWN | SRI_O_DOWN)) continue; usable++; @@ -4024,9 +4024,9 @@ void sentinelCommand(client *c) { /* Create an ad-hoc dictionary type so that we can iterate * a dictionary composed of just the primary groups the user * requested. */ - dictType copy_keeper = instancesDictType; + hashtableType copy_keeper = instancesDictType; copy_keeper.entryDestructor = zfree; - dict *primaries_local = sentinel.primaries; + hashtable *primaries_local = sentinel.primaries; if (c->argc > 2) { primaries_local = dictCreate(©_keeper); @@ -4051,11 +4051,11 @@ void sentinelCommand(client *c) { */ addReplyArrayLen(c, dictSize(primaries_local) * 2); - dictIterator *di; + hashtableIterator *di; dictEntry *de; di = dictGetIterator(primaries_local); while ((de = dictNext(di)) != NULL) { - sentinelValkeyInstance *ri = dictGetVal(de); + sentinelValkeyInstance *ri = de->v.val; addReplyBulkCBuffer(c, ri->name, strlen(ri->name)); addReplyArrayLen(c, dictSize(ri->replicas) + 1); /* +1 for self */ addReplyArrayLen(c, 2); @@ -4065,11 +4065,11 @@ void sentinelCommand(client *c) { else addReplyNull(c); - dictIterator *sdi; + hashtableIterator *sdi; dictEntry *sde; sdi = dictGetIterator(ri->replicas); while ((sde = dictNext(sdi)) != NULL) { - sentinelValkeyInstance *sri = dictGetVal(sde); + sentinelValkeyInstance *sri = sde->v.val; addReplyArrayLen(c, 2); addReplyLongLong(c, ri->info_refresh ? (now - sri->info_refresh) : 0); if (sri->info) @@ -4121,23 +4121,23 @@ void sentinelCommand(client *c) { addReplyErrorArity(c); } -void addInfoSectionsToDict(dict *section_dict, char **sections); +void addInfoSectionsToDict(hashtable *section_dict, char **sections); /* INFO [
[
...]] */ void sentinelInfoCommand(client *c) { char *sentinel_sections[] = {"server", "clients", "cpu", "stats", "sentinel", NULL}; int sec_all = 0, sec_everything = 0; - static dict *cached_all_info_sections = NULL; + static hashtable *cached_all_info_sections = NULL; /* Get requested section list. */ - dict *sections_dict = genInfoSectionDict(c->argv + 1, c->argc - 1, sentinel_sections, &sec_all, &sec_everything); + hashtable *sections_dict = genInfoSectionDict(c->argv + 1, c->argc - 1, sentinel_sections, &sec_all, &sec_everything); /* Purge unsupported sections from the requested ones. */ dictEntry *de; - dictIterator *di = dictGetSafeIterator(sections_dict); + hashtableIterator *di = dictGetSafeIterator(sections_dict); while ((de = dictNext(di)) != NULL) { int i; - sds sec = dictGetKey(de); + sds sec = de->key; for (i = 0; sentinel_sections[i]; i++) if (!strcasecmp(sentinel_sections[i], sec)) break; /* section not found? remove it */ @@ -4158,7 +4158,7 @@ void sentinelInfoCommand(client *c) { sds info = genValkeyInfoString(sections_dict, 0, 0); if (sec_all || (dictFind(sections_dict, "sentinel") != NULL)) { - dictIterator *di; + hashtableIterator *di; dictEntry *de; int primary_id = 0; @@ -4179,7 +4179,7 @@ void sentinelInfoCommand(client *c) { di = dictGetIterator(sentinel.primaries); while ((de = dictNext(di)) != NULL) { - sentinelValkeyInstance *ri = dictGetVal(de); + sentinelValkeyInstance *ri = de->v.val; char *status = "ok"; if (ri->flags & SRI_O_DOWN) @@ -4201,7 +4201,7 @@ void sentinelInfoCommand(client *c) { /* Implements Sentinel version of the ROLE command. The output is * "sentinel" and the list of currently monitored primary names. */ void sentinelRoleCommand(client *c) { - dictIterator *di; + hashtableIterator *di; dictEntry *de; addReplyArrayLen(c, 2); @@ -4210,7 +4210,7 @@ void sentinelRoleCommand(client *c) { di = dictGetIterator(sentinel.primaries); while ((de = dictNext(di)) != NULL) { - sentinelValkeyInstance *ri = dictGetVal(de); + sentinelValkeyInstance *ri = de->v.val; addReplyBulkCString(c, ri->name); } @@ -4471,7 +4471,7 @@ void sentinelCheckSubjectivelyDown(sentinelValkeyInstance *ri) { * However messages can be delayed so there are no strong guarantees about * N instances agreeing at the same time about the down state. */ void sentinelCheckObjectivelyDown(sentinelValkeyInstance *primary) { - dictIterator *di; + hashtableIterator *di; dictEntry *de; unsigned int quorum = 0, odown = 0; @@ -4481,7 +4481,7 @@ void sentinelCheckObjectivelyDown(sentinelValkeyInstance *primary) { /* Count all the other sentinels. */ di = dictGetIterator(primary->sentinels); while ((de = dictNext(di)) != NULL) { - sentinelValkeyInstance *ri = dictGetVal(de); + sentinelValkeyInstance *ri = de->v.val; if (ri->flags & SRI_PRIMARY_DOWN) quorum++; } @@ -4550,12 +4550,12 @@ void sentinelAskPrimaryStateToOtherSentinels(sentinelValkeyInstance *primary, in char port[32]; ll2string(port, sizeof(port), primary->addr->port); - dictIterator *di; + hashtableIterator *di; dictEntry *de; di = dictGetIterator(primary->sentinels); while ((de = dictNext(di)) != NULL) { - sentinelValkeyInstance *ri = dictGetVal(de); + sentinelValkeyInstance *ri = de->v.val; mstime_t elapsed = mstime() - ri->last_primary_down_reply_time; int retval; @@ -4630,18 +4630,18 @@ struct sentinelLeader { /* Helper function for sentinelGetLeader, increment the counter * relative to the specified runid. */ -int sentinelLeaderIncr(dict *counters, char *runid) { +int sentinelLeaderIncr(hashtable *counters, char *runid) { dictEntry *existing, *de; uint64_t oldval; de = dictAddRaw(counters, runid, &existing); if (existing) { - oldval = dictGetUnsignedIntegerVal(existing); - dictSetUnsignedIntegerVal(existing, oldval + 1); + oldval = existing->v.u64; + existing->v.u64 = oldval + 1; return oldval + 1; } else { serverAssert(de != NULL); - dictSetUnsignedIntegerVal(de, 1); + de->v.u64 = 1; return 1; } } @@ -4653,8 +4653,8 @@ int sentinelLeaderIncr(dict *counters, char *runid) { * the Sentinels we know (ever seen since the last SENTINEL RESET) that * reported the same instance as leader for the same epoch. */ char *sentinelGetLeader(sentinelValkeyInstance *primary, uint64_t epoch) { - dict *counters; - dictIterator *di; + hashtable *counters; + hashtableIterator *di; dictEntry *de; unsigned int voters = 0, voters_quorum; char *myvote; @@ -4670,7 +4670,7 @@ char *sentinelGetLeader(sentinelValkeyInstance *primary, uint64_t epoch) { /* Count other sentinels votes */ di = dictGetIterator(primary->sentinels); while ((de = dictNext(di)) != NULL) { - sentinelValkeyInstance *ri = dictGetVal(de); + sentinelValkeyInstance *ri = de->v.val; if (ri->leader != NULL && ri->leader_epoch == sentinel.current_epoch) sentinelLeaderIncr(counters, ri->leader); } dictReleaseIterator(di); @@ -4680,11 +4680,11 @@ char *sentinelGetLeader(sentinelValkeyInstance *primary, uint64_t epoch) { * 2) And anyway at least primary->quorum votes. */ di = dictGetIterator(counters); while ((de = dictNext(di)) != NULL) { - uint64_t votes = dictGetUnsignedIntegerVal(de); + uint64_t votes = de->v.u64; if (votes > max_votes) { max_votes = votes; - winner = dictGetKey(de); + winner = de->key; } } dictReleaseIterator(di); @@ -5011,7 +5011,7 @@ sentinelValkeyInstance *sentinelSelectReplica(sentinelValkeyInstance *primary) { sentinelValkeyInstance **instance = zmalloc(sizeof(instance[0]) * dictSize(primary->replicas)); sentinelValkeyInstance *selected = NULL; int instances = 0; - dictIterator *di; + hashtableIterator *di; dictEntry *de; mstime_t max_primary_down_time = 0; @@ -5021,7 +5021,7 @@ sentinelValkeyInstance *sentinelSelectReplica(sentinelValkeyInstance *primary) { di = dictGetIterator(primary->replicas); while ((de = dictNext(di)) != NULL) { - sentinelValkeyInstance *replica = dictGetVal(de); + sentinelValkeyInstance *replica = de->v.val; mstime_t info_validity_time; if (replica->flags & (SRI_S_DOWN | SRI_O_DOWN)) continue; @@ -5169,7 +5169,7 @@ void sentinelFailoverWaitPromotion(sentinelValkeyInstance *ri) { void sentinelFailoverDetectEnd(sentinelValkeyInstance *primary) { int not_reconfigured = 0, timeout = 0; - dictIterator *di; + hashtableIterator *di; dictEntry *de; mstime_t elapsed = mstime() - primary->failover_state_change_time; @@ -5181,7 +5181,7 @@ void sentinelFailoverDetectEnd(sentinelValkeyInstance *primary) { * configured. */ di = dictGetIterator(primary->replicas); while ((de = dictNext(di)) != NULL) { - sentinelValkeyInstance *replica = dictGetVal(de); + sentinelValkeyInstance *replica = de->v.val; if (replica->flags & (SRI_PROMOTED | SRI_RECONF_DONE)) continue; if (replica->flags & SRI_S_DOWN) continue; @@ -5206,12 +5206,12 @@ void sentinelFailoverDetectEnd(sentinelValkeyInstance *primary) { * command to all the replicas still not reconfigured to replicate with * the new primary. */ if (timeout) { - dictIterator *di; + hashtableIterator *di; dictEntry *de; di = dictGetIterator(primary->replicas); while ((de = dictNext(di)) != NULL) { - sentinelValkeyInstance *replica = dictGetVal(de); + sentinelValkeyInstance *replica = de->v.val; int retval; if (replica->flags & (SRI_PROMOTED | SRI_RECONF_DONE | SRI_RECONF_SENT)) continue; @@ -5230,13 +5230,13 @@ void sentinelFailoverDetectEnd(sentinelValkeyInstance *primary) { /* Send REPLICAOF to all the remaining replicas that * still don't appear to have the configuration updated. */ void sentinelFailoverReconfNextReplica(sentinelValkeyInstance *primary) { - dictIterator *di; + hashtableIterator *di; dictEntry *de; int in_progress = 0; di = dictGetIterator(primary->replicas); while ((de = dictNext(di)) != NULL) { - sentinelValkeyInstance *replica = dictGetVal(de); + sentinelValkeyInstance *replica = de->v.val; if (replica->flags & (SRI_RECONF_SENT | SRI_RECONF_INPROG)) in_progress++; } @@ -5244,7 +5244,7 @@ void sentinelFailoverReconfNextReplica(sentinelValkeyInstance *primary) { di = dictGetIterator(primary->replicas); while (in_progress < primary->parallel_syncs && (de = dictNext(di)) != NULL) { - sentinelValkeyInstance *replica = dictGetVal(de); + sentinelValkeyInstance *replica = de->v.val; int retval; /* Skip the promoted replica, and already configured replicas. */ @@ -5367,15 +5367,15 @@ void sentinelHandleValkeyInstance(sentinelValkeyInstance *ri) { /* Perform scheduled operations for all the instances in the dictionary. * Recursively call the function against dictionaries of replicas. */ -void sentinelHandleDictOfValkeyInstances(dict *instances) { - dictIterator *di; +void sentinelHandleDictOfValkeyInstances(hashtable *instances) { + hashtableIterator *di; dictEntry *de; sentinelValkeyInstance *switch_to_promoted = NULL; /* There are a number of things we need to perform against every primary. */ di = dictGetIterator(instances); while ((de = dictNext(di)) != NULL) { - sentinelValkeyInstance *ri = dictGetVal(de); + sentinelValkeyInstance *ri = de->v.val; sentinelHandleValkeyInstance(ri); if (ri->flags & SRI_PRIMARY) { diff --git a/src/server.c b/src/server.c index e1cef181ff..384882ddcc 100644 --- a/src/server.c +++ b/src/server.c @@ -536,67 +536,67 @@ const void *hashtableSubcommandGetKey(const void *element) { /* Entry destructor that frees object key and the dictEntry itself */ void dictEntryDestructorObjectKey(void *entry) { dictEntry *de = entry; - dictObjectDestructor(dictGetKey(de)); + dictObjectDestructor(de->key); zfree(de); } /* Entry destructor that frees object key, heap pointer value, and the dictEntry itself */ void dictEntryDestructorObjectKeyHeapValue(void *entry) { dictEntry *de = entry; - dictObjectDestructor(dictGetKey(de)); - zfree(dictGetVal(de)); + dictObjectDestructor(de->key); + zfree(de->v.val); zfree(de); } /* Entry destructor that frees object key, list value, and the dictEntry itself */ void dictEntryDestructorObjectKeyListValue(void *entry) { dictEntry *de = entry; - dictObjectDestructor(dictGetKey(de)); - dictListDestructor(dictGetVal(de)); + dictObjectDestructor(de->key); + dictListDestructor(de->v.val); zfree(de); } /* Entry destructor that frees object key, hashtable value, and the dictEntry itself */ void dictEntryDestructorObjectKeyHashtableValue(void *entry) { dictEntry *de = entry; - dictObjectDestructor(dictGetKey(de)); - dictHashtableDestructor(dictGetVal(de)); + dictObjectDestructor(de->key); + dictHashtableDestructor(de->v.val); zfree(de); } /* Entry destructor that frees SDS key and the dictEntry itself */ void dictEntryDestructorSdsKey(void *entry) { dictEntry *de = entry; - dictSdsDestructor(dictGetKey(de)); + dictSdsDestructor(de->key); zfree(de); } void dictEntryDestructorSdsKeyValue(void *entry) { dictEntry *de = entry; - dictSdsDestructor(dictGetKey(de)); - dictSdsDestructor(dictGetVal(de)); + dictSdsDestructor(de->key); + dictSdsDestructor(de->v.val); zfree(de); } /* Entry destructor that frees SDS key, list value, and the dictEntry itself */ void dictEntryDestructorSdsKeyListValue(void *entry) { dictEntry *de = entry; - dictSdsDestructor(dictGetKey(de)); - dictListDestructor(dictGetVal(de)); + dictSdsDestructor(de->key); + dictListDestructor(de->v.val); zfree(de); } /* Entry destructor that frees SDS key, heap pointer value, and the dictEntry itself */ void dictEntryDestructorSdsKeyHeapValue(void *entry) { dictEntry *de = entry; - dictSdsDestructor(dictGetKey(de)); - zfree(dictGetVal(de)); + dictSdsDestructor(de->key); + zfree(de->v.val); zfree(de); } /* Generic hash table type where keys are Objects, Values * dummy pointers. */ -dictType objectKeyPointerValueDictType = { +hashtableType objectKeyPointerValueDictType = { .entryGetKey = dictEntryGetKey, .hashFunction = dictEncObjHash, .keyCompare = dictEncObjKeyCompare, @@ -605,7 +605,7 @@ dictType objectKeyPointerValueDictType = { /* Like objectKeyPointerValueDictType(), but values can be destroyed, if * not NULL, calling zfree(). */ -dictType objectKeyHeapPointerValueDictType = { +hashtableType objectKeyHeapPointerValueDictType = { .entryGetKey = dictEntryGetKey, .hashFunction = dictEncObjHash, .keyCompare = dictEncObjKeyCompare, @@ -745,7 +745,7 @@ hashtableType sdsReplyHashtableType = { /* Keylist hash table type has unencoded Objects as keys and * lists as values. It's used for blocking operations (BLPOP) and to * map swapped keys to a list of clients waiting for this keys to be loaded. */ -dictType keylistDictType = { +hashtableType keylistDictType = { .entryGetKey = dictEntryGetKey, .hashFunction = dictObjHash, .keyCompare = dictObjKeyCompare, @@ -754,7 +754,7 @@ dictType keylistDictType = { /* objToHashtableDictType has unencoded Objects as keys and * hashtables as values. It's used for PUBSUB command to track clients subscribing the patterns. */ -dictType objToHashtableDictType = { +hashtableType objToHashtableDictType = { .entryGetKey = dictEntryGetKey, .hashFunction = dictObjHash, .keyCompare = dictObjKeyCompare, @@ -792,7 +792,7 @@ hashtableType kvstoreChannelHashtableType = { /* Modules system dictionary type. Keys are module name, * values are pointer to ValkeyModule struct. */ -dictType modulesDictType = { +hashtableType modulesDictType = { .entryGetKey = dictEntryGetKey, .hashFunction = dictSdsCaseHash, .keyCompare = dictSdsKeyCaseCompare, @@ -800,7 +800,7 @@ dictType modulesDictType = { }; /* Migrate cache dict type. */ -dictType migrateCacheDictType = { +hashtableType migrateCacheDictType = { .entryGetKey = dictEntryGetKey, .hashFunction = dictSdsHash, .keyCompare = dictSdsKeyCompare, @@ -809,7 +809,7 @@ dictType migrateCacheDictType = { /* Dict for for case-insensitive search using null terminated C strings. * The keys stored in dict are sds though. */ -dictType stringSetDictType = { +hashtableType stringSetDictType = { .entryGetKey = dictEntryGetKey, .hashFunction = dictCStrCaseHash, .keyCompare = dictCStrKeyCaseCompare, @@ -818,7 +818,7 @@ dictType stringSetDictType = { /* Dict for for case-insensitive search using null terminated C strings. * The key and value do not have a destructor. */ -dictType externalStringType = { +hashtableType externalStringType = { .entryGetKey = dictEntryGetKey, .hashFunction = dictCStrCaseHash, .keyCompare = dictCStrKeyCaseCompare, @@ -827,7 +827,7 @@ dictType externalStringType = { /* Dict for case-insensitive search using sds objects with a zmalloc * allocated object as the value. */ -dictType sdsHashDictType = { +hashtableType sdsHashDictType = { .entryGetKey = dictEntryGetKey, .hashFunction = dictSdsCaseHash, .keyCompare = dictSdsKeyCaseCompare, @@ -5952,7 +5952,7 @@ sds genValkeyInfoStringLatencyStats(sds info, hashtable *commands) { } /* Takes a null terminated sections list, and adds them to the dict. */ -void addInfoSectionsToDict(dict *section_dict, char **sections) { +void addInfoSectionsToDict(hashtable *section_dict, char **sections) { while (*sections) { sds section = sdsnew(*sections); if (dictAdd(section_dict, section, NULL) == DICT_ERR) sdsfree(section); @@ -5961,9 +5961,9 @@ void addInfoSectionsToDict(dict *section_dict, char **sections) { } /* Cached copy of the default sections, as an optimization. */ -static dict *cached_default_info_sections = NULL; +static hashtable *cached_default_info_sections = NULL; -void releaseInfoSectionDict(dict *sec) { +void releaseInfoSectionDict(hashtable *sec) { if (sec != cached_default_info_sections) dictRelease(sec); } @@ -6028,7 +6028,7 @@ sds genValkeyInfoStringScriptingEngines(sds info) { * 'defaults' is an optional null terminated list of default sections. * 'out_all' and 'out_everything' are optional. * The resulting dictionary should be released with releaseInfoSectionDict. */ -dict *genInfoSectionDict(robj **argv, int argc, char **defaults, int *out_all, int *out_everything) { +hashtable *genInfoSectionDict(robj **argv, int argc, char **defaults, int *out_all, int *out_everything) { char *default_sections[] = { "server", "clients", @@ -6055,7 +6055,7 @@ dict *genInfoSectionDict(robj **argv, int argc, char **defaults, int *out_all, i return cached_default_info_sections; } - dict *section_dict = dictCreate(&stringSetDictType); + hashtable *section_dict = dictCreate(&stringSetDictType); dictExpand(section_dict, min(argc, 16)); for (int i = 0; i < argc; i++) { if (!strcasecmp(objectGetVal(argv[i]), "default")) { @@ -6095,7 +6095,7 @@ void totalNumberOfStatefulKeys(unsigned long *blocking_keys, /* Create the string returned by the INFO command. This is decoupled * by the INFO command itself as we need to report the same information * on memory corruption problems. */ -sds genValkeyInfoString(dict *section_dict, int all_sections, int everything) { +sds genValkeyInfoString(hashtable *section_dict, int all_sections, int everything) { sds info = sdsempty(); time_t uptime = server.unixtime - server.stat_starttime; int j; @@ -6808,7 +6808,7 @@ void infoCommand(client *c) { } int all_sections = 0; int everything = 0; - dict *sections_dict = genInfoSectionDict(c->argv + 1, c->argc - 1, NULL, &all_sections, &everything); + hashtable *sections_dict = genInfoSectionDict(c->argv + 1, c->argc - 1, NULL, &all_sections, &everything); sds info = genValkeyInfoString(sections_dict, all_sections, everything); addReplyVerbatim(c, info, sdslen(info), "txt"); sdsfree(info); diff --git a/src/server.h b/src/server.h index 0211264de4..e1cac1aa5d 100644 --- a/src/server.h +++ b/src/server.h @@ -899,16 +899,16 @@ typedef struct replBufBlock { * by integers from 0 (the default database) up to the max configured * database. The database number is the 'id' field in the structure. */ typedef struct serverDb { - kvstore *keys; /* The keyspace for this DB */ - kvstore *expires; /* Timeout of keys with a timeout set */ - kvstore *keys_with_volatile_items; /* Keys with volatile items */ - dict *blocking_keys; /* Keys with clients waiting for data (BLPOP)*/ - dict *blocking_keys_unblock_on_nokey; /* Keys with clients waiting for - * data, and should be unblocked if key is deleted (XREADEDGROUP). - * This is a subset of blocking_keys*/ - dict *ready_keys; /* Blocked keys that received a PUSH */ - dict *watched_keys; /* WATCHED keys for MULTI/EXEC CAS */ - int id; /* Database ID */ + kvstore *keys; /* The keyspace for this DB */ + kvstore *expires; /* Timeout of keys with a timeout set */ + kvstore *keys_with_volatile_items; /* Keys with volatile items */ + hashtable *blocking_keys; /* Keys with clients waiting for data (BLPOP)*/ + hashtable *blocking_keys_unblock_on_nokey; /* Keys with clients waiting for + * data, and should be unblocked if key is deleted (XREADEDGROUP). + * This is a subset of blocking_keys*/ + hashtable *ready_keys; /* Blocked keys that received a PUSH */ + hashtable *watched_keys; /* WATCHED keys for MULTI/EXEC CAS */ + int id; /* Database ID */ struct { long long avg_ttl; /* Average TTL, just for stats */ unsigned long cursor; /* Cursor of the active expire cycle. */ @@ -977,7 +977,7 @@ typedef struct blockingState { }; /* BLOCKED_LIST, BLOCKED_ZSET and BLOCKED_STREAM or any other Keys related blocking */ - dict *keys; /* The keys we are blocked on */ + hashtable *keys; /* The keys we are blocked on */ /* BLOCKED_WAIT */ int numreplicas; /* Number of replicas we are waiting for ACK. */ @@ -1788,11 +1788,11 @@ struct valkeyServer { int thp_enabled; /* If true, THP is enabled. */ size_t page_size; /* The page size of OS. */ /* Modules */ - dict *moduleapi; /* Exported core APIs dictionary for modules. */ - dict *sharedapi; /* Like moduleapi but containing the APIs that - modules share with each other. */ - dict *module_configs_queue; /* Dict that stores module configurations from .conf file until after modules are loaded - during startup or arguments to loadex. */ + hashtable *moduleapi; /* Exported core APIs dictionary for modules. */ + hashtable *sharedapi; /* Like moduleapi but containing the APIs that + modules share with each other. */ + hashtable *module_configs_queue; /* Dict that stores module configurations from .conf file until after modules are loaded + during startup or arguments to loadex. */ list *loadmodule_queue; /* List of modules to load at startup. */ int module_pipe[2]; /* Pipe used to awake the event loop by module threads. */ pid_t child_pid; /* PID of current child */ @@ -1840,7 +1840,7 @@ struct valkeyServer { list *postponed_clients; /* List of postponed clients */ pause_event client_pause_per_purpose[NUM_PAUSE_PURPOSES]; char neterr[ANET_ERR_LEN]; /* Error buffer for anet.c */ - dict *migrate_cached_sockets; /* MIGRATE cached sockets */ + hashtable *migrate_cached_sockets; /* MIGRATE cached sockets */ _Atomic(uint64_t) next_client_id; /* Next client unique ID. Incremental. */ int protected_mode; /* Don't accept external connections. */ int io_threads_num; /* Number of IO threads to use. */ @@ -2256,7 +2256,7 @@ struct valkeyServer { long long blocked_last_cron; /* Indicate the mstime of the last time we did cron jobs from a blocking operation */ /* Pubsub */ kvstore *pubsub_channels; /* Map channels to list of subscribed clients */ - dict *pubsub_patterns; /* A dict of pubsub_patterns */ + hashtable *pubsub_patterns; /* A dict of pubsub_patterns */ int notify_keyspace_events; /* Events to propagate via Pub/Sub. This is an xor of NOTIFY_... flags. */ kvstore *pubsubshard_channels; /* Map shard channels in every slot to list of subscribed clients */ @@ -2338,7 +2338,7 @@ struct valkeyServer { int lazyfree_lazy_user_flush; /* Latency monitor */ long long latency_monitor_threshold; - dict *latency_events; + hashtable *latency_events; /* ACLs */ char *acl_filename; /* ACL Users file. NULL if not configured. */ unsigned long acllog_max_len; /* Maximum length of the ACL LOG list. */ @@ -2819,9 +2819,9 @@ typedef struct clusterScanCtx { extern struct valkeyServer server; extern struct sharedObjectsStruct shared; -extern dictType objectKeyPointerValueDictType; +extern hashtableType objectKeyPointerValueDictType; extern hashtableType objectHashtableType; -extern dictType objectKeyHeapPointerValueDictType; +extern hashtableType objectKeyHeapPointerValueDictType; extern hashtableType setHashtableType; extern hashtableType zsetHashtableType; extern hashtableType kvstoreKeysHashtableType; @@ -2829,15 +2829,15 @@ extern hashtableType kvstoreExpiresHashtableType; extern double R_Zero, R_PosInf, R_NegInf, R_Nan; extern hashtableType hashHashtableType; extern hashtableType hashWithVolatileItemsHashtableType; -extern dictType stringSetDictType; -extern dictType externalStringType; -extern dictType sdsHashDictType; +extern hashtableType stringSetDictType; +extern hashtableType externalStringType; +extern hashtableType sdsHashDictType; extern hashtableType clientHashtableType; extern hashtableType kvstoreChannelHashtableType; -extern dictType modulesDictType; +extern hashtableType modulesDictType; extern hashtableType sdsReplyHashtableType; -extern dictType keylistDictType; -extern dict *modules; +extern hashtableType keylistDictType; +extern hashtable *modules; /*----------------------------------------------------------------------------- * Functions prototypes @@ -3849,12 +3849,12 @@ int redis_check_rdb_main(int argc, char **argv, FILE *fp); int redis_check_aof_main(int argc, char **argv); /* Scripting */ -void freeEvalScripts(dict *scripts, list *scripts_lru_list, list *engine_callbacks); -void freeEvalScriptsAsync(dict *scripts, list *scripts_lru_list, list *engine_callbacks); +void freeEvalScripts(hashtable *scripts, list *scripts_lru_list, list *engine_callbacks); +void freeEvalScriptsAsync(hashtable *scripts, list *scripts_lru_list, list *engine_callbacks); void freeFunctionsAsync(functionsLibCtx *lib_ctx, list *engine_callbacks); void sha1hex(char *digest, char *script, size_t len); unsigned long evalMemory(void); -dict *evalScriptsDict(void); +hashtable *evalScriptsDict(void); unsigned long evalScriptsMemory(void); uint64_t evalGetCommandFlags(client *c, uint64_t orig_flags); uint64_t fcallGetCommandFlags(client *c, uint64_t orig_flags); @@ -4257,9 +4257,9 @@ void setupDebugSigHandlers(void); void setupSigSegvHandler(void); void removeSigSegvHandlers(void); const char *getSafeInfoString(const char *s, size_t len, char **tmp); -dict *genInfoSectionDict(robj **argv, int argc, char **defaults, int *out_all, int *out_everything); -void releaseInfoSectionDict(dict *sec); -sds genValkeyInfoString(dict *section_dict, int all_sections, int everything); +hashtable *genInfoSectionDict(robj **argv, int argc, char **defaults, int *out_all, int *out_everything); +void releaseInfoSectionDict(hashtable *sec); +sds genValkeyInfoString(hashtable *section_dict, int all_sections, int everything); sds genModulesInfoString(sds info); void applyWatchdogPeriod(void); void watchdogScheduleSignal(int period); diff --git a/src/t_zset.c b/src/t_zset.c index 5dbd1f38d4..4446ddf291 100644 --- a/src/t_zset.c +++ b/src/t_zset.c @@ -2372,7 +2372,7 @@ static int zuiCompareByRevCardinality(const void *s1, const void *s2) { #define REDIS_AGGR_SUM 1 #define REDIS_AGGR_MIN 2 #define REDIS_AGGR_MAX 3 -#define zunionInterDictValue(_e) (dictGetVal(_e) == NULL ? 1.0 : *(double *)dictGetVal(_e)) +#define zunionInterDictValue(_e) (_e->v.val == NULL ? 1.0 : *(double *)_e->v.val) inline static void zunionInterAggregate(double *target, double val, int aggregate) { if (aggregate == REDIS_AGGR_SUM) { diff --git a/src/valkey-benchmark.c b/src/valkey-benchmark.c index fb4194696b..3d441543d2 100644 --- a/src/valkey-benchmark.c +++ b/src/valkey-benchmark.c @@ -316,7 +316,7 @@ static int dictSdsKeyCompare(const void *key1, const void *key2) { return memcmp(key1, key2, l1) == 0; } -static dictType dtype = { +static hashtableType dtype = { .entryGetKey = dictEntryGetKey, .hashFunction = dictSdsHash, .keyCompare = dictSdsKeyCompare, @@ -1437,7 +1437,7 @@ static int fetchClusterConfiguration(void) { int success = 1; valkeyContext *ctx = NULL; valkeyReply *reply = NULL; - dict *nodes = NULL; + hashtable *nodes = NULL; const char *errmsg = "Failed to fetch cluster configuration"; size_t i, j; ctx = getValkeyContext(config.ct, config.conn_info.hostip, config.conn_info.hostport); @@ -1491,7 +1491,7 @@ static int fetchClusterConfiguration(void) { if (!is_primary) node->replicate = sdsdup(primary); } } else { - node = dictGetVal(entry); + node = entry->v.val; sdsfree(ip); sdsfree(name); } @@ -1548,7 +1548,7 @@ static int fetchClusterSlotsConfiguration(client c) { const char *errmsg = "Failed to update cluster slots configuration"; /* printf("[%d] fetchClusterSlotsConfiguration\n", c->thread_id); */ - dict *nodes = dictCreate(&dtype); + hashtable *nodes = dictCreate(&dtype); valkeyContext *ctx = NULL; for (i = 0; i < (size_t)config.cluster_node_count; i++) { clusterNode *node = config.cluster_nodes[i]; @@ -1610,7 +1610,7 @@ static int fetchClusterSlotsConfiguration(client c) { goto cleanup; } sdsfree(name); - clusterNode *node = dictGetVal(entry); + clusterNode *node = entry->v.val; if (node->updated_slots == NULL) node->updated_slots = zcalloc(CLUSTER_SLOTS * sizeof(int)); for (slot = from; slot <= to; slot++) node->updated_slots[node->updated_slots_count++] = slot; } diff --git a/src/valkey-cli.c b/src/valkey-cli.c index bffa33b0f1..a035b1720a 100644 --- a/src/valkey-cli.c +++ b/src/valkey-cli.c @@ -392,20 +392,20 @@ static int dictSdsKeyCompare(const void *key1, const void *key2) { static void dictEntryDestructorSdsKeyNoVal(void *entry) { dictEntry *de = entry; - sdsfree(dictGetKey(de)); + sdsfree(de->key); zfree(de); } static void dictEntryDestructorSdsVal(void *entry) { dictEntry *de = entry; - sdsfree(dictGetVal(de)); + sdsfree(de->v.val); zfree(de); } static void dictEntryDestructorSdsKeyListVal(void *entry) { dictEntry *de = entry; - sdsfree(dictGetKey(de)); - listRelease(dictGetVal(de)); + sdsfree(de->key); + listRelease(de->v.val); zfree(de); } @@ -608,7 +608,7 @@ static void cliFillInCommandHelpEntry(helpEntry *help, char *cmdname, char *subc * If the command has subcommands, this is called recursively for the subcommands. */ static helpEntry * -cliInitCommandHelpEntry(char *cmdname, char *subcommandname, helpEntry *next, valkeyReply *specs, dict *groups) { +cliInitCommandHelpEntry(char *cmdname, char *subcommandname, helpEntry *next, valkeyReply *specs, hashtable *groups) { helpEntry *help = next++; cliFillInCommandHelpEntry(help, cmdname, subcommandname); @@ -688,8 +688,8 @@ int helpEntryCompare(const void *entry1, const void *entry2) { * Called after the command help entries have already been filled in. * Extends the help table with new entries for the command groups. */ -void cliInitGroupHelpEntries(dict *groups) { - dictIterator *iter = dictGetIterator(groups); +void cliInitGroupHelpEntries(hashtable *groups) { + hashtableIterator *iter = dictGetIterator(groups); dictEntry *entry; helpEntry tmp; @@ -701,7 +701,7 @@ void cliInitGroupHelpEntries(dict *groups) { for (entry = dictNext(iter); entry != NULL; entry = dictNext(iter)) { tmp.argc = 1; tmp.argv = zmalloc(sizeof(sds)); - tmp.argv[0] = sdscatprintf(sdsempty(), "@%s", (char *)dictGetKey(entry)); + tmp.argv[0] = sdscatprintf(sdsempty(), "@%s", (char *)entry->key); tmp.full = tmp.argv[0]; tmp.type = CLI_HELP_GROUP; tmp.docs.name = NULL; @@ -717,7 +717,7 @@ void cliInitGroupHelpEntries(dict *groups) { } /* Initializes help entries for all commands in the COMMAND DOCS reply. */ -void cliInitCommandHelpEntries(valkeyReply *commandTable, dict *groups) { +void cliInitCommandHelpEntries(valkeyReply *commandTable, hashtable *groups) { helpEntry *next = helpEntries; for (size_t i = 0; i < commandTable->elements; i += 2) { assert(commandTable->element[i]->type == VALKEY_REPLY_STRING); @@ -784,7 +784,7 @@ static helpEntry *cliLegacyInitCommandHelpEntry(char *cmdname, char *subcommandname, helpEntry *next, struct commandDocs *command, - dict *groups, + hashtable *groups, sds version) { helpEntry *help = next++; cliFillInCommandHelpEntry(help, cmdname, subcommandname); @@ -816,7 +816,7 @@ static helpEntry *cliLegacyInitCommandHelpEntry(char *cmdname, return next; } -int cliLegacyInitCommandHelpEntries(struct commandDocs *commands, dict *groups, sds version) { +int cliLegacyInitCommandHelpEntries(struct commandDocs *commands, hashtable *groups, sds version) { helpEntry *next = helpEntries; for (size_t i = 0; commands[i].name != NULL; i++) { if (!version || versionIsSupported(version, commands[i].since)) { @@ -881,7 +881,7 @@ static sds cliGetServerVersion(void) { return NULL; } -static void cliLegacyInitHelp(dict *groups) { +static void cliLegacyInitHelp(hashtable *groups) { sds serverVersion = cliGetServerVersion(); /* Scan the commandDocs array and fill in the entries */ @@ -900,14 +900,14 @@ static void cliLegacyInitHelp(dict *groups) { */ static void cliInitHelp(void) { /* Dict type for a set of strings, used to collect names of command groups. */ - dictType groupsdt = { + hashtableType groupsdt = { .entryGetKey = dictEntryGetKey, .hashFunction = dictSdsHash, .keyCompare = dictSdsKeyCompare, .entryDestructor = dictEntryDestructorSdsKeyNoVal, }; valkeyReply *commandTable; - dict *groups; + hashtable *groups; if (cliConnect(CC_QUIET) == VALKEY_ERR) { /* Can not connect to the server, but we still want to provide @@ -3621,7 +3621,7 @@ static struct clusterManager { } cluster_manager; /* Used by clusterManagerFixSlotsCoverage */ -dict *clusterManagerUncoveredSlots = NULL; +hashtable *clusterManagerUncoveredSlots = NULL; typedef struct clusterManagerNode { valkeyContext *context; @@ -3679,14 +3679,14 @@ typedef struct clusterManagerLink { int handshaking; } clusterManagerLink; -static dictType clusterManagerDictType = { +static hashtableType clusterManagerDictType = { .entryGetKey = dictEntryGetKey, .hashFunction = dictSdsHash, .keyCompare = dictSdsKeyCompare, .entryDestructor = dictEntryDestructorSdsVal, }; -static dictType clusterManagerLinkDictType = { +static hashtableType clusterManagerLinkDictType = { .entryGetKey = dictEntryGetKey, .hashFunction = dictSdsHash, .keyCompare = dictSdsKeyCompare, @@ -3720,7 +3720,7 @@ static void clusterManagerWaitForClusterJoin(void); static int clusterManagerCheckCluster(int quiet); static void clusterManagerLog(int level, const char *fmt, ...); static int clusterManagerIsConfigConsistent(void); -static dict *clusterManagerGetLinkStatus(void); +static hashtable *clusterManagerGetLinkStatus(void); static void clusterManagerOnError(sds err); static void clusterManagerNodeArrayInit(clusterManagerNodeArray *array, int len); static void clusterManagerNodeArrayReset(clusterManagerNodeArray *array); @@ -4231,7 +4231,7 @@ static int clusterManagerGetAntiAffinityScore(clusterManagerNodeArray *ipnodes, * replication of each other) */ for (i = 0; i < ip_count; i++) { clusterManagerNodeArray *node_array = &(ipnodes[i]); - dict *related = dictCreate(&clusterManagerDictType); + hashtable *related = dictCreate(&clusterManagerDictType); char *ip = NULL; for (j = 0; j < node_array->len; j++) { clusterManagerNode *node = node_array->nodes[j]; @@ -4243,7 +4243,7 @@ static int clusterManagerGetAntiAffinityScore(clusterManagerNodeArray *ipnodes, assert(key != NULL); dictEntry *entry = dictFind(related, key); if (entry) - types = sdsdup((sds)dictGetVal(entry)); + types = sdsdup((sds)entry->v.val); else types = sdsempty(); /* Primary type 'm' is always set as the first character of the @@ -4259,11 +4259,11 @@ static int clusterManagerGetAntiAffinityScore(clusterManagerNodeArray *ipnodes, } /* Now it's trivial to check, for each related group having the * same host, what is their local score. */ - dictIterator *iter = dictGetIterator(related); + hashtableIterator *iter = dictGetIterator(related); dictEntry *entry; while ((entry = dictNext(iter)) != NULL) { - sds types = (sds)dictGetVal(entry); - sds name = (sds)dictGetKey(entry); + sds types = (sds)entry->v.val; + sds name = (sds)entry->key; int typeslen = sdslen(types); if (typeslen < 2) continue; if (types[0] == 'm') @@ -5565,8 +5565,8 @@ static void clusterManagerWaitForClusterJoin(void) { fflush(stdout); sleep(1); if (++counter > check_after) { - dict *status = clusterManagerGetLinkStatus(); - dictIterator *iter = NULL; + hashtable *status = clusterManagerGetLinkStatus(); + hashtableIterator *iter = NULL; if (status != NULL && dictSize(status) > 0) { printf("\n"); clusterManagerLogErr("Warning: %d node(s) may " @@ -5575,10 +5575,10 @@ static void clusterManagerWaitForClusterJoin(void) { iter = dictGetIterator(status); dictEntry *entry; while ((entry = dictNext(iter)) != NULL) { - sds nodeaddr = (sds)dictGetKey(entry); + sds nodeaddr = (sds)entry->key; char *node_ip = NULL; int node_port = 0, node_bus_port = 0; - list *from = (list *)dictGetVal(entry); + list *from = (list *)entry->v.val; if (parseClusterNodeAddress(nodeaddr, &node_ip, &node_port, &node_bus_port) && node_bus_port) { clusterManagerLogErr(" - The port %d of node %s may " "be unreachable from:\n", @@ -6072,9 +6072,9 @@ static list *clusterManagerGetDisconnectedLinks(clusterManagerNode *node) { /* Check for disconnected cluster links. It returns a dict whose keys * are the unreachable node addresses and the values are lists of * node addresses that cannot reach the unreachable node. */ -static dict *clusterManagerGetLinkStatus(void) { +static hashtable *clusterManagerGetLinkStatus(void) { if (cluster_manager.nodes == NULL) return NULL; - dict *status = dictCreate(&clusterManagerLinkDictType); + hashtable *status = dictCreate(&clusterManagerLinkDictType); listIter li; listNode *ln; listRewind(cluster_manager.nodes, &li); @@ -6090,7 +6090,7 @@ static dict *clusterManagerGetLinkStatus(void) { list *from = NULL; dictEntry *entry = dictFind(status, link->node_addr); if (entry) - from = dictGetVal(entry); + from = entry->v.val; else { from = listCreate(); dictAdd(status, sdsdup(link->node_addr), from); @@ -6289,11 +6289,11 @@ static int clusterManagerFixSlotsCoverage(char *all_slots) { none = listCreate(); single = listCreate(); multi = listCreate(); - dictIterator *iter = dictGetIterator(clusterManagerUncoveredSlots); + hashtableIterator *iter = dictGetIterator(clusterManagerUncoveredSlots); dictEntry *entry; while ((entry = dictNext(iter)) != NULL) { - sds slot = (sds)dictGetKey(entry); - list *nodes = (list *)dictGetVal(entry); + sds slot = (sds)entry->key; + list *nodes = (list *)entry->v.val; switch (listLength(nodes)) { case 0: listAddNodeTail(none, slot); break; case 1: listAddNodeTail(single, slot); break; @@ -6344,7 +6344,7 @@ static int clusterManagerFixSlotsCoverage(char *all_slots) { int s = atoi(slot); dictEntry *entry = dictFind(clusterManagerUncoveredSlots, slot); assert(entry != NULL); - list *nodes = (list *)dictGetVal(entry); + list *nodes = (list *)entry->v.val; listNode *fn = listFirst(nodes); assert(fn != NULL); clusterManagerNode *n = fn->value; @@ -6375,7 +6375,7 @@ static int clusterManagerFixSlotsCoverage(char *all_slots) { sds slot = ln->value; dictEntry *entry = dictFind(clusterManagerUncoveredSlots, slot); assert(entry != NULL); - list *nodes = (list *)dictGetVal(entry); + list *nodes = (list *)entry->v.val; int s = atoi(slot); clusterManagerNode *target = clusterManagerGetNodeWithMostKeysInSlot(nodes, s, NULL); if (target == NULL) { @@ -6809,7 +6809,7 @@ static int clusterManagerCheckCluster(int quiet) { listIter li; listRewind(cluster_manager.nodes, &li); int i; - dict *open_slots = NULL; + hashtable *open_slots = NULL; while ((ln = listNext(&li)) != NULL) { clusterManagerNode *n = ln->value; if (n->migrating != NULL) { @@ -6847,12 +6847,12 @@ static int clusterManagerCheckCluster(int quiet) { } if (open_slots != NULL) { result = 0; - dictIterator *iter = dictGetIterator(open_slots); + hashtableIterator *iter = dictGetIterator(open_slots); dictEntry *entry; sds errstr = sdsnew("[WARNING] The following slots are open: "); i = 0; while ((entry = dictNext(iter)) != NULL) { - sds slot = (sds)dictGetKey(entry); + sds slot = (sds)entry->key; char *fmt = (i++ > 0 ? ",%S" : "%S"); errstr = sdscatfmt(errstr, fmt, slot); } @@ -6863,7 +6863,7 @@ static int clusterManagerCheckCluster(int quiet) { dictReleaseIterator(iter); iter = dictGetIterator(open_slots); while ((entry = dictNext(iter)) != NULL) { - sds slot = (sds)dictGetKey(entry); + sds slot = (sds)entry->key; result = clusterManagerFixOpenSlot(atoi(slot)); if (!result) break; } @@ -9213,7 +9213,7 @@ typeinfo type_zset = {"zset", "ZCARD", "members"}; typeinfo type_stream = {"stream", "XLEN", "entries"}; typeinfo type_other = {"other", NULL, "?"}; -static typeinfo *typeinfo_add(dict *types, char *name, typeinfo *type_template) { +static typeinfo *typeinfo_add(hashtable *types, char *name, typeinfo *type_template) { typeinfo *info = zmalloc(sizeof(typeinfo)); *info = *type_template; info->name = sdsnew(name); @@ -9230,18 +9230,18 @@ void type_free(void *val) { static void dictEntryDestructorTypeinfoVal(void *entry) { dictEntry *de = entry; - type_free(dictGetVal(de)); + type_free(de->v.val); zfree(de); } -static dictType typeinfoDictType = { +static hashtableType typeinfoDictType = { .entryGetKey = dictEntryGetKey, .hashFunction = dictSdsHash, .keyCompare = dictSdsKeyCompare, .entryDestructor = dictEntryDestructorTypeinfoVal, }; -static void getKeyTypes(dict *types_dict, valkeyReply *keys, typeinfo **types) { +static void getKeyTypes(hashtable *types_dict, valkeyReply *keys, typeinfo **types) { valkeyReply *reply; unsigned int i; @@ -9272,7 +9272,7 @@ static void getKeyTypes(dict *types_dict, valkeyReply *keys, typeinfo **types) { sdsfree(typereply); typeinfo *type = NULL; if (de) - type = dictGetVal(de); + type = de->v.val; else if (strcmp(reply->str, "none")) /* create new types for modules, (but not for deleted keys) */ type = typeinfo_add(types_dict, reply->str, &type_other); types[i] = type; @@ -9359,12 +9359,12 @@ static void findBigKeys(int memkeys, unsigned memkeys_samples) { unsigned long long sampled = 0, total_keys, totlen = 0, *sizes = NULL, it = 0, scan_loops = 0; valkeyReply *reply, *keys; unsigned int arrsize = 0, i; - dictIterator *di; + hashtableIterator *di; dictEntry *de; typeinfo **types = NULL; double pct; - dict *types_dict = dictCreate(&typeinfoDictType); + hashtable *types_dict = dictCreate(&typeinfoDictType); typeinfo_add(types_dict, "string", &type_string); typeinfo_add(types_dict, "list", &type_list); typeinfo_add(types_dict, "set", &type_set); @@ -9464,7 +9464,7 @@ static void findBigKeys(int memkeys, unsigned memkeys_samples) { /* Output the biggest keys we found, for types we did find */ di = dictGetIterator(types_dict); while ((de = dictNext(di))) { - typeinfo *type = dictGetVal(de); + typeinfo *type = de->v.val; if (type->biggest_key) { printf("Biggest %6s found '%s' has %llu %s\n", type->name, type->biggest_key, type->biggest, !memkeys ? type->sizeunit : "bytes"); @@ -9476,7 +9476,7 @@ static void findBigKeys(int memkeys, unsigned memkeys_samples) { di = dictGetIterator(types_dict); while ((de = dictNext(di))) { - typeinfo *type = dictGetVal(de); + typeinfo *type = de->v.val; printf("%llu %ss with %llu %s (%05.2f%% of keys, avg size %.2f)\n", type->count, type->name, type->totalsize, !memkeys ? type->sizeunit : "bytes", sampled ? 100 * (double)type->count / sampled : 0, type->count ? (double)type->totalsize / type->count : 0);