From 601daa0e5d2664c80dc6fef1fdc03280a5ec6617 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Mon, 24 Nov 2008 22:56:04 +0000 Subject: [PATCH] Use a larger prime number list. Fixes #1710 [SVN r49926] --- doc/changes.qbk | 3 ++ include/boost/unordered/detail/hash_table.hpp | 5 +-- .../unordered/detail/hash_table_impl.hpp | 31 ++++++++++++++----- 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/doc/changes.qbk b/doc/changes.qbk index ee58b2a9..09fd4c4d 100644 --- a/doc/changes.qbk +++ b/doc/changes.qbk @@ -49,5 +49,8 @@ First official release. Document that the equality and inequality operators are undefined for two objects if their equality predicates aren't equivalent. Thanks to Daniel Krügler. +* [@https://svn.boost.org/trac/boost/ticket/1710 Ticket 1710]: + Use a larger prime number list. Thanks to Thorsten Ottosen and Hervé + Brönnimann. [endsect] diff --git a/include/boost/unordered/detail/hash_table.hpp b/include/boost/unordered/detail/hash_table.hpp index 7e649a3f..b3826ab1 100644 --- a/include/boost/unordered/detail/hash_table.hpp +++ b/include/boost/unordered/detail/hash_table.hpp @@ -76,8 +76,9 @@ namespace boost { template std::size_t const prime_list_template::value[] = { - 53ul, 97ul, 193ul, 389ul, 769ul, - 1543ul, 3079ul, 6151ul, 12289ul, 24593ul, + 5ul, 11ul, 17ul, 29ul, 37ul, 53ul, 67ul, 79ul, + 97ul, 131ul, 193ul, 257ul, 389ul, 521ul, 769ul, + 1031ul, 1543ul, 2053ul, 3079ul, 6151ul, 12289ul, 24593ul, 49157ul, 98317ul, 196613ul, 393241ul, 786433ul, 1572869ul, 3145739ul, 6291469ul, 12582917ul, 25165843ul, 50331653ul, 100663319ul, 201326611ul, 402653189ul, 805306457ul, diff --git a/include/boost/unordered/detail/hash_table_impl.hpp b/include/boost/unordered/detail/hash_table_impl.hpp index a75d30d5..89302072 100644 --- a/include/boost/unordered/detail/hash_table_impl.hpp +++ b/include/boost/unordered/detail/hash_table_impl.hpp @@ -1469,6 +1469,21 @@ namespace boost { return need_to_reserve; } + // basic exception safety + bool reserve_for_insert(size_type n) + { + bool need_to_reserve = n >= max_load_; + // throws - basic: + if (need_to_reserve) { + size_type s = size(); + s = s + (s >> 1); + s = s > n ? s : n; + rehash_impl(min_buckets_for_size(s)); + } + BOOST_ASSERT(n < max_load_ || n > max_size()); + return need_to_reserve; + } + public: // no throw @@ -1720,7 +1735,7 @@ namespace boost { // reserve has basic exception safety if the hash function // throws, strong otherwise. - if(reserve(size() + 1)) + if(reserve_for_insert(size() + 1)) bucket = data_.bucket_ptr_from_hash(hash_value); // I'm relying on link_ptr not being invalidated by @@ -1750,7 +1765,7 @@ namespace boost { // reserve has basic exception safety if the hash function // throws, strong otherwise. - bucket_ptr base = reserve(size() + 1) ? + bucket_ptr base = reserve_for_insert(size() + 1) ? get_bucket(extract_key(a.get()->value_)) : it.bucket_; // Nothing after this point can throw @@ -1775,7 +1790,7 @@ namespace boost { } else { // Only require basic exception safety here - reserve(size() + distance); + reserve_for_insert(size() + distance); node_constructor a(data_.allocators_); for (; i != j; ++i) { @@ -1841,7 +1856,7 @@ namespace boost { // reserve has basic exception safety if the hash function // throws, strong otherwise. - if(reserve(size() + 1)) + if(reserve_for_insert(size() + 1)) bucket = data_.bucket_ptr_from_hash(hash_value); // Nothing after this point can throw. @@ -1880,7 +1895,7 @@ namespace boost { // reserve has basic exception safety if the hash function // throws, strong otherwise. - if(reserve(size() + 1)) + if(reserve_for_insert(size() + 1)) bucket = data_.bucket_ptr_from_hash(hash_value); // Nothing after this point can throw. @@ -1947,7 +1962,7 @@ namespace boost { // reserve has basic exception safety if the hash function // throws, strong otherwise. - if(reserve(size() + 1)) + if(reserve_for_insert(size() + 1)) bucket = data_.bucket_ptr_from_hash(hash_value); // Nothing after this point can throw. @@ -1978,7 +1993,7 @@ namespace boost { } else { // reserve has basic exception safety if the hash function // throws, strong otherwise. - if(reserve(size() + 1)) + if(reserve_for_insert(size() + 1)) bucket = data_.bucket_ptr_from_hash(hash_value); // Nothing after this point can throw. @@ -2047,7 +2062,7 @@ namespace boost { // reserve has basic exception safety if the hash function // throws, strong otherwise. if(size() + 1 >= max_load_) { - reserve(size() + insert_size(i, j)); + reserve_for_insert(size() + insert_size(i, j)); bucket = data_.bucket_ptr_from_hash(hash_value); }