Commit be34a1a4 authored by Vitaly Arbuzov's avatar Vitaly Arbuzov
Browse files

Use direct CRC hash calculation instead of nulling out the client

parent cd109e8e
......@@ -239,6 +239,14 @@ void dbAdd(redisDb *db, robj *key, robj *val) {
notifyKeyspaceEvent(NOTIFY_NEW,"new",key,db->id);
}
/* Returns key's hash slot when cluster mode is enabled, or 0 when disabled.
* The only difference between this function and getKeySlot, is that it's not using cached key slot from the current_client
* and always calculates CRC hash.
* This is useful when slot needs to be calculated for a key that user didn't request for, such as in case of eviction. */
int calculateKeySlot(sds key) {
return server.cluster_enabled ? keyHashSlot(key, (int) sdslen(key)) : 0;
}
/* Return slot-specific dictionary for key based on key's hash slot in CME, or 0 in CMD.*/
int getKeySlot(sds key) {
/* This is performance optimization, that uses pre-set slot id from the current command,
......@@ -247,7 +255,7 @@ int getKeySlot(sds key) {
if (server.current_client && server.current_client->slot >= 0) {
return server.current_client->slot;
}
return server.cluster_enabled ? keyHashSlot(key, (int) sdslen(key)) : 0;
return calculateKeySlot(key);
}
/* This is a special version of dbAdd() that is used only when loading
......
......@@ -161,7 +161,7 @@ void evictionPoolPopulate(int dbid, dict *sampledict, redisDb *db, struct evicti
* dictionary (but the expires one) we need to lookup the key
* again in the key dictionary to obtain the value object. */
if (server.maxmemory_policy != MAXMEMORY_VOLATILE_TTL) {
if (!(server.maxmemory_policy & MAXMEMORY_FLAG_ALLKEYS)) de = dictFind(db->dict[getKeySlot(key)], key);
if (!(server.maxmemory_policy & MAXMEMORY_FLAG_ALLKEYS)) de = dictFind(db->dict[calculateKeySlot(key)], key);
o = dictGetVal(de);
}
......@@ -570,11 +570,6 @@ int performEvictions(void) {
/* Try to smoke-out bugs (server.also_propagate should be empty here) */
serverAssert(server.also_propagate.numops == 0);
/* Evictions are performed on random keys that have nothing to do with the current command slot. */
int client_slot = -1;
if (server.current_client) {
client_slot = server.current_client->slot;
server.current_client->slot = -1;
}
while (mem_freed < (long long)mem_tofree) {
int j, k, i;
......@@ -619,7 +614,7 @@ int performEvictions(void) {
bestdbid = pool[k].dbid;
if (server.maxmemory_policy & MAXMEMORY_FLAG_ALLKEYS) {
de = dictFind(server.db[bestdbid].dict[getKeySlot(pool[k].key)],
de = dictFind(server.db[bestdbid].dict[calculateKeySlot(pool[k].key)],
pool[k].key);
} else {
de = dictFind(server.db[bestdbid].expires,
......@@ -728,7 +723,6 @@ int performEvictions(void) {
goto cant_free; /* nothing to free... */
}
}
if (client_slot != -1) server.current_client->slot = client_slot; /* Restore client slot for further command processing. */
/* at this point, the memory is OK, or we have reached the time limit */
result = (isEvictionProcRunning) ? EVICT_RUNNING : EVICT_OK;
......
......@@ -394,7 +394,7 @@ void touchWatchedKey(redisDb *db, robj *key) {
/* The key was already expired when WATCH was called. */
if (db == wk->db &&
equalStringObjects(key, wk->key) &&
dictFind(db->dict[getKeySlot(key->ptr)], key->ptr) == NULL)
dictFind(db->dict[calculateKeySlot(key->ptr)], key->ptr) == NULL)
{
/* Already expired key is deleted, so logically no change. Clear
* the flag. Deleted keys are not flagged as expired. */
......@@ -432,9 +432,9 @@ void touchAllWatchedKeysInDb(redisDb *emptied, redisDb *replaced_with) {
dictIterator *di = dictGetSafeIterator(emptied->watched_keys);
while((de = dictNext(di)) != NULL) {
robj *key = dictGetKey(de);
int exists_in_emptied = dictFind(emptied->dict[getKeySlot(key->ptr)], key->ptr) != NULL;
int exists_in_emptied = dictFind(emptied->dict[calculateKeySlot(key->ptr)], key->ptr) != NULL;
if (exists_in_emptied ||
(replaced_with && dictFind(replaced_with->dict[getKeySlot(key->ptr)], key->ptr)))
(replaced_with && dictFind(replaced_with->dict[calculateKeySlot(key->ptr)], key->ptr)))
{
list *clients = dictGetVal(de);
if (!clients) continue;
......@@ -442,7 +442,7 @@ void touchAllWatchedKeysInDb(redisDb *emptied, redisDb *replaced_with) {
while((ln = listNext(&li))) {
watchedKey *wk = redis_member2struct(watchedKey, node, ln);
if (wk->expired) {
if (!replaced_with || !dictFind(replaced_with->dict[getKeySlot(key->ptr)], key->ptr)) {
if (!replaced_with || !dictFind(replaced_with->dict[calculateKeySlot(key->ptr)], key->ptr)) {
/* Expired key now deleted. No logical change. Clear the
* flag. Deleted keys are not flagged as expired. */
wk->expired = 0;
......
......@@ -3129,6 +3129,7 @@ void dismissMemoryInChild(void);
int restartServer(int flags, mstime_t delay);
unsigned long long int dbSize(redisDb *db);
int getKeySlot(sds key);
int calculateKeySlot(sds key);
unsigned long dbSlots(redisDb *db);
void expandDb(const redisDb *db, uint64_t db_size);
unsigned long long cumulativeKeyCountRead(redisDb *db, int idx);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment