Commit 90c39c5a authored by Sergei Golubchik's avatar Sergei Golubchik

hopefully the last case of walk-and-delete HASH antipattern

here global_index_stats is expected to be big, so we don't
restart the search, but use a two-pass approach
parent 2e6a9886
......@@ -7233,11 +7233,13 @@ static
int del_global_index_stats_for_table(THD *thd, uchar* cache_key, size_t cache_key_length)
{
int res = 0;
uint to_delete_counter= 0;
INDEX_STATS *index_stats_to_delete[MAX_INDEXES];
DBUG_ENTER("del_global_index_stats_for_table");
mysql_mutex_lock(&LOCK_global_index_stats);
for (uint i= 0; i < global_index_stats.records;)
for (uint i= 0; i < global_index_stats.records; i++)
{
INDEX_STATS *index_stats =
(INDEX_STATS*) my_hash_element(&global_index_stats, i);
......@@ -7247,19 +7249,13 @@ int del_global_index_stats_for_table(THD *thd, uchar* cache_key, size_t cache_ke
index_stats->index_name_length >= cache_key_length &&
!memcmp(index_stats->index, cache_key, cache_key_length))
{
res= my_hash_delete(&global_index_stats, (uchar*)index_stats);
/*
In our HASH implementation on deletion one elements
is moved into a place where a deleted element was,
and the last element is moved into the empty space.
Thus we need to re-examine the current element, but
we don't have to restart the search from the beginning.
*/
index_stats_to_delete[to_delete_counter++]= index_stats;
}
else
i++;
}
for (uint i= 0; i < to_delete_counter; i++)
res= my_hash_delete(&global_index_stats, (uchar*)index_stats_to_delete[i]);
mysql_mutex_unlock(&LOCK_global_index_stats);
DBUG_RETURN(res);
}
......
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