Fix variable reuse in table expiration

While expiring a table, DoExpire checks at the end to see if NextEntry
returned nothing to determine if it should sleep for the short
table_expire_delay or the long table_expire_interval.

However, the check to see if the expire_func deleted the entry
re-assigns the same variable.  This means that:

  If you have a large table that is behind on expiring values
& The table defines an expire_func
& That expire_func deletes the item
& It so happens that the last item checked in the batch of
table_incremental_step size had expired

then DoExpire will reset the cookie and sleep for table_expire_interval
This commit is contained in:
Justin Azoff 2019-01-11 23:32:28 -05:00
parent cc2981ab3b
commit 665d8b01d2

View file

@ -2348,6 +2348,7 @@ void TableVal::DoExpire(double t)
HashKey* k = 0; HashKey* k = 0;
TableEntryVal* v = 0; TableEntryVal* v = 0;
TableEntryVal* v_saved = 0;
for ( int i = 0; i < table_incremental_step && for ( int i = 0; i < table_incremental_step &&
(v = tbl->NextEntry(k, expire_cookie)); ++i ) (v = tbl->NextEntry(k, expire_cookie)); ++i )
@ -2371,10 +2372,12 @@ void TableVal::DoExpire(double t)
// It's possible that the user-provided // It's possible that the user-provided
// function modified or deleted the table // function modified or deleted the table
// value, so look it up again. // value, so look it up again.
v_saved = v;
v = tbl->Lookup(k); v = tbl->Lookup(k);
if ( ! v ) if ( ! v )
{ // user-provided function deleted it { // user-provided function deleted it
v = v_saved;
delete k; delete k;
continue; continue;
} }