mirror of
https://github.com/redis/redis.git
synced 2026-05-28 04:02:46 -04:00
Pause dict auto-resize during multi-field deletion (#14783)
The idea comes directly from ValKey: https://github.com/valkey-io/valkey/pull/3144 Deleting many fields from a hash/zset/set stored as a dict can trigger repeated shrink/rehash work during the loop. --------- Co-authored-by: Binbin <binloveplay1314@qq.com> Co-authored-by: debing.sun <debing.sun@redis.com>
This commit is contained in:
parent
a9838e6a4b
commit
98328ae2ec
4 changed files with 29 additions and 1 deletions
|
|
@ -1,6 +1,9 @@
|
|||
/*
|
||||
* Copyright (c) 2009-Present, Redis Ltd.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Copyright (c) 2024-present, Valkey contributors.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Licensed under your choice of (a) the Redis Source Available License 2.0
|
||||
* (RSALv2); or (b) the Server Side Public License v1 (SSPLv1); or (c) the
|
||||
|
|
@ -2926,6 +2929,8 @@ void hdelCommand(client *c) {
|
|||
* field with expiration and removes it from global HFE DS. */
|
||||
int isHFE = hashTypeIsFieldsWithExpire(o);
|
||||
|
||||
if (o->encoding == OBJ_ENCODING_HT)
|
||||
dictPauseAutoResize((dict*)o->ptr);
|
||||
for (j = 2; j < c->argc; j++) {
|
||||
if (hashTypeDelete(o,c->argv[j]->ptr)) {
|
||||
deleted++;
|
||||
|
|
@ -2939,6 +2944,10 @@ void hdelCommand(client *c) {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (!keyremoved && o->encoding == OBJ_ENCODING_HT) {
|
||||
dictResumeAutoResize((dict*)o->ptr);
|
||||
dictShrinkIfNeeded((dict*)o->ptr);
|
||||
}
|
||||
if (server.memory_tracking_enabled && !keyremoved)
|
||||
updateSlotAllocSize(c->db, getKeySlot(c->argv[1]->ptr), o, oldsize, kvobjAllocSize(o));
|
||||
if (deleted) {
|
||||
|
|
|
|||
|
|
@ -657,6 +657,8 @@ void sremCommand(client *c) {
|
|||
if (server.memory_tracking_enabled)
|
||||
oldsize = kvobjAllocSize(set);
|
||||
|
||||
if (set->encoding == OBJ_ENCODING_HT)
|
||||
dictPauseAutoResize((dict*)set->ptr);
|
||||
for (j = 2; j < c->argc; j++) {
|
||||
if (setTypeRemove(set,c->argv[j]->ptr)) {
|
||||
deleted++;
|
||||
|
|
@ -669,6 +671,10 @@ void sremCommand(client *c) {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (!keyremoved && set->encoding == OBJ_ENCODING_HT) {
|
||||
dictResumeAutoResize((dict*)set->ptr);
|
||||
dictShrinkIfNeeded((dict*)set->ptr);
|
||||
}
|
||||
if (server.memory_tracking_enabled && !keyremoved)
|
||||
updateSlotAllocSize(c->db, getKeySlot(c->argv[1]->ptr), set, oldsize, kvobjAllocSize(set));
|
||||
if (deleted) {
|
||||
|
|
|
|||
|
|
@ -2118,6 +2118,8 @@ void zremCommand(client *c) {
|
|||
int64_t oldlen = (int64_t) zsetLength(zobj);
|
||||
if (server.memory_tracking_enabled)
|
||||
oldsize = kvobjAllocSize(zobj);
|
||||
if (zobj->encoding == OBJ_ENCODING_SKIPLIST)
|
||||
dictPauseAutoResize(((zset*)zobj->ptr)->dict);
|
||||
for (j = 2; j < c->argc; j++) {
|
||||
if (zsetDel(zobj, c->argv[j]->ptr)) deleted++;
|
||||
if (zsetLength(zobj) == 0) {
|
||||
|
|
@ -2129,6 +2131,10 @@ void zremCommand(client *c) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (!keyremoved && zobj->encoding == OBJ_ENCODING_SKIPLIST) {
|
||||
dictResumeAutoResize(((zset*)zobj->ptr)->dict);
|
||||
dictShrinkIfNeeded(((zset*)zobj->ptr)->dict);
|
||||
}
|
||||
|
||||
if (server.memory_tracking_enabled && !keyremoved)
|
||||
updateSlotAllocSize(c->db, getKeySlot(key->ptr), zobj, oldsize, kvobjAllocSize(zobj));
|
||||
|
|
|
|||
|
|
@ -1026,7 +1026,14 @@ foreach type {single multiple single_multiple} {
|
|||
break
|
||||
}
|
||||
}
|
||||
r srem $myset {*}$members
|
||||
r deferred 1
|
||||
foreach m $members {
|
||||
r srem $myset $m
|
||||
}
|
||||
foreach m $members {
|
||||
r read
|
||||
}
|
||||
r deferred 0
|
||||
}
|
||||
|
||||
proc verify_rehashing_completed_key {myset table_size keys} {
|
||||
|
|
|
|||
Loading…
Reference in a new issue