diff --git a/db/perf_context_test.cc b/db/perf_context_test.cc index 6e4a02749d56ce89edbfd92cbf7a5d41b431c569..4500b810a89bfce901738b75956a79b1f79fa286 100644 --- a/db/perf_context_test.cc +++ b/db/perf_context_test.cc @@ -688,6 +688,89 @@ TEST_F(PerfContextTest, MergeOperatorTime) { delete db; } +TEST_F(PerfContextTest, CopyAndMove) { + // Assignment operator + { + get_perf_context()->Reset(); + get_perf_context()->EnablePerLevelPerfContext(); + PERF_COUNTER_BY_LEVEL_ADD(bloom_filter_useful, 1, 5); + ASSERT_EQ( + 1, + (*(get_perf_context()->level_to_perf_context))[5].bloom_filter_useful); + PerfContext perf_context_assign; + perf_context_assign = *get_perf_context(); + ASSERT_EQ( + 1, + (*(perf_context_assign.level_to_perf_context))[5].bloom_filter_useful); + get_perf_context()->ClearPerLevelPerfContext(); + get_perf_context()->Reset(); + ASSERT_EQ( + 1, + (*(perf_context_assign.level_to_perf_context))[5].bloom_filter_useful); + perf_context_assign.ClearPerLevelPerfContext(); + perf_context_assign.Reset(); + } + // Copy constructor + { + get_perf_context()->Reset(); + get_perf_context()->EnablePerLevelPerfContext(); + PERF_COUNTER_BY_LEVEL_ADD(bloom_filter_useful, 1, 5); + ASSERT_EQ( + 1, + (*(get_perf_context()->level_to_perf_context))[5].bloom_filter_useful); + PerfContext perf_context_copy(*get_perf_context()); + ASSERT_EQ( + 1, (*(perf_context_copy.level_to_perf_context))[5].bloom_filter_useful); + get_perf_context()->ClearPerLevelPerfContext(); + get_perf_context()->Reset(); + ASSERT_EQ( + 1, (*(perf_context_copy.level_to_perf_context))[5].bloom_filter_useful); + perf_context_copy.ClearPerLevelPerfContext(); + perf_context_copy.Reset(); + } + // Move constructor + { + get_perf_context()->Reset(); + get_perf_context()->EnablePerLevelPerfContext(); + PERF_COUNTER_BY_LEVEL_ADD(bloom_filter_useful, 1, 5); + ASSERT_EQ( + 1, + (*(get_perf_context()->level_to_perf_context))[5].bloom_filter_useful); + PerfContext perf_context_move = std::move(*get_perf_context()); + ASSERT_EQ( + 1, (*(perf_context_move.level_to_perf_context))[5].bloom_filter_useful); + get_perf_context()->ClearPerLevelPerfContext(); + get_perf_context()->Reset(); + ASSERT_EQ( + 1, (*(perf_context_move.level_to_perf_context))[5].bloom_filter_useful); + perf_context_move.ClearPerLevelPerfContext(); + perf_context_move.Reset(); + } +} + +TEST_F(PerfContextTest, PerfContextDisableEnable) { + get_perf_context()->Reset(); + get_perf_context()->EnablePerLevelPerfContext(); + PERF_COUNTER_BY_LEVEL_ADD(bloom_filter_full_positive, 1, 0); + get_perf_context()->DisablePerLevelPerfContext(); + PERF_COUNTER_BY_LEVEL_ADD(bloom_filter_useful, 1, 5); + get_perf_context()->EnablePerLevelPerfContext(); + PERF_COUNTER_BY_LEVEL_ADD(block_cache_hit_count, 1, 0); + get_perf_context()->DisablePerLevelPerfContext(); + PerfContext perf_context_copy(*get_perf_context()); + ASSERT_EQ(1, (*(perf_context_copy.level_to_perf_context))[0] + .bloom_filter_full_positive); + // this was set when per level perf context is disabled, should not be copied + ASSERT_NE( + 1, (*(perf_context_copy.level_to_perf_context))[5].bloom_filter_useful); + ASSERT_EQ( + 1, (*(perf_context_copy.level_to_perf_context))[0].block_cache_hit_count); + perf_context_copy.ClearPerLevelPerfContext(); + perf_context_copy.Reset(); + get_perf_context()->ClearPerLevelPerfContext(); + get_perf_context()->Reset(); +} + TEST_F(PerfContextTest, PerfContextByLevelGetSet) { get_perf_context()->Reset(); get_perf_context()->EnablePerLevelPerfContext(); diff --git a/include/rocksdb/perf_context.h b/include/rocksdb/perf_context.h index a47b4d5ed912086b7d14f6a9ed9363a7176657a4..4e299b3735a1a8ebb2505890635504fb4aa22de2 100644 --- a/include/rocksdb/perf_context.h +++ b/include/rocksdb/perf_context.h @@ -45,6 +45,12 @@ struct PerfContext { ~PerfContext(); + PerfContext() {} + + PerfContext(const PerfContext&); + PerfContext& operator=(const PerfContext&); + PerfContext(PerfContext&&) noexcept; + void Reset(); // reset all performance counters to zero std::string ToString(bool exclude_zero_counters = false) const; diff --git a/monitoring/perf_context.cc b/monitoring/perf_context.cc index 1046106e2b01249df8654a11a02202fe2b679fdf..90199c3ca818fa1c3d68b7750596f07923fb83a9 100644 --- a/monitoring/perf_context.cc +++ b/monitoring/perf_context.cc @@ -37,6 +37,285 @@ PerfContext::~PerfContext() { #endif } +PerfContext::PerfContext(const PerfContext& other) { +#ifndef NPERF_CONTEXT + user_key_comparison_count = other.user_key_comparison_count; + block_cache_hit_count = other.block_cache_hit_count; + block_read_count = other.block_read_count; + block_read_byte = other.block_read_byte; + block_read_time = other.block_read_time; + block_cache_index_hit_count = other.block_cache_index_hit_count; + index_block_read_count = other.index_block_read_count; + block_cache_filter_hit_count = other.block_cache_filter_hit_count; + filter_block_read_count = other.filter_block_read_count; + compression_dict_block_read_count = other.compression_dict_block_read_count; + block_checksum_time = other.block_checksum_time; + block_decompress_time = other.block_decompress_time; + get_read_bytes = other.get_read_bytes; + multiget_read_bytes = other.multiget_read_bytes; + iter_read_bytes = other.iter_read_bytes; + internal_key_skipped_count = other.internal_key_skipped_count; + internal_delete_skipped_count = other.internal_delete_skipped_count; + internal_recent_skipped_count = other.internal_recent_skipped_count; + internal_merge_count = other.internal_merge_count; + write_wal_time = other.write_wal_time; + get_snapshot_time = other.get_snapshot_time; + get_from_memtable_time = other.get_from_memtable_time; + get_from_memtable_count = other.get_from_memtable_count; + get_post_process_time = other.get_post_process_time; + get_from_output_files_time = other.get_from_output_files_time; + seek_on_memtable_time = other.seek_on_memtable_time; + seek_on_memtable_count = other.seek_on_memtable_count; + next_on_memtable_count = other.next_on_memtable_count; + prev_on_memtable_count = other.prev_on_memtable_count; + seek_child_seek_time = other.seek_child_seek_time; + seek_child_seek_count = other.seek_child_seek_count; + seek_min_heap_time = other.seek_min_heap_time; + seek_internal_seek_time = other.seek_internal_seek_time; + find_next_user_entry_time = other.find_next_user_entry_time; + write_pre_and_post_process_time = other.write_pre_and_post_process_time; + write_memtable_time = other.write_memtable_time; + write_delay_time = other.write_delay_time; + write_thread_wait_nanos = other.write_thread_wait_nanos; + write_scheduling_flushes_compactions_time = + other.write_scheduling_flushes_compactions_time; + db_mutex_lock_nanos = other.db_mutex_lock_nanos; + db_condition_wait_nanos = other.db_condition_wait_nanos; + merge_operator_time_nanos = other.merge_operator_time_nanos; + read_index_block_nanos = other.read_index_block_nanos; + read_filter_block_nanos = other.read_filter_block_nanos; + new_table_block_iter_nanos = other.new_table_block_iter_nanos; + new_table_iterator_nanos = other.new_table_iterator_nanos; + block_seek_nanos = other.block_seek_nanos; + find_table_nanos = other.find_table_nanos; + bloom_memtable_hit_count = other.bloom_memtable_hit_count; + bloom_memtable_miss_count = other.bloom_memtable_miss_count; + bloom_sst_hit_count = other.bloom_sst_hit_count; + bloom_sst_miss_count = other.bloom_sst_miss_count; + key_lock_wait_time = other.key_lock_wait_time; + key_lock_wait_count = other.key_lock_wait_count; + + env_new_sequential_file_nanos = other.env_new_sequential_file_nanos; + env_new_random_access_file_nanos = other.env_new_random_access_file_nanos; + env_new_writable_file_nanos = other.env_new_writable_file_nanos; + env_reuse_writable_file_nanos = other.env_reuse_writable_file_nanos; + env_new_random_rw_file_nanos = other.env_new_random_rw_file_nanos; + env_new_directory_nanos = other.env_new_directory_nanos; + env_file_exists_nanos = other.env_file_exists_nanos; + env_get_children_nanos = other.env_get_children_nanos; + env_get_children_file_attributes_nanos = + other.env_get_children_file_attributes_nanos; + env_delete_file_nanos = other.env_delete_file_nanos; + env_create_dir_nanos = other.env_create_dir_nanos; + env_create_dir_if_missing_nanos = other.env_create_dir_if_missing_nanos; + env_delete_dir_nanos = other.env_delete_dir_nanos; + env_get_file_size_nanos = other.env_get_file_size_nanos; + env_get_file_modification_time_nanos = + other.env_get_file_modification_time_nanos; + env_rename_file_nanos = other.env_rename_file_nanos; + env_link_file_nanos = other.env_link_file_nanos; + env_lock_file_nanos = other.env_lock_file_nanos; + env_unlock_file_nanos = other.env_unlock_file_nanos; + env_new_logger_nanos = other.env_new_logger_nanos; + get_cpu_nanos = other.get_cpu_nanos; + if (per_level_perf_context_enabled && level_to_perf_context != nullptr) { + ClearPerLevelPerfContext(); + } + if (other.level_to_perf_context != nullptr) { + level_to_perf_context = new std::map(); + *level_to_perf_context = *other.level_to_perf_context; + } + per_level_perf_context_enabled = other.per_level_perf_context_enabled; +#endif +} + +PerfContext::PerfContext(PerfContext&& other) noexcept { +#ifndef NPERF_CONTEXT + user_key_comparison_count = other.user_key_comparison_count; + block_cache_hit_count = other.block_cache_hit_count; + block_read_count = other.block_read_count; + block_read_byte = other.block_read_byte; + block_read_time = other.block_read_time; + block_cache_index_hit_count = other.block_cache_index_hit_count; + index_block_read_count = other.index_block_read_count; + block_cache_filter_hit_count = other.block_cache_filter_hit_count; + filter_block_read_count = other.filter_block_read_count; + compression_dict_block_read_count = other.compression_dict_block_read_count; + block_checksum_time = other.block_checksum_time; + block_decompress_time = other.block_decompress_time; + get_read_bytes = other.get_read_bytes; + multiget_read_bytes = other.multiget_read_bytes; + iter_read_bytes = other.iter_read_bytes; + internal_key_skipped_count = other.internal_key_skipped_count; + internal_delete_skipped_count = other.internal_delete_skipped_count; + internal_recent_skipped_count = other.internal_recent_skipped_count; + internal_merge_count = other.internal_merge_count; + write_wal_time = other.write_wal_time; + get_snapshot_time = other.get_snapshot_time; + get_from_memtable_time = other.get_from_memtable_time; + get_from_memtable_count = other.get_from_memtable_count; + get_post_process_time = other.get_post_process_time; + get_from_output_files_time = other.get_from_output_files_time; + seek_on_memtable_time = other.seek_on_memtable_time; + seek_on_memtable_count = other.seek_on_memtable_count; + next_on_memtable_count = other.next_on_memtable_count; + prev_on_memtable_count = other.prev_on_memtable_count; + seek_child_seek_time = other.seek_child_seek_time; + seek_child_seek_count = other.seek_child_seek_count; + seek_min_heap_time = other.seek_min_heap_time; + seek_internal_seek_time = other.seek_internal_seek_time; + find_next_user_entry_time = other.find_next_user_entry_time; + write_pre_and_post_process_time = other.write_pre_and_post_process_time; + write_memtable_time = other.write_memtable_time; + write_delay_time = other.write_delay_time; + write_thread_wait_nanos = other.write_thread_wait_nanos; + write_scheduling_flushes_compactions_time = + other.write_scheduling_flushes_compactions_time; + db_mutex_lock_nanos = other.db_mutex_lock_nanos; + db_condition_wait_nanos = other.db_condition_wait_nanos; + merge_operator_time_nanos = other.merge_operator_time_nanos; + read_index_block_nanos = other.read_index_block_nanos; + read_filter_block_nanos = other.read_filter_block_nanos; + new_table_block_iter_nanos = other.new_table_block_iter_nanos; + new_table_iterator_nanos = other.new_table_iterator_nanos; + block_seek_nanos = other.block_seek_nanos; + find_table_nanos = other.find_table_nanos; + bloom_memtable_hit_count = other.bloom_memtable_hit_count; + bloom_memtable_miss_count = other.bloom_memtable_miss_count; + bloom_sst_hit_count = other.bloom_sst_hit_count; + bloom_sst_miss_count = other.bloom_sst_miss_count; + key_lock_wait_time = other.key_lock_wait_time; + key_lock_wait_count = other.key_lock_wait_count; + + env_new_sequential_file_nanos = other.env_new_sequential_file_nanos; + env_new_random_access_file_nanos = other.env_new_random_access_file_nanos; + env_new_writable_file_nanos = other.env_new_writable_file_nanos; + env_reuse_writable_file_nanos = other.env_reuse_writable_file_nanos; + env_new_random_rw_file_nanos = other.env_new_random_rw_file_nanos; + env_new_directory_nanos = other.env_new_directory_nanos; + env_file_exists_nanos = other.env_file_exists_nanos; + env_get_children_nanos = other.env_get_children_nanos; + env_get_children_file_attributes_nanos = + other.env_get_children_file_attributes_nanos; + env_delete_file_nanos = other.env_delete_file_nanos; + env_create_dir_nanos = other.env_create_dir_nanos; + env_create_dir_if_missing_nanos = other.env_create_dir_if_missing_nanos; + env_delete_dir_nanos = other.env_delete_dir_nanos; + env_get_file_size_nanos = other.env_get_file_size_nanos; + env_get_file_modification_time_nanos = + other.env_get_file_modification_time_nanos; + env_rename_file_nanos = other.env_rename_file_nanos; + env_link_file_nanos = other.env_link_file_nanos; + env_lock_file_nanos = other.env_lock_file_nanos; + env_unlock_file_nanos = other.env_unlock_file_nanos; + env_new_logger_nanos = other.env_new_logger_nanos; + get_cpu_nanos = other.get_cpu_nanos; + if (per_level_perf_context_enabled && level_to_perf_context != nullptr) { + ClearPerLevelPerfContext(); + } + if (other.level_to_perf_context != nullptr) { + level_to_perf_context = other.level_to_perf_context; + other.level_to_perf_context = nullptr; + } + per_level_perf_context_enabled = other.per_level_perf_context_enabled; +#endif +} + +// TODO(Zhongyi): reduce code duplication between copy constructor and +// assignment operator +PerfContext& PerfContext::operator=(const PerfContext& other) { +#ifndef NPERF_CONTEXT + user_key_comparison_count = other.user_key_comparison_count; + block_cache_hit_count = other.block_cache_hit_count; + block_read_count = other.block_read_count; + block_read_byte = other.block_read_byte; + block_read_time = other.block_read_time; + block_cache_index_hit_count = other.block_cache_index_hit_count; + index_block_read_count = other.index_block_read_count; + block_cache_filter_hit_count = other.block_cache_filter_hit_count; + filter_block_read_count = other.filter_block_read_count; + compression_dict_block_read_count = other.compression_dict_block_read_count; + block_checksum_time = other.block_checksum_time; + block_decompress_time = other.block_decompress_time; + get_read_bytes = other.get_read_bytes; + multiget_read_bytes = other.multiget_read_bytes; + iter_read_bytes = other.iter_read_bytes; + internal_key_skipped_count = other.internal_key_skipped_count; + internal_delete_skipped_count = other.internal_delete_skipped_count; + internal_recent_skipped_count = other.internal_recent_skipped_count; + internal_merge_count = other.internal_merge_count; + write_wal_time = other.write_wal_time; + get_snapshot_time = other.get_snapshot_time; + get_from_memtable_time = other.get_from_memtable_time; + get_from_memtable_count = other.get_from_memtable_count; + get_post_process_time = other.get_post_process_time; + get_from_output_files_time = other.get_from_output_files_time; + seek_on_memtable_time = other.seek_on_memtable_time; + seek_on_memtable_count = other.seek_on_memtable_count; + next_on_memtable_count = other.next_on_memtable_count; + prev_on_memtable_count = other.prev_on_memtable_count; + seek_child_seek_time = other.seek_child_seek_time; + seek_child_seek_count = other.seek_child_seek_count; + seek_min_heap_time = other.seek_min_heap_time; + seek_internal_seek_time = other.seek_internal_seek_time; + find_next_user_entry_time = other.find_next_user_entry_time; + write_pre_and_post_process_time = other.write_pre_and_post_process_time; + write_memtable_time = other.write_memtable_time; + write_delay_time = other.write_delay_time; + write_thread_wait_nanos = other.write_thread_wait_nanos; + write_scheduling_flushes_compactions_time = + other.write_scheduling_flushes_compactions_time; + db_mutex_lock_nanos = other.db_mutex_lock_nanos; + db_condition_wait_nanos = other.db_condition_wait_nanos; + merge_operator_time_nanos = other.merge_operator_time_nanos; + read_index_block_nanos = other.read_index_block_nanos; + read_filter_block_nanos = other.read_filter_block_nanos; + new_table_block_iter_nanos = other.new_table_block_iter_nanos; + new_table_iterator_nanos = other.new_table_iterator_nanos; + block_seek_nanos = other.block_seek_nanos; + find_table_nanos = other.find_table_nanos; + bloom_memtable_hit_count = other.bloom_memtable_hit_count; + bloom_memtable_miss_count = other.bloom_memtable_miss_count; + bloom_sst_hit_count = other.bloom_sst_hit_count; + bloom_sst_miss_count = other.bloom_sst_miss_count; + key_lock_wait_time = other.key_lock_wait_time; + key_lock_wait_count = other.key_lock_wait_count; + + env_new_sequential_file_nanos = other.env_new_sequential_file_nanos; + env_new_random_access_file_nanos = other.env_new_random_access_file_nanos; + env_new_writable_file_nanos = other.env_new_writable_file_nanos; + env_reuse_writable_file_nanos = other.env_reuse_writable_file_nanos; + env_new_random_rw_file_nanos = other.env_new_random_rw_file_nanos; + env_new_directory_nanos = other.env_new_directory_nanos; + env_file_exists_nanos = other.env_file_exists_nanos; + env_get_children_nanos = other.env_get_children_nanos; + env_get_children_file_attributes_nanos = + other.env_get_children_file_attributes_nanos; + env_delete_file_nanos = other.env_delete_file_nanos; + env_create_dir_nanos = other.env_create_dir_nanos; + env_create_dir_if_missing_nanos = other.env_create_dir_if_missing_nanos; + env_delete_dir_nanos = other.env_delete_dir_nanos; + env_get_file_size_nanos = other.env_get_file_size_nanos; + env_get_file_modification_time_nanos = + other.env_get_file_modification_time_nanos; + env_rename_file_nanos = other.env_rename_file_nanos; + env_link_file_nanos = other.env_link_file_nanos; + env_lock_file_nanos = other.env_lock_file_nanos; + env_unlock_file_nanos = other.env_unlock_file_nanos; + env_new_logger_nanos = other.env_new_logger_nanos; + get_cpu_nanos = other.get_cpu_nanos; + if (per_level_perf_context_enabled && level_to_perf_context != nullptr) { + ClearPerLevelPerfContext(); + } + if (other.level_to_perf_context != nullptr) { + level_to_perf_context = new std::map(); + *level_to_perf_context = *other.level_to_perf_context; + } + per_level_perf_context_enabled = other.per_level_perf_context_enabled; +#endif + return *this; +} + void PerfContext::Reset() { #ifndef NPERF_CONTEXT user_key_comparison_count = 0; @@ -240,7 +519,7 @@ std::string PerfContext::ToString(bool exclude_zero_counters) const { } void PerfContext::EnablePerLevelPerfContext() { - if (!level_to_perf_context) { + if (level_to_perf_context == nullptr) { level_to_perf_context = new std::map(); } per_level_perf_context_enabled = true; @@ -251,7 +530,8 @@ void PerfContext::DisablePerLevelPerfContext(){ } void PerfContext::ClearPerLevelPerfContext(){ - if (level_to_perf_context) { + if (level_to_perf_context != nullptr) { + level_to_perf_context->clear(); delete level_to_perf_context; level_to_perf_context = nullptr; }