diff --git a/doc/unordered/changes.adoc b/doc/unordered/changes.adoc index 8ab7b639..b59bb90b 100644 --- a/doc/unordered/changes.adoc +++ b/doc/unordered/changes.adoc @@ -9,6 +9,7 @@ == Release 1.86.0 * Added container `pmr` aliases when header `` is available. The alias `boost::unordered::pmr::[container]` refers to `boost::unordered::[container]` with a `std::pmr::polymorphic_allocator` allocator type. +* Equipped open-addressing and concurrent containers to internally calculate and provide statistical metrics affected by the quality of the hash function. This functionality is enabled by the global macro `BOOST_UNORDERED_ENABLE_STATS`. == Release 1.85.0 diff --git a/doc/unordered/concurrent_flat_map.adoc b/doc/unordered/concurrent_flat_map.adoc index 6f87390c..50c840a9 100644 --- a/doc/unordered/concurrent_flat_map.adoc +++ b/doc/unordered/concurrent_flat_map.adoc @@ -50,6 +50,8 @@ namespace boost { using size_type = std::size_t; using difference_type = std::ptrdiff_t; + using stats = xref:stats_stats_type[__stats-type__]; // if statistics are xref:concurrent_flat_map_boost_unordered_enable_stats[enabled] + // constants static constexpr size_type xref:#concurrent_flat_map_constants[bulk_visit_size] = _implementation-defined_; @@ -228,6 +230,10 @@ namespace boost { size_type xref:#concurrent_flat_map_max_load[max_load]() const noexcept; void xref:#concurrent_flat_map_rehash[rehash](size_type n); void xref:#concurrent_flat_map_reserve[reserve](size_type n); + + // statistics (if xref:concurrent_flat_map_boost_unordered_enable_stats[enabled]) + stats xref:#concurrent_flat_map_get_stats[get_stats]() const; + void xref:#concurrent_flat_map_reset_stats[reset_stats]() noexcept; }; // Deduction Guides @@ -407,6 +413,15 @@ a function visiting elements of `m`) are detected and signalled through `BOOST_A When run-time speed is a concern, the feature can be disabled by globally defining this macro. +--- + +==== `BOOST_UNORDERED_ENABLE_STATS` + +Globally define this macro to enable xref:#stats[statistics calculation] for the table. Note +that this option decreases the overall performance of many operations. + +--- + === Constants ```cpp @@ -488,6 +503,8 @@ concurrent_flat_map(concurrent_flat_map&& other); The move constructor. The internal bucket array of `other` is transferred directly to the new table. The hash function, predicate and allocator are moved-constructed from `other`. +If statistics are xref:concurrent_flat_map_boost_unordered_enable_stats[enabled], +transfers the internal statistical information from `other` and calls `other.reset_stats()`. [horizontal] Concurrency:;; Blocking on `other`. @@ -536,6 +553,9 @@ concurrent_flat_map(concurrent_flat_map&& other, Allocator const& a); If `a == other.get_allocator()`, the elements of `other` are transferred directly to the new table; otherwise, elements are moved-constructed from those of `other`. The hash function and predicate are moved-constructed from `other`, and the allocator is copy-constructed from `a`. +If statistics are xref:concurrent_flat_map_boost_unordered_enable_stats[enabled], +transfers the internal statistical information from `other` iff `a == other.get_allocator()`, +and always calls `other.reset_stats()`. [horizontal] Concurrency:;; Blocking on `other`. @@ -551,6 +571,8 @@ concurrent_flat_map(unordered_flat_map&& other); Move construction from a xref:#unordered_flat_map[`unordered_flat_map`]. The internal bucket array of `other` is transferred directly to the new container. The hash function, predicate and allocator are moved-constructed from `other`. +If statistics are xref:concurrent_flat_map_boost_unordered_enable_stats[enabled], +transfers the internal statistical information from `other` and calls `other.reset_stats()`. [horizontal] Complexity:;; O(`bucket_count()`) @@ -709,6 +731,9 @@ The move assignment operator. Destroys previously existing elements, swaps the h and move-assigns the allocator from `other` if `Alloc::propagate_on_container_move_assignment` exists and `Alloc::propagate_on_container_move_assignment::value` is `true`. If at this point the allocator is equal to `other.get_allocator()`, the internal bucket array of `other` is transferred directly to `*this`; otherwise, inserts move-constructed copies of the elements of `other`. +If statistics are xref:concurrent_flat_map_boost_unordered_enable_stats[enabled], +transfers the internal statistical information from `other` iff the final allocator is equal to `other.get_allocator()`, +and always calls `other.reset_stats()`. [horizontal] Concurrency:;; Blocking on `*this` and `other`. @@ -1480,6 +1505,30 @@ Concurrency:;; Blocking on `*this`. --- +=== Statistics + +==== get_stats +```c++ +stats get_stats() const; +``` + +[horizontal] +Returns:;; A statistical description of the insertion and lookup operations performed by the table so far. +Notes:;; Only available if xref:stats[statistics calculation] is xref:concurrent_flat_map_boost_unordered_enable_stats[enabled]. + +--- + +==== reset_stats +```c++ +void reset_stats() noexcept; +``` + +[horizontal] +Effects:;; Sets to zero the internal statistics kept by the table. +Notes:;; Only available if xref:stats[statistics calculation] is xref:concurrent_flat_map_boost_unordered_enable_stats[enabled]. + +--- + === Deduction Guides A deduction guide will not participate in overload resolution if any of the following are true: diff --git a/doc/unordered/concurrent_flat_set.adoc b/doc/unordered/concurrent_flat_set.adoc index e7713352..c52725cc 100644 --- a/doc/unordered/concurrent_flat_set.adoc +++ b/doc/unordered/concurrent_flat_set.adoc @@ -45,6 +45,8 @@ namespace boost { using size_type = std::size_t; using difference_type = std::ptrdiff_t; + using stats = xref:stats_stats_type[__stats-type__]; // if statistics are xref:concurrent_flat_set_boost_unordered_enable_stats[enabled] + // constants static constexpr size_type xref:#concurrent_flat_set_constants[bulk_visit_size] = _implementation-defined_; @@ -188,6 +190,10 @@ namespace boost { size_type xref:#concurrent_flat_set_max_load[max_load]() const noexcept; void xref:#concurrent_flat_set_rehash[rehash](size_type n); void xref:#concurrent_flat_set_reserve[reserve](size_type n); + + // statistics (if xref:concurrent_flat_set_boost_unordered_enable_stats[enabled]) + stats xref:#concurrent_flat_set_get_stats[get_stats]() const; + void xref:#concurrent_flat_set_reset_stats[reset_stats]() noexcept; }; // Deduction Guides @@ -358,6 +364,15 @@ a function visiting elements of `m`) are detected and signalled through `BOOST_A When run-time speed is a concern, the feature can be disabled by globally defining this macro. +--- + +==== `BOOST_UNORDERED_ENABLE_STATS` + +Globally define this macro to enable xref:#stats[statistics calculation] for the table. Note +that this option decreases the overall performance of many operations. + +--- + === Constants ```cpp @@ -439,6 +454,8 @@ concurrent_flat_set(concurrent_flat_set&& other); The move constructor. The internal bucket array of `other` is transferred directly to the new table. The hash function, predicate and allocator are moved-constructed from `other`. +If statistics are xref:concurrent_flat_set_boost_unordered_enable_stats[enabled], +transfers the internal statistical information from `other` and calls `other.reset_stats()`. [horizontal] Concurrency:;; Blocking on `other`. @@ -487,6 +504,9 @@ concurrent_flat_set(concurrent_flat_set&& other, Allocator const& a); If `a == other.get_allocator()`, the elements of `other` are transferred directly to the new table; otherwise, elements are moved-constructed from those of `other`. The hash function and predicate are moved-constructed from `other`, and the allocator is copy-constructed from `a`. +If statistics are xref:concurrent_flat_set_boost_unordered_enable_stats[enabled], +transfers the internal statistical information from `other` iff `a == other.get_allocator()`, +and always calls `other.reset_stats()`. [horizontal] Concurrency:;; Blocking on `other`. @@ -502,6 +522,8 @@ concurrent_flat_set(unordered_flat_set&& other); Move construction from a xref:#unordered_flat_set[`unordered_flat_set`]. The internal bucket array of `other` is transferred directly to the new container. The hash function, predicate and allocator are moved-constructed from `other`. +If statistics are xref:concurrent_flat_set_boost_unordered_enable_stats[enabled], +transfers the internal statistical information from `other` and calls `other.reset_stats()`. [horizontal] Complexity:;; O(`bucket_count()`) @@ -659,6 +681,9 @@ The move assignment operator. Destroys previously existing elements, swaps the h and move-assigns the allocator from `other` if `Alloc::propagate_on_container_move_assignment` exists and `Alloc::propagate_on_container_move_assignment::value` is `true`. If at this point the allocator is equal to `other.get_allocator()`, the internal bucket array of `other` is transferred directly to `*this`; otherwise, inserts move-constructed copies of the elements of `other`. +If statistics are xref:concurrent_flat_set_boost_unordered_enable_stats[enabled], +transfers the internal statistical information from `other` iff the final allocator is equal to `other.get_allocator()`, +and always calls `other.reset_stats()`. [horizontal] Concurrency:;; Blocking on `*this` and `other`. @@ -1316,6 +1341,30 @@ Concurrency:;; Blocking on `*this`. --- +=== Statistics + +==== get_stats +```c++ +stats get_stats() const; +``` + +[horizontal] +Returns:;; A statistical description of the insertion and lookup operations performed by the table so far. +Notes:;; Only available if xref:stats[statistics calculation] is xref:concurrent_flat_set_boost_unordered_enable_stats[enabled]. + +--- + +==== reset_stats +```c++ +void reset_stats() noexcept; +``` + +[horizontal] +Effects:;; Sets to zero the internal statistics kept by the table. +Notes:;; Only available if xref:stats[statistics calculation] is xref:concurrent_flat_set_boost_unordered_enable_stats[enabled]. + +--- + === Deduction Guides A deduction guide will not participate in overload resolution if any of the following are true: diff --git a/doc/unordered/ref.adoc b/doc/unordered/ref.adoc index 08743fa6..6a0d22c4 100644 --- a/doc/unordered/ref.adoc +++ b/doc/unordered/ref.adoc @@ -6,6 +6,7 @@ include::unordered_multimap.adoc[] include::unordered_set.adoc[] include::unordered_multiset.adoc[] include::hash_traits.adoc[] +include::stats.adoc[] include::unordered_flat_map.adoc[] include::unordered_flat_set.adoc[] include::unordered_node_map.adoc[] diff --git a/doc/unordered/stats.adoc b/doc/unordered/stats.adoc new file mode 100644 index 00000000..944b6069 --- /dev/null +++ b/doc/unordered/stats.adoc @@ -0,0 +1,71 @@ +[#stats] +== Statistics + +:idprefix: stats_ + +Open-addressing and concurrent containers can be configured to keep running statistics +of some internal operations affected by the quality of the supplied hash function. + +=== Synopsis + +[listing,subs="+macros,+quotes"] +----- +struct xref:#stats_stats_summary_type[__stats-summary-type__] +{ + double average; + double variance; + double deviation; +}; + +struct xref:#stats_insertion_stats_type[__insertion-stats-type__] +{ + std::size_t count; + xref:#stats_stats_summary_type[__stats-summary-type__] probe_length; +}; + +struct xref:stats_lookup_stats_type[__lookup-stats-type__] +{ + std::size_t count; + xref:#stats_stats_summary_type[__stats-summary-type__] probe_length; + xref:#stats_stats_summary_type[__stats-summary-type__] num_comparisons; +}; + +struct xref:stats_stats_type[__stats-type__] +{ + xref:#stats_insertion_stats_type[__insertion-stats-type__] insertion; + xref:stats_lookup_stats_type[__lookup-stats-type__] successful_lookup, + unsuccessful_lookup; +}; +----- + +==== __stats-summary-type__ + +Provides the average value, variance and standard deviation of a sequence of numerical values. + +==== __insertion-stats-type__ + +Provides the number of insertion operations performed by a container and +statistics on the associated __probe length__ (number of +xref:#structures_open_addressing_containers[bucket groups] accessed per operation). + +==== __lookup-stats-type__ + +For successful (element found) or unsuccessful (not found) lookup, +provides the number of operations performed by a container and +statistics on the associated __probe length__ (number of +xref:#structures_open_addressing_containers[bucket groups] accessed) +and number of element comparisons per operation. + +==== __stats-type__ + +Provides statistics on insertion, successful and unsuccessful lookups performed by a container. +If the supplied hash function has good quality, then: + +* Average probe lenghts should be close to 1.0. +* For successful lookups, the average number of element comparisons should be close to 1.0. +* For unsuccessful lookups, the average number of element comparisons should be close to 0.0. + +These statistics can be used to determine if a given hash function +can be marked as xref:hash_traits_hash_is_avalanching[__avalanching__]. + +--- diff --git a/doc/unordered/unordered_flat_map.adoc b/doc/unordered/unordered_flat_map.adoc index 07f90d0e..13733f50 100644 --- a/doc/unordered/unordered_flat_map.adoc +++ b/doc/unordered/unordered_flat_map.adoc @@ -58,6 +58,8 @@ namespace boost { using iterator = _implementation-defined_; using const_iterator = _implementation-defined_; + using stats = xref:stats_stats_type[__stats-type__]; // if statistics are xref:unordered_flat_map_boost_unordered_enable_stats[enabled] + // construct/copy/destroy xref:#unordered_flat_map_default_constructor[unordered_flat_map](); explicit xref:#unordered_flat_map_bucket_count_constructor[unordered_flat_map](size_type n, @@ -214,6 +216,10 @@ namespace boost { size_type xref:#unordered_flat_map_max_load[max_load]() const noexcept; void xref:#unordered_flat_map_rehash[rehash](size_type n); void xref:#unordered_flat_map_reserve[reserve](size_type n); + + // statistics (if xref:unordered_flat_map_boost_unordered_enable_stats[enabled]) + stats xref:#unordered_flat_map_get_stats[get_stats]() const; + void xref:#unordered_flat_map_reset_stats[reset_stats]() noexcept; }; // Deduction Guides @@ -343,6 +349,15 @@ at the expense of extra computational cost. --- +=== Configuration Macros + +==== `BOOST_UNORDERED_ENABLE_STATS` + +Globally define this macro to enable xref:#stats[statistics calculation] for the container. Note +that this option decreases the overall performance of many operations. + +--- + === Typedefs [source,c++,subs=+quotes] @@ -439,6 +454,8 @@ unordered_flat_map(unordered_flat_map&& other); The move constructor. The internal bucket array of `other` is transferred directly to the new container. The hash function, predicate and allocator are moved-constructed from `other`. +If statistics are xref:unordered_flat_map_boost_unordered_enable_stats[enabled], +transfers the internal statistical information from `other` and calls `other.reset_stats()`. --- @@ -481,6 +498,9 @@ unordered_flat_map(unordered_flat_map&& other, Allocator const& a); If `a == other.get_allocator()`, the elements of `other` are transferred directly to the new container; otherwise, elements are moved-constructed from those of `other`. The hash function and predicate are moved-constructed from `other`, and the allocator is copy-constructed from `a`. +If statistics are xref:unordered_flat_map_boost_unordered_enable_stats[enabled], +transfers the internal statistical information from `other` iff `a == other.get_allocator()`, +and always calls `other.reset_stats()`. --- @@ -493,6 +513,8 @@ unordered_flat_map(concurrent_flat_map&& other); Move construction from a xref:#concurrent_flat_map[`concurrent_flat_map`]. The internal bucket array of `other` is transferred directly to the new container. The hash function, predicate and allocator are moved-constructed from `other`. +If statistics are xref:unordered_flat_map_boost_unordered_enable_stats[enabled], +transfers the internal statistical information from `other` and calls `other.reset_stats()`. [horizontal] Complexity:;; Constant time. @@ -651,6 +673,9 @@ The move assignment operator. Destroys previously existing elements, swaps the h and move-assigns the allocator from `other` if `Alloc::propagate_on_container_move_assignment` exists and `Alloc::propagate_on_container_move_assignment::value` is `true`. If at this point the allocator is equal to `other.get_allocator()`, the internal bucket array of `other` is transferred directly to the new container; otherwise, inserts move-constructed copies of the elements of `other`. +If statistics are xref:unordered_flat_map_boost_unordered_enable_stats[enabled], +transfers the internal statistical information from `other` iff the final allocator is equal to `other.get_allocator()`, +and always calls `other.reset_stats()`. --- @@ -1364,6 +1389,32 @@ Invalidates iterators, pointers and references, and changes the order of element [horizontal] Throws:;; The function has no effect if an exception is thrown, unless it is thrown by the container's hash function or comparison function. +--- + +=== Statistics + +==== get_stats +```c++ +stats get_stats() const; +``` + +[horizontal] +Returns:;; A statistical description of the insertion and lookup operations performed by the container so far. +Notes:;; Only available if xref:stats[statistics calculation] is xref:unordered_flat_map_boost_unordered_enable_stats[enabled]. + +--- + +==== reset_stats +```c++ +void reset_stats() noexcept; +``` + +[horizontal] +Effects:;; Sets to zero the internal statistics kept by the container. +Notes:;; Only available if xref:stats[statistics calculation] is xref:unordered_flat_map_boost_unordered_enable_stats[enabled]. + +--- + === Deduction Guides A deduction guide will not participate in overload resolution if any of the following are true: diff --git a/doc/unordered/unordered_flat_set.adoc b/doc/unordered/unordered_flat_set.adoc index 48ca0837..caa58586 100644 --- a/doc/unordered/unordered_flat_set.adoc +++ b/doc/unordered/unordered_flat_set.adoc @@ -53,6 +53,8 @@ namespace boost { using iterator = _implementation-defined_; using const_iterator = _implementation-defined_; + using stats = xref:stats_stats_type[__stats-type__]; // if statistics are xref:unordered_flat_set_boost_unordered_enable_stats[enabled] + // construct/copy/destroy xref:#unordered_flat_set_default_constructor[unordered_flat_set](); explicit xref:#unordered_flat_set_bucket_count_constructor[unordered_flat_set](size_type n, @@ -172,6 +174,10 @@ namespace boost { size_type xref:#unordered_flat_set_max_load[max_load]() const noexcept; void xref:#unordered_flat_set_rehash[rehash](size_type n); void xref:#unordered_flat_set_reserve[reserve](size_type n); + + // statistics (if xref:unordered_flat_set_boost_unordered_enable_stats[enabled]) + stats xref:#unordered_flat_set_get_stats[get_stats]() const; + void xref:#unordered_flat_set_reset_stats[reset_stats]() noexcept; }; // Deduction Guides @@ -291,6 +297,15 @@ at the expense of extra computational cost. --- +=== Configuration Macros + +==== `BOOST_UNORDERED_ENABLE_STATS` + +Globally define this macro to enable xref:#stats[statistics calculation] for the container. Note +that this option decreases the overall performance of many operations. + +--- + === Typedefs [source,c++,subs=+quotes] @@ -387,6 +402,8 @@ unordered_flat_set(unordered_flat_set&& other); The move constructor. The internal bucket array of `other` is transferred directly to the new container. The hash function, predicate and allocator are moved-constructed from `other`. +If statistics are xref:unordered_flat_set_boost_unordered_enable_stats[enabled], +transfers the internal statistical information from `other` and calls `other.reset_stats()`. --- @@ -429,6 +446,9 @@ unordered_flat_set(unordered_flat_set&& other, Allocator const& a); If `a == other.get_allocator()`, the elements of `other` are transferred directly to the new container; otherwise, elements are moved-constructed from those of `other`. The hash function and predicate are moved-constructed from `other`, and the allocator is copy-constructed from `a`. +If statistics are xref:unordered_flat_set_boost_unordered_enable_stats[enabled], +transfers the internal statistical information from `other` iff `a == other.get_allocator()`, +and always calls `other.reset_stats()`. --- @@ -441,6 +461,8 @@ unordered_flat_set(concurrent_flat_set&& other); Move construction from a xref:#concurrent_flat_set[`concurrent_flat_set`]. The internal bucket array of `other` is transferred directly to the new container. The hash function, predicate and allocator are moved-constructed from `other`. +If statistics are xref:unordered_flat_set_boost_unordered_enable_stats[enabled], +transfers the internal statistical information from `other` and calls `other.reset_stats()`. [horizontal] Complexity:;; Constant time. @@ -599,6 +621,9 @@ The move assignment operator. Destroys previously existing elements, swaps the h and move-assigns the allocator from `other` if `Alloc::propagate_on_container_move_assignment` exists and `Alloc::propagate_on_container_move_assignment::value` is `true`. If at this point the allocator is equal to `other.get_allocator()`, the internal bucket array of `other` is transferred directly to the new container; otherwise, inserts move-constructed copies of the elements of `other`. +If statistics are xref:unordered_flat_set_boost_unordered_enable_stats[enabled], +transfers the internal statistical information from `other` iff the final allocator is equal to `other.get_allocator()`, +and always calls `other.reset_stats()`. --- @@ -1137,6 +1162,32 @@ Invalidates iterators, pointers and references, and changes the order of element [horizontal] Throws:;; The function has no effect if an exception is thrown, unless it is thrown by the container's hash function or comparison function. +--- + +=== Statistics + +==== get_stats +```c++ +stats get_stats() const; +``` + +[horizontal] +Returns:;; A statistical description of the insertion and lookup operations performed by the container so far. +Notes:;; Only available if xref:stats[statistics calculation] is xref:unordered_flat_set_boost_unordered_enable_stats[enabled]. + +--- + +==== reset_stats +```c++ +void reset_stats() noexcept; +``` + +[horizontal] +Effects:;; Sets to zero the internal statistics kept by the container. +Notes:;; Only available if xref:stats[statistics calculation] is xref:unordered_flat_set_boost_unordered_enable_stats[enabled]. + +--- + === Deduction Guides A deduction guide will not participate in overload resolution if any of the following are true: diff --git a/doc/unordered/unordered_node_map.adoc b/doc/unordered/unordered_node_map.adoc index 8056bb64..f5f7d77f 100644 --- a/doc/unordered/unordered_node_map.adoc +++ b/doc/unordered/unordered_node_map.adoc @@ -57,6 +57,8 @@ namespace boost { using node_type = _implementation-defined_; using insert_return_type = _implementation-defined_; + using stats = xref:stats_stats_type[__stats-type__]; // if statistics are xref:unordered_node_map_boost_unordered_enable_stats[enabled] + // construct/copy/destroy xref:#unordered_node_map_default_constructor[unordered_node_map](); explicit xref:#unordered_node_map_bucket_count_constructor[unordered_node_map](size_type n, @@ -217,6 +219,10 @@ namespace boost { size_type xref:#unordered_node_map_max_load[max_load]() const noexcept; void xref:#unordered_node_map_rehash[rehash](size_type n); void xref:#unordered_node_map_reserve[reserve](size_type n); + + // statistics (if xref:unordered_node_map_boost_unordered_enable_stats[enabled]) + stats xref:#unordered_node_map_get_stats[get_stats]() const; + void xref:#unordered_node_map_reset_stats[reset_stats]() noexcept; }; // Deduction Guides @@ -345,6 +351,15 @@ at the expense of extra computational cost. --- +=== Configuration Macros + +==== `BOOST_UNORDERED_ENABLE_STATS` + +Globally define this macro to enable xref:#stats[statistics calculation] for the container. Note +that this option decreases the overall performance of many operations. + +--- + === Typedefs [source,c++,subs=+quotes] @@ -472,6 +487,8 @@ unordered_node_map(unordered_node_map&& other); The move constructor. The internal bucket array of `other` is transferred directly to the new container. The hash function, predicate and allocator are moved-constructed from `other`. +If statistics are xref:unordered_node_map_boost_unordered_enable_stats[enabled], +transfers the internal statistical information from `other` and calls `other.reset_stats()`. --- @@ -514,6 +531,9 @@ unordered_node_map(unordered_node_map&& other, Allocator const& a); If `a == other.get_allocator()`, the element nodes of `other` are transferred directly to the new container; otherwise, elements are moved-constructed from those of `other`. The hash function and predicate are moved-constructed from `other`, and the allocator is copy-constructed from `a`. +If statistics are xref:unordered_node_map_boost_unordered_enable_stats[enabled], +transfers the internal statistical information from `other` iff `a == other.get_allocator()`, +and always calls `other.reset_stats()`. --- @@ -668,6 +688,9 @@ The move assignment operator. Destroys previously existing elements, swaps the h and move-assigns the allocator from `other` if `Alloc::propagate_on_container_move_assignment` exists and `Alloc::propagate_on_container_move_assignment::value` is `true`. If at this point the allocator is equal to `other.get_allocator()`, the internal bucket array of `other` is transferred directly to the new container; otherwise, inserts move-constructed copies of the elements of `other`. +If statistics are xref:unordered_node_map_boost_unordered_enable_stats[enabled], +transfers the internal statistical information from `other` iff the final allocator is equal to `other.get_allocator()`, +and always calls `other.reset_stats()`. --- @@ -1451,6 +1474,32 @@ Invalidates iterators and changes the order of elements. [horizontal] Throws:;; The function has no effect if an exception is thrown, unless it is thrown by the container's hash function or comparison function. +--- + +=== Statistics + +==== get_stats +```c++ +stats get_stats() const; +``` + +[horizontal] +Returns:;; A statistical description of the insertion and lookup operations performed by the container so far. +Notes:;; Only available if xref:stats[statistics calculation] is xref:unordered_node_map_boost_unordered_enable_stats[enabled]. + +--- + +==== reset_stats +```c++ +void reset_stats() noexcept; +``` + +[horizontal] +Effects:;; Sets to zero the internal statistics kept by the container. +Notes:;; Only available if xref:stats[statistics calculation] is xref:unordered_node_map_boost_unordered_enable_stats[enabled]. + +--- + === Deduction Guides A deduction guide will not participate in overload resolution if any of the following are true: diff --git a/doc/unordered/unordered_node_set.adoc b/doc/unordered/unordered_node_set.adoc index f5b5fdf2..af1255d5 100644 --- a/doc/unordered/unordered_node_set.adoc +++ b/doc/unordered/unordered_node_set.adoc @@ -52,6 +52,8 @@ namespace boost { using node_type = _implementation-defined_; using insert_return_type = _implementation-defined_; + using stats = xref:stats_stats_type[__stats-type__]; // if statistics are xref:unordered_node_set_boost_unordered_enable_stats[enabled] + // construct/copy/destroy xref:#unordered_node_set_default_constructor[unordered_node_set](); explicit xref:#unordered_node_set_bucket_count_constructor[unordered_node_set](size_type n, @@ -176,6 +178,10 @@ namespace boost { size_type xref:#unordered_node_set_max_load[max_load]() const noexcept; void xref:#unordered_node_set_rehash[rehash](size_type n); void xref:#unordered_node_set_reserve[reserve](size_type n); + + // statistics (if xref:unordered_node_set_boost_unordered_enable_stats[enabled]) + stats xref:#unordered_node_set_get_stats[get_stats]() const; + void xref:#unordered_node_set_reset_stats[reset_stats]() noexcept; }; // Deduction Guides @@ -294,6 +300,15 @@ at the expense of extra computational cost. --- +=== Configuration Macros + +==== `BOOST_UNORDERED_ENABLE_STATS` + +Globally define this macro to enable xref:#stats[statistics calculation] for the container. Note +that this option decreases the overall performance of many operations. + +--- + === Typedefs [source,c++,subs=+quotes] @@ -424,6 +439,8 @@ unordered_node_set(unordered_node_set&& other); The move constructor. The internal bucket array of `other` is transferred directly to the new container. The hash function, predicate and allocator are moved-constructed from `other`. +If statistics are xref:unordered_node_set_boost_unordered_enable_stats[enabled], +transfers the internal statistical information from `other` and calls `other.reset_stats()`. --- @@ -466,6 +483,9 @@ unordered_node_set(unordered_node_set&& other, Allocator const& a); If `a == other.get_allocator()`, the element nodes of `other` are transferred directly to the new container; otherwise, elements are moved-constructed from those of `other`. The hash function and predicate are moved-constructed from `other`, and the allocator is copy-constructed from `a`. +If statistics are xref:unordered_node_set_boost_unordered_enable_stats[enabled], +transfers the internal statistical information from `other` iff `a == other.get_allocator()`, +and always calls `other.reset_stats()`. --- @@ -620,6 +640,9 @@ The move assignment operator. Destroys previously existing elements, swaps the h and move-assigns the allocator from `other` if `Alloc::propagate_on_container_move_assignment` exists and `Alloc::propagate_on_container_move_assignment::value` is `true`. If at this point the allocator is equal to `other.get_allocator()`, the internal bucket array of `other` is transferred directly to the new container; otherwise, inserts move-constructed copies of the elements of `other`. +If statistics are xref:unordered_node_set_boost_unordered_enable_stats[enabled], +transfers the internal statistical information from `other` iff the final allocator is equal to `other.get_allocator()`, +and always calls `other.reset_stats()`. --- @@ -1228,6 +1251,32 @@ Invalidates iterators and changes the order of elements. [horizontal] Throws:;; The function has no effect if an exception is thrown, unless it is thrown by the container's hash function or comparison function. +--- + +=== Statistics + +==== get_stats +```c++ +stats get_stats() const; +``` + +[horizontal] +Returns:;; A statistical description of the insertion and lookup operations performed by the container so far. +Notes:;; Only available if xref:stats[statistics calculation] is xref:unordered_node_set_boost_unordered_enable_stats[enabled]. + +--- + +==== reset_stats +```c++ +void reset_stats() noexcept; +``` + +[horizontal] +Effects:;; Sets to zero the internal statistics kept by the container. +Notes:;; Only available if xref:stats[statistics calculation] is xref:unordered_node_set_boost_unordered_enable_stats[enabled]. + +--- + === Deduction Guides A deduction guide will not participate in overload resolution if any of the following are true: