@@ -1223,23 +1223,30 @@ template <typename VALUE_SIZE_FUNC>
1223
1223
inline TableStatistics ConcurrentHashTable<CONFIG, F>::
1224
1224
statistics_calculate (Thread* thread, VALUE_SIZE_FUNC& vs_f)
1225
1225
{
1226
+ constexpr size_t batch_size = 128 ;
1226
1227
NumberSeq summary;
1227
1228
size_t literal_bytes = 0 ;
1228
1229
InternalTable* table = get_table ();
1229
- for (size_t bucket_it = 0 ; bucket_it < table->_size ; bucket_it++) {
1230
+ size_t num_batches = table->_size / batch_size;
1231
+ for (size_t batch_start = 0 ; batch_start < _table->_size ; batch_start += batch_size) {
1232
+ // We batch the use of ScopedCS here as it has been found to be quite expensive to
1233
+ // invoke it for every single bucket.
1234
+ size_t batch_end = MIN2 (batch_start + batch_size, _table->_size );
1230
1235
ScopedCS cs (thread, this );
1231
- size_t count = 0 ;
1232
- Bucket* bucket = table->get_bucket (bucket_it);
1233
- if (bucket->have_redirect () || bucket->is_locked ()) {
1234
- continue ;
1235
- }
1236
- Node* current_node = bucket->first ();
1237
- while (current_node != nullptr ) {
1238
- ++count;
1239
- literal_bytes += vs_f (current_node->value ());
1240
- current_node = current_node->next ();
1236
+ for (size_t bucket_it = batch_start; bucket_it < batch_end; bucket_it++) {
1237
+ size_t count = 0 ;
1238
+ Bucket* bucket = table->get_bucket (bucket_it);
1239
+ if (bucket->have_redirect () || bucket->is_locked ()) {
1240
+ continue ;
1241
+ }
1242
+ Node* current_node = bucket->first ();
1243
+ while (current_node != nullptr ) {
1244
+ ++count;
1245
+ literal_bytes += vs_f (current_node->value ());
1246
+ current_node = current_node->next ();
1247
+ }
1248
+ summary.add ((double )count);
1241
1249
}
1242
- summary.add ((double )count);
1243
1250
}
1244
1251
1245
1252
if (_stats_rate == nullptr ) {
0 commit comments