Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenlib/BLI_hash_tables.hh')
-rw-r--r--source/blender/blenlib/BLI_hash_tables.hh175
1 files changed, 91 insertions, 84 deletions
diff --git a/source/blender/blenlib/BLI_hash_tables.hh b/source/blender/blenlib/BLI_hash_tables.hh
index b565b396a7a..5d8f8862a09 100644
--- a/source/blender/blenlib/BLI_hash_tables.hh
+++ b/source/blender/blenlib/BLI_hash_tables.hh
@@ -30,6 +30,7 @@
#include "BLI_math_base.h"
#include "BLI_memory_utils.hh"
#include "BLI_string.h"
+#include "BLI_string_ref.hh"
#include "BLI_utildefines.h"
#include "BLI_vector.hh"
@@ -38,61 +39,67 @@ namespace blender {
/* -------------------------------------------------------------------- */
/** \name Constexpr Utility Functions
*
- * Those should eventually be deduplicated with functions in BLI_math_base.h.
+ * Those should eventually be de-duplicated with functions in BLI_math_base.h.
* \{ */
-inline constexpr int is_power_of_2_i_constexpr(int n)
+inline constexpr int64_t is_power_of_2_constexpr(const int64_t x)
{
- return (n & (n - 1)) == 0;
+ BLI_assert(x >= 0);
+ return (x & (x - 1)) == 0;
}
-inline constexpr uint32_t log2_floor_u_constexpr(uint32_t x)
+inline constexpr int64_t log2_floor_constexpr(const int64_t x)
{
- return x <= 1 ? 0 : 1 + log2_floor_u_constexpr(x >> 1);
+ BLI_assert(x >= 0);
+ return x <= 1 ? 0 : 1 + log2_floor_constexpr(x >> 1);
}
-inline constexpr uint32_t log2_ceil_u_constexpr(uint32_t x)
+inline constexpr int64_t log2_ceil_constexpr(const int64_t x)
{
- return (is_power_of_2_i_constexpr((int)x)) ? log2_floor_u_constexpr(x) :
- log2_floor_u_constexpr(x) + 1;
+ BLI_assert(x >= 0);
+ return (is_power_of_2_constexpr((int)x)) ? log2_floor_constexpr(x) : log2_floor_constexpr(x) + 1;
}
-inline constexpr uint32_t power_of_2_max_u_constexpr(uint32_t x)
+inline constexpr int64_t power_of_2_max_constexpr(const int64_t x)
{
- return 1u << log2_ceil_u_constexpr(x);
+ BLI_assert(x >= 0);
+ return 1ll << log2_ceil_constexpr(x);
}
-template<typename IntT> inline constexpr IntT ceil_division(IntT x, IntT y)
+template<typename IntT> inline constexpr IntT ceil_division(const IntT x, const IntT y)
{
- BLI_STATIC_ASSERT(!std::is_signed<IntT>::value, "");
+ BLI_assert(x >= 0);
+ BLI_assert(y >= 0);
return x / y + ((x % y) != 0);
}
-template<typename IntT> inline constexpr IntT floor_division(IntT x, IntT y)
+template<typename IntT> inline constexpr IntT floor_division(const IntT x, const IntT y)
{
- BLI_STATIC_ASSERT(!std::is_signed<IntT>::value, "");
+ BLI_assert(x >= 0);
+ BLI_assert(y >= 0);
return x / y;
}
-inline constexpr uint32_t ceil_division_by_fraction(uint32_t x,
- uint32_t numerator,
- uint32_t denominator)
+inline constexpr int64_t ceil_division_by_fraction(const int64_t x,
+ const int64_t numerator,
+ const int64_t denominator)
{
- return (uint32_t)ceil_division((uint64_t)x * (uint64_t)denominator, (uint64_t)numerator);
+ return (int64_t)ceil_division((uint64_t)x * (uint64_t)denominator, (uint64_t)numerator);
}
-inline constexpr uint32_t floor_multiplication_with_fraction(uint32_t x,
- uint32_t numerator,
- uint32_t denominator)
+inline constexpr int64_t floor_multiplication_with_fraction(const int64_t x,
+ const int64_t numerator,
+ const int64_t denominator)
{
- return (uint32_t)((uint64_t)x * (uint64_t)numerator / (uint64_t)denominator);
+ return (int64_t)((uint64_t)x * (uint64_t)numerator / (uint64_t)denominator);
}
-inline constexpr uint32_t total_slot_amount_for_usable_slots(uint32_t min_usable_slots,
- uint32_t max_load_factor_numerator,
- uint32_t max_load_factor_denominator)
+inline constexpr int64_t total_slot_amount_for_usable_slots(
+ const int64_t min_usable_slots,
+ const int64_t max_load_factor_numerator,
+ const int64_t max_load_factor_denominator)
{
- return power_of_2_max_u_constexpr(ceil_division_by_fraction(
+ return power_of_2_max_constexpr(ceil_division_by_fraction(
min_usable_slots, max_load_factor_numerator, max_load_factor_denominator));
}
@@ -108,37 +115,37 @@ inline constexpr uint32_t total_slot_amount_for_usable_slots(uint32_t min_usable
class LoadFactor {
private:
- uint8_t m_numerator;
- uint8_t m_denominator;
+ uint8_t numerator_;
+ uint8_t denominator_;
public:
LoadFactor(uint8_t numerator, uint8_t denominator)
- : m_numerator(numerator), m_denominator(denominator)
+ : numerator_(numerator), denominator_(denominator)
{
BLI_assert(numerator > 0);
BLI_assert(numerator < denominator);
}
- void compute_total_and_usable_slots(uint32_t min_total_slots,
- uint32_t min_usable_slots,
- uint32_t *r_total_slots,
- uint32_t *r_usable_slots) const
+ void compute_total_and_usable_slots(int64_t min_total_slots,
+ int64_t min_usable_slots,
+ int64_t *r_total_slots,
+ int64_t *r_usable_slots) const
{
BLI_assert(is_power_of_2_i((int)min_total_slots));
- uint32_t total_slots = this->compute_total_slots(min_usable_slots, m_numerator, m_denominator);
+ int64_t total_slots = this->compute_total_slots(min_usable_slots, numerator_, denominator_);
total_slots = std::max(total_slots, min_total_slots);
- uint32_t usable_slots = floor_multiplication_with_fraction(
- total_slots, m_numerator, m_denominator);
+ const int64_t usable_slots = floor_multiplication_with_fraction(
+ total_slots, numerator_, denominator_);
BLI_assert(min_usable_slots <= usable_slots);
*r_total_slots = total_slots;
*r_usable_slots = usable_slots;
}
- static constexpr uint32_t compute_total_slots(uint32_t min_usable_slots,
- uint8_t numerator,
- uint8_t denominator)
+ static constexpr int64_t compute_total_slots(int64_t min_usable_slots,
+ uint8_t numerator,
+ uint8_t denominator)
{
return total_slot_amount_for_usable_slots(min_usable_slots, numerator, denominator);
}
@@ -157,10 +164,10 @@ class LoadFactor {
* two values of the key type are selected to indicate whether the slot is empty or removed.
*
* The classes below tell a slot implementation which special key values it can use. They can be
- * used as KeyInfo in slot types like IntrusiveSetSlot and IntrusiveMapSlot.
+ * used as #KeyInfo in slot types like #IntrusiveSetSlot and #IntrusiveMapSlot.
*
- * A KeyInfo type has to implement a couple of static methods that are descriped in
- * TemplatedKeyInfo.
+ * A #KeyInfo type has to implement a couple of static methods that are descried in
+ * #TemplatedKeyInfo.
*
* \{ */
@@ -260,72 +267,72 @@ template<typename Pointer> struct PointerKeyInfo {
class HashTableStats {
private:
- Vector<uint32_t> m_keys_by_collision_count;
- uint32_t m_total_collisions;
- float m_average_collisions;
- uint32_t m_size;
- uint32_t m_capacity;
- uint32_t m_removed_amount;
- float m_load_factor;
- float m_removed_load_factor;
- uint32_t m_size_per_element;
- uint32_t m_size_in_bytes;
- const void *m_address;
+ Vector<int64_t> keys_by_collision_count_;
+ int64_t total_collisions_;
+ float average_collisions_;
+ int64_t size_;
+ int64_t capacity_;
+ int64_t removed_amount_;
+ float load_factor_;
+ float removed_load_factor_;
+ int64_t size_per_element_;
+ int64_t size_in_bytes_;
+ const void *address_;
public:
/**
* Requires that the hash table has the following methods:
- * - count_collisions(key) -> uint32_t
- * - size() -> uint32_t
- * - capacity() -> uint32_t
- * - removed_amount() -> uint32_t
- * - size_per_element() -> uint32_t
- * - size_in_bytes() -> uint32_t
+ * - count_collisions(key) -> int64_t
+ * - size() -> int64_t
+ * - capacity() -> int64_t
+ * - removed_amount() -> int64_t
+ * - size_per_element() -> int64_t
+ * - size_in_bytes() -> int64_t
*/
template<typename HashTable, typename Keys>
HashTableStats(const HashTable &hash_table, const Keys &keys)
{
- m_total_collisions = 0;
- m_size = hash_table.size();
- m_capacity = hash_table.capacity();
- m_removed_amount = hash_table.removed_amount();
- m_size_per_element = hash_table.size_per_element();
- m_size_in_bytes = hash_table.size_in_bytes();
- m_address = (const void *)&hash_table;
+ total_collisions_ = 0;
+ size_ = hash_table.size();
+ capacity_ = hash_table.capacity();
+ removed_amount_ = hash_table.removed_amount();
+ size_per_element_ = hash_table.size_per_element();
+ size_in_bytes_ = hash_table.size_in_bytes();
+ address_ = (const void *)&hash_table;
for (const auto &key : keys) {
- uint32_t collisions = hash_table.count_collisions(key);
- if (m_keys_by_collision_count.size() <= collisions) {
- m_keys_by_collision_count.append_n_times(
- 0, collisions - m_keys_by_collision_count.size() + 1);
+ int64_t collisions = hash_table.count_collisions(key);
+ if (keys_by_collision_count_.size() <= collisions) {
+ keys_by_collision_count_.append_n_times(0,
+ collisions - keys_by_collision_count_.size() + 1);
}
- m_keys_by_collision_count[collisions]++;
- m_total_collisions += collisions;
+ keys_by_collision_count_[collisions]++;
+ total_collisions_ += collisions;
}
- m_average_collisions = (m_size == 0) ? 0 : (float)m_total_collisions / (float)m_size;
- m_load_factor = (float)m_size / (float)m_capacity;
- m_removed_load_factor = (float)m_removed_amount / (float)m_capacity;
+ average_collisions_ = (size_ == 0) ? 0 : (float)total_collisions_ / (float)size_;
+ load_factor_ = (float)size_ / (float)capacity_;
+ removed_load_factor_ = (float)removed_amount_ / (float)capacity_;
}
void print(StringRef name = "")
{
std::cout << "Hash Table Stats: " << name << "\n";
- std::cout << " Address: " << m_address << "\n";
- std::cout << " Total Slots: " << m_capacity << "\n";
- std::cout << " Occupied Slots: " << m_size << " (" << m_load_factor * 100.0f << " %)\n";
- std::cout << " Removed Slots: " << m_removed_amount << " (" << m_removed_load_factor * 100.0f
+ std::cout << " Address: " << address_ << "\n";
+ std::cout << " Total Slots: " << capacity_ << "\n";
+ std::cout << " Occupied Slots: " << size_ << " (" << load_factor_ * 100.0f << " %)\n";
+ std::cout << " Removed Slots: " << removed_amount_ << " (" << removed_load_factor_ * 100.0f
<< " %)\n";
char memory_size_str[15];
- BLI_str_format_byte_unit(memory_size_str, m_size_in_bytes, true);
+ BLI_str_format_byte_unit(memory_size_str, size_in_bytes_, true);
std::cout << " Size: ~" << memory_size_str << "\n";
- std::cout << " Size per Slot: " << m_size_per_element << " bytes\n";
+ std::cout << " Size per Slot: " << size_per_element_ << " bytes\n";
- std::cout << " Average Collisions: " << m_average_collisions << "\n";
- for (uint32_t collision_count : m_keys_by_collision_count.index_range()) {
+ std::cout << " Average Collisions: " << average_collisions_ << "\n";
+ for (int64_t collision_count : keys_by_collision_count_.index_range()) {
std::cout << " " << collision_count
- << " Collisions: " << m_keys_by_collision_count[collision_count] << "\n";
+ << " Collisions: " << keys_by_collision_count_[collision_count] << "\n";
}
}
};