[PATCH] [libcxx] Fix __is_power2 and __next_power2. Change hashmap to handle new behavior.

Eric Fiselier eric at efcs.ca
Sun Aug 17 18:04:29 PDT 2014


Woops. That last patch was wrong. I forgot to negate __is_rehash_power2.
I also incorrectly rounded 1 -> 2 in __next_power2. Both of these errors have been fixed.

http://reviews.llvm.org/D4948

Files:
  include/__hash_table

Index: include/__hash_table
===================================================================
--- include/__hash_table
+++ include/__hash_table
@@ -63,7 +63,7 @@
 bool
 __is_power2(size_t __bc)
 {
-    return __bc > 2 && !(__bc & (__bc - 1));
+    return __bc && !(__bc & (__bc - 1));
 }
 
 inline _LIBCPP_INLINE_VISIBILITY
@@ -74,10 +74,17 @@
 }
 
 inline _LIBCPP_INLINE_VISIBILITY
+bool __is_rehash_power2(size_t __bc)
+{
+    return __bc > 2 && __is_power2(__bc);
+}
+
+inline _LIBCPP_INLINE_VISIBILITY
 size_t
 __next_pow2(size_t __n)
 {
-    return size_t(1) << (std::numeric_limits<size_t>::digits - __clz(__n-1));
+    return __n < 2 ? __n + (__n == 0)
+        : size_t(1) << (std::numeric_limits<size_t>::digits - __clz(__n-1));
 }
 
 template <class _Tp, class _Hash, class _Equal, class _Alloc> class __hash_table;
@@ -1615,7 +1622,7 @@
     {
         if (size()+1 > __bc * max_load_factor() || __bc == 0)
         {
-            rehash(_VSTD::max<size_type>(2 * __bc + !__is_power2(__bc),
+            rehash(_VSTD::max<size_type>(2 * __bc + !__is_rehash_power2(__bc),
                            size_type(ceil(float(size() + 1) / max_load_factor()))));
             __bc = bucket_count();
             __chash = __constrain_hash(__nd->__hash_, __bc);
@@ -1658,7 +1665,7 @@
     size_type __bc = bucket_count();
     if (size()+1 > __bc * max_load_factor() || __bc == 0)
     {
-        rehash(_VSTD::max<size_type>(2 * __bc + !__is_power2(__bc),
+        rehash(_VSTD::max<size_type>(2 * __bc + !__is_rehash_power2(__bc),
                        size_type(ceil(float(size() + 1) / max_load_factor()))));
         __bc = bucket_count();
     }
@@ -1728,7 +1735,7 @@
         size_type __bc = bucket_count();
         if (size()+1 > __bc * max_load_factor() || __bc == 0)
         {
-            rehash(_VSTD::max<size_type>(2 * __bc + !__is_power2(__bc),
+            rehash(_VSTD::max<size_type>(2 * __bc + !__is_rehash_power2(__bc),
                            size_type(ceil(float(size() + 1) / max_load_factor()))));
             __bc = bucket_count();
         }
@@ -1776,7 +1783,7 @@
         __node_holder __h = __construct_node(__x, __hash);
         if (size()+1 > __bc * max_load_factor() || __bc == 0)
         {
-            rehash(_VSTD::max<size_type>(2 * __bc + !__is_power2(__bc),
+            rehash(_VSTD::max<size_type>(2 * __bc + !__is_rehash_power2(__bc),
                            size_type(ceil(float(size() + 1) / max_load_factor()))));
             __bc = bucket_count();
             __chash = __constrain_hash(__hash, __bc);
@@ -1946,8 +1953,9 @@
         __n = _VSTD::max<size_type>
               (
                   __n,
-                  __is_power2(__bc) ? __next_pow2(size_t(ceil(float(size()) / max_load_factor()))) :
-                                      __next_prime(size_t(ceil(float(size()) / max_load_factor())))
+                  (__is_rehash_power2(__bc))
+                    ? __next_pow2(size_t(ceil(float(size()) / max_load_factor())))
+                    : __next_prime(size_t(ceil(float(size()) / max_load_factor())))
               );
         if (__n < __bc)
             __rehash(__n);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D4948.12600.patch
Type: text/x-patch
Size: 3159 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140818/ca7c5d0f/attachment.bin>


More information about the cfe-commits mailing list