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) { ...@@ -239,6 +239,14 @@ void dbAdd(redisDb *db, robj *key, robj *val) {
notifyKeyspaceEvent(NOTIFY_NEW,"new",key,db->id); 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.*/ /* Return slot-specific dictionary for key based on key's hash slot in CME, or 0 in CMD.*/
int getKeySlot(sds key) { int getKeySlot(sds key) {
/* This is performance optimization, that uses pre-set slot id from the current command, /* This is performance optimization, that uses pre-set slot id from the current command,
...@@ -247,7 +255,7 @@ int getKeySlot(sds key) { ...@@ -247,7 +255,7 @@ int getKeySlot(sds key) {
if (server.current_client && server.current_client->slot >= 0) { if (server.current_client && server.current_client->slot >= 0) {
return server.current_client->slot; 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 /* 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 ...@@ -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 * dictionary (but the expires one) we need to lookup the key
* again in the key dictionary to obtain the value object. */ * again in the key dictionary to obtain the value object. */
if (server.maxmemory_policy != MAXMEMORY_VOLATILE_TTL) { 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); o = dictGetVal(de);
} }
...@@ -570,11 +570,6 @@ int performEvictions(void) { ...@@ -570,11 +570,6 @@ int performEvictions(void) {
/* Try to smoke-out bugs (server.also_propagate should be empty here) */ /* Try to smoke-out bugs (server.also_propagate should be empty here) */
serverAssert(server.also_propagate.numops == 0); serverAssert(server.also_propagate.numops == 0);
/* Evictions are performed on random keys that have nothing to do with the current command slot. */ /* 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) { while (mem_freed < (long long)mem_tofree) {
int j, k, i; int j, k, i;
...@@ -619,7 +614,7 @@ int performEvictions(void) { ...@@ -619,7 +614,7 @@ int performEvictions(void) {
bestdbid = pool[k].dbid; bestdbid = pool[k].dbid;
if (server.maxmemory_policy & MAXMEMORY_FLAG_ALLKEYS) { 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); pool[k].key);
} else { } else {
de = dictFind(server.db[bestdbid].expires, de = dictFind(server.db[bestdbid].expires,
...@@ -728,7 +723,6 @@ int performEvictions(void) { ...@@ -728,7 +723,6 @@ int performEvictions(void) {
goto cant_free; /* nothing to free... */ 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 */ /* at this point, the memory is OK, or we have reached the time limit */
result = (isEvictionProcRunning) ? EVICT_RUNNING : EVICT_OK; result = (isEvictionProcRunning) ? EVICT_RUNNING : EVICT_OK;
......
...@@ -394,7 +394,7 @@ void touchWatchedKey(redisDb *db, robj *key) { ...@@ -394,7 +394,7 @@ void touchWatchedKey(redisDb *db, robj *key) {
/* The key was already expired when WATCH was called. */ /* The key was already expired when WATCH was called. */
if (db == wk->db && if (db == wk->db &&
equalStringObjects(key, wk->key) && 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 /* Already expired key is deleted, so logically no change. Clear
* the flag. Deleted keys are not flagged as expired. */ * the flag. Deleted keys are not flagged as expired. */
...@@ -432,9 +432,9 @@ void touchAllWatchedKeysInDb(redisDb *emptied, redisDb *replaced_with) { ...@@ -432,9 +432,9 @@ void touchAllWatchedKeysInDb(redisDb *emptied, redisDb *replaced_with) {
dictIterator *di = dictGetSafeIterator(emptied->watched_keys); dictIterator *di = dictGetSafeIterator(emptied->watched_keys);
while((de = dictNext(di)) != NULL) { while((de = dictNext(di)) != NULL) {
robj *key = dictGetKey(de); 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 || 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); list *clients = dictGetVal(de);
if (!clients) continue; if (!clients) continue;
...@@ -442,7 +442,7 @@ void touchAllWatchedKeysInDb(redisDb *emptied, redisDb *replaced_with) { ...@@ -442,7 +442,7 @@ void touchAllWatchedKeysInDb(redisDb *emptied, redisDb *replaced_with) {
while((ln = listNext(&li))) { while((ln = listNext(&li))) {
watchedKey *wk = redis_member2struct(watchedKey, node, ln); watchedKey *wk = redis_member2struct(watchedKey, node, ln);
if (wk->expired) { 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 /* Expired key now deleted. No logical change. Clear the
* flag. Deleted keys are not flagged as expired. */ * flag. Deleted keys are not flagged as expired. */
wk->expired = 0; wk->expired = 0;
......
...@@ -3129,6 +3129,7 @@ void dismissMemoryInChild(void); ...@@ -3129,6 +3129,7 @@ void dismissMemoryInChild(void);
int restartServer(int flags, mstime_t delay); int restartServer(int flags, mstime_t delay);
unsigned long long int dbSize(redisDb *db); unsigned long long int dbSize(redisDb *db);
int getKeySlot(sds key); int getKeySlot(sds key);
int calculateKeySlot(sds key);
unsigned long dbSlots(redisDb *db); unsigned long dbSlots(redisDb *db);
void expandDb(const redisDb *db, uint64_t db_size); void expandDb(const redisDb *db, uint64_t db_size);
unsigned long long cumulativeKeyCountRead(redisDb *db, int idx); 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