Optimize dictTypeResizeAllowed to avoid mistaken OOM judgement. (#12950)
When doing dict resizing, dictTypeResizeAllowed is used to judge whether the new allocated memory for rehashing would cause OOM. However when shrinking, we alloc `_dictNextExp(d->ht_used[0])` bytes of memory, while in `dictTypeResizeAllowed` we still use `_dictNextExp(d->ht_used[0]+1)` as the new allocated memory size. This will overestimate the memory used by shrinking at special conditions, causing a false OOM judgement.
This commit is contained in:
parent
1c7eb0ad37
commit
f81c3fd89e
12
src/dict.c
12
src/dict.c
@ -1421,12 +1421,12 @@ unsigned long dictScanDefrag(dict *d,
|
|||||||
/* ------------------------- private functions ------------------------------ */
|
/* ------------------------- private functions ------------------------------ */
|
||||||
|
|
||||||
/* Because we may need to allocate huge memory chunk at once when dict
|
/* Because we may need to allocate huge memory chunk at once when dict
|
||||||
* expands, we will check this allocation is allowed or not if the dict
|
* resizes, we will check this allocation is allowed or not if the dict
|
||||||
* type has expandAllowed member function. */
|
* type has resizeAllowed member function. */
|
||||||
static int dictTypeResizeAllowed(dict *d) {
|
static int dictTypeResizeAllowed(dict *d, size_t size) {
|
||||||
if (d->type->resizeAllowed == NULL) return 1;
|
if (d->type->resizeAllowed == NULL) return 1;
|
||||||
return d->type->resizeAllowed(
|
return d->type->resizeAllowed(
|
||||||
DICTHT_SIZE(_dictNextExp(d->ht_used[0] + 1)) * sizeof(dictEntry*),
|
DICTHT_SIZE(_dictNextExp(size)) * sizeof(dictEntry*),
|
||||||
(double)d->ht_used[0] / DICTHT_SIZE(d->ht_size_exp[0]));
|
(double)d->ht_used[0] / DICTHT_SIZE(d->ht_size_exp[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1454,7 +1454,7 @@ static void _dictExpandIfNeeded(dict *d)
|
|||||||
(dict_can_resize != DICT_RESIZE_FORBID &&
|
(dict_can_resize != DICT_RESIZE_FORBID &&
|
||||||
d->ht_used[0] >= dict_force_resize_ratio * DICTHT_SIZE(d->ht_size_exp[0])))
|
d->ht_used[0] >= dict_force_resize_ratio * DICTHT_SIZE(d->ht_size_exp[0])))
|
||||||
{
|
{
|
||||||
if (!dictTypeResizeAllowed(d))
|
if (!dictTypeResizeAllowed(d, d->ht_used[0] + 1))
|
||||||
return;
|
return;
|
||||||
dictExpand(d, d->ht_used[0] + 1);
|
dictExpand(d, d->ht_used[0] + 1);
|
||||||
}
|
}
|
||||||
@ -1479,7 +1479,7 @@ static void _dictShrinkIfNeeded(dict *d)
|
|||||||
(dict_can_resize != DICT_RESIZE_FORBID &&
|
(dict_can_resize != DICT_RESIZE_FORBID &&
|
||||||
d->ht_used[0] * 100 * dict_force_resize_ratio <= HASHTABLE_MIN_FILL * DICTHT_SIZE(d->ht_size_exp[0])))
|
d->ht_used[0] * 100 * dict_force_resize_ratio <= HASHTABLE_MIN_FILL * DICTHT_SIZE(d->ht_size_exp[0])))
|
||||||
{
|
{
|
||||||
if (!dictTypeResizeAllowed(d))
|
if (!dictTypeResizeAllowed(d, d->ht_used[0]))
|
||||||
return;
|
return;
|
||||||
dictShrink(d, d->ht_used[0]);
|
dictShrink(d, d->ht_used[0]);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user