Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r77066 - in trunk/boost/unordered: . detail
From: dnljms_at_[hidden]
Date: 2012-02-18 10:48:00


Author: danieljames
Date: 2012-02-18 10:47:59 EST (Sat, 18 Feb 2012)
New Revision: 77066
URL: http://svn.boost.org/trac/boost/changeset/77066

Log:
Unordered: Hashing policy for 64 bit computers.
Text files modified:
   trunk/boost/unordered/detail/buckets.hpp | 105 ++++++++++++++++++++++++++++++++++++---
   trunk/boost/unordered/detail/equivalent.hpp | 39 ++++++++------
   trunk/boost/unordered/detail/table.hpp | 50 +++++++++++-------
   trunk/boost/unordered/detail/unique.hpp | 39 ++++++++------
   trunk/boost/unordered/unordered_map.hpp | 6 +
   trunk/boost/unordered/unordered_set.hpp | 6 +
   6 files changed, 179 insertions(+), 66 deletions(-)

Modified: trunk/boost/unordered/detail/buckets.hpp
==============================================================================
--- trunk/boost/unordered/detail/buckets.hpp (original)
+++ trunk/boost/unordered/detail/buckets.hpp 2012-02-18 10:47:59 EST (Sat, 18 Feb 2012)
@@ -18,6 +18,7 @@
 #include <boost/type_traits/alignment_of.hpp>
 #include <boost/swap.hpp>
 #include <boost/assert.hpp>
+#include <boost/limits.hpp>
 
 #if defined(BOOST_MSVC)
 #pragma warning(push)
@@ -29,7 +30,8 @@
     template <typename Types> struct table;
     template <typename NodePointer> struct bucket;
     struct ptr_bucket;
- template <typename A, typename Bucket, typename Node> struct buckets;
+ template <typename A, typename Bucket, typename Node, typename Policy>
+ struct buckets;
 
     ///////////////////////////////////////////////////////////////////
     //
@@ -181,10 +183,95 @@
 
     ///////////////////////////////////////////////////////////////////
     //
+ // Hash Policy
+ //
+ // Don't really want buckets to derive from this, but will for now.
+
+ template <typename SizeT>
+ struct prime_policy
+ {
+ template <typename Hash, typename T>
+ static inline SizeT apply_hash(Hash const& hf, T const& x) {
+ return hf(x);
+ }
+
+ static inline SizeT to_bucket(SizeT bucket_count, SizeT hash) {
+ return hash % bucket_count;
+ }
+
+ static inline SizeT new_bucket_count(SizeT min) {
+ return boost::unordered::detail::next_prime(min);
+ }
+
+ static inline SizeT prev_bucket_count(SizeT max) {
+ return boost::unordered::detail::prev_prime(max);
+ }
+ };
+
+ template <typename SizeT>
+ struct mix64_policy
+ {
+ template <typename Hash, typename T>
+ static inline SizeT apply_hash(Hash const& hf, T const& x) {
+ SizeT key = hf(x);
+ key = (~key) + (key << 21); // key = (key << 21) - key - 1;
+ key = key ^ (key >> 24);
+ key = (key + (key << 3)) + (key << 8); // key * 265
+ key = key ^ (key >> 14);
+ key = (key + (key << 2)) + (key << 4); // key * 21
+ key = key ^ (key >> 28);
+ key = key + (key << 31);
+ return key;
+ }
+
+ static inline SizeT to_bucket(SizeT bucket_count, SizeT hash) {
+ return hash & (bucket_count - 1);
+ }
+
+ static inline SizeT new_bucket_count(SizeT min) {
+ if (min <= 4) return 4;
+ --min;
+ min |= min >> 1;
+ min |= min >> 2;
+ min |= min >> 4;
+ min |= min >> 8;
+ min |= min >> 16;
+ min |= min >> 32;
+ return min + 1;
+ }
+
+ static inline SizeT prev_bucket_count(SizeT max) {
+ max |= max >> 1;
+ max |= max >> 2;
+ max |= max >> 4;
+ max |= max >> 8;
+ max |= max >> 16;
+ max |= max >> 32;
+ return (max >> 1) + 1;
+ }
+ };
+
+ template <int digits, int radix>
+ struct pick_policy_impl {
+ typedef prime_policy<std::size_t> type;
+ };
+
+ template <>
+ struct pick_policy_impl<64, 2> {
+ typedef mix64_policy<std::size_t> type;
+ };
+
+ struct pick_policy :
+ pick_policy_impl<
+ std::numeric_limits<std::size_t>::digits,
+ std::numeric_limits<std::size_t>::radix> {};
+
+ ///////////////////////////////////////////////////////////////////
+ //
     // Buckets
 
- template <typename A, typename Bucket, typename Node>
- struct buckets
+ template <typename A, typename Bucket, typename Node, typename Policy>
+ struct buckets : Policy
     {
     private:
         buckets(buckets const&);
@@ -247,7 +334,7 @@
         std::size_t max_bucket_count() const
         {
             // -1 to account for the start bucket.
- return boost::unordered::detail::prev_prime(
+ return this->prev_bucket_count(
                 bucket_allocator_traits::max_size(bucket_alloc()) - 1);
         }
 
@@ -292,7 +379,7 @@
             if (!ptr) return 0;
 
             std::size_t count = 0;
- while(ptr && ptr->hash_ % this->bucket_count_ == index)
+ while(ptr && this->to_bucket(this->bucket_count_, ptr->hash_) == index)
             {
                 ++count;
                 ptr = static_cast<node_pointer>(ptr->next_);
@@ -487,7 +574,7 @@
             else
             {
                 bucket_pointer next_bucket = this->get_bucket(
- next->hash_ % this->bucket_count_);
+ this->to_bucket(this->bucket_count_, next->hash_));
 
                 if (next_bucket != bucket)
                 {
@@ -513,7 +600,7 @@
                     if (n == end) return;
     
                     std::size_t new_bucket_index =
- n->hash_ % this->bucket_count_;
+ this->to_bucket(this->bucket_count_, n->hash_);
                     if (bucket_index != new_bucket_index) {
                         bucket_index = new_bucket_index;
                         break;
@@ -529,7 +616,7 @@
                 if (n == end) break;
     
                 std::size_t new_bucket_index =
- n->hash_ % this->bucket_count_;
+ this->to_bucket(this->bucket_count_, n->hash_);
                 if (bucket_index != new_bucket_index) {
                     bucket_index = new_bucket_index;
                     this->get_bucket(bucket_index)->next_ = previous_pointer();
@@ -538,7 +625,7 @@
     
             // Finally fix the bucket containing the trailing node.
             if (n) {
- this->get_bucket(n->hash_ % this->bucket_count_)->next_
+ this->get_bucket(this->to_bucket(this->bucket_count_, n->hash_))->next_
                     = prev;
             }
         }

Modified: trunk/boost/unordered/detail/equivalent.hpp
==============================================================================
--- trunk/boost/unordered/detail/equivalent.hpp (original)
+++ trunk/boost/unordered/detail/equivalent.hpp 2012-02-18 10:47:59 EST (Sat, 18 Feb 2012)
@@ -136,6 +136,8 @@
 
         typedef boost::unordered::detail::grouped_table_impl<types> table;
         typedef boost::unordered::detail::set_extractor<value_type> extractor;
+
+ typedef boost::unordered::detail::pick_policy::type policy;
     };
 
     template <typename A, typename K, typename M, typename H, typename P>
@@ -160,6 +162,8 @@
         typedef boost::unordered::detail::grouped_table_impl<types> table;
         typedef boost::unordered::detail::map_extractor<key_type, value_type>
             extractor;
+
+ typedef boost::unordered::detail::pick_policy::type policy;
     };
 
     template <typename Types>
@@ -219,7 +223,7 @@
                 Key const& k,
                 Pred const& eq) const
         {
- std::size_t bucket_index = hash % this->bucket_count_;
+ std::size_t bucket_index = this->to_bucket(this->bucket_count_, hash);
             node_pointer n = this->get_start(bucket_index);
 
             for (;;)
@@ -234,7 +238,7 @@
                 }
                 else
                 {
- if (node_hash % this->bucket_count_ != bucket_index)
+ if (this->to_bucket(this->bucket_count_, node_hash) != bucket_index)
                         return node_pointer();
                 }
 
@@ -397,25 +401,25 @@
             if(pos) {
                 this->add_after_node(n, pos);
                 if (n->next_) {
- std::size_t next_bucket =
- static_cast<node_pointer>(n->next_)->hash_ %
- this->bucket_count_;
- if (next_bucket != hash % this->bucket_count_) {
+ std::size_t next_bucket = this->to_bucket(
+ this->bucket_count_,
+ static_cast<node_pointer>(n->next_)->hash_);
+ if (next_bucket != this->to_bucket(this->bucket_count_, hash)) {
                         this->get_bucket(next_bucket)->next_ = n;
                     }
                 }
             }
             else {
- bucket_pointer b = this->get_bucket(hash % this->bucket_count_);
+ bucket_pointer b = this->get_bucket(this->to_bucket(this->bucket_count_, hash));
 
                 if (!b->next_)
                 {
                     previous_pointer start_node = this->get_previous_start();
                     
                     if (start_node->next_) {
- this->get_bucket(
+ this->get_bucket(this->to_bucket(this->bucket_count_,
                             static_cast<node_pointer>(start_node->next_)->hash_
- % this->bucket_count_)->next_ = n;
+ ))->next_ = n;
                     }
     
                     b->next_ = start_node;
@@ -435,7 +439,7 @@
         node_pointer emplace_impl(node_constructor& a)
         {
             key_type const& k = this->get_key(a.value());
- std::size_t hash = this->hash_function()(k);
+ std::size_t hash = this->hash(k);
             node_pointer position = this->find_node(hash, k);
 
             // reserve has basic exception safety if the hash function
@@ -447,7 +451,7 @@
         void emplace_impl_no_rehash(node_constructor& a)
         {
             key_type const& k = this->get_key(a.value());
- std::size_t hash = this->hash_function()(k);
+ std::size_t hash = this->hash(k);
             this->add_node(a, hash,
                 this->find_node(hash, k));
         }
@@ -523,8 +527,8 @@
         {
             if(!this->size_) return 0;
 
- std::size_t hash = this->hash_function()(k);
- std::size_t bucket_index = hash % this->bucket_count_;
+ std::size_t hash = this->hash(k);
+ std::size_t bucket_index = this->to_bucket(this->bucket_count_, hash);
             bucket_pointer bucket = this->get_bucket(bucket_index);
 
             previous_pointer prev = bucket->next_;
@@ -535,7 +539,7 @@
                 if (!prev->next_) return 0;
                 std::size_t node_hash =
                     static_cast<node_pointer>(prev->next_)->hash_;
- if (node_hash % this->bucket_count_ != bucket_index)
+ if (this->to_bucket(this->bucket_count_, node_hash) != bucket_index)
                     return 0;
                 if (node_hash == hash &&
                     this->key_eq()(k, this->get_key(
@@ -560,7 +564,7 @@
             node_pointer next = static_cast<node_pointer>(r->next_);
 
             bucket_pointer bucket = this->get_bucket(
- r->hash_ % this->bucket_count_);
+ this->to_bucket(this->bucket_count_, r->hash_));
             previous_pointer prev = unlink_node(*bucket, r);
 
             this->fix_buckets(bucket, prev, next);
@@ -574,7 +578,7 @@
         {
             if (r1 == r2) return r2;
 
- std::size_t bucket_index = r1->hash_ % this->bucket_count_;
+ std::size_t bucket_index = this->to_bucket(this->bucket_count_, r1->hash_);
             previous_pointer prev = unlink_nodes(
                 *this->get_bucket(bucket_index), r1, r2);
             this->fix_buckets_range(bucket_index, prev, r1, r2);
@@ -809,7 +813,8 @@
         static previous_pointer place_in_bucket(buckets& dst,
                 previous_pointer prev, node_pointer end)
         {
- bucket_pointer b = dst.get_bucket(end->hash_ % dst.bucket_count_);
+ bucket_pointer b = dst.get_bucket(dst.to_bucket(
+ dst.bucket_count_, end->hash_));
 
             if (!b->next_) {
                 b->next_ = static_cast<node_pointer>(prev);

Modified: trunk/boost/unordered/detail/table.hpp
==============================================================================
--- trunk/boost/unordered/detail/table.hpp (original)
+++ trunk/boost/unordered/detail/table.hpp 2012-02-18 10:47:59 EST (Sat, 18 Feb 2012)
@@ -24,15 +24,16 @@
     template <typename NodePointer, typename Value> struct iterator;
     template <typename ConstNodePointer, typename NodePointer,
         typename Value> struct c_iterator;
- template <typename NodePointer, typename Value> struct l_iterator;
+ template <typename NodePointer, typename Value, typename Policy>
+ struct l_iterator;
     template <typename ConstNodePointer, typename NodePointer,
- typename Value> struct cl_iterator;
+ typename Value, typename Policy> struct cl_iterator;
 
     // Local Iterators
     //
     // all no throw
 
- template <typename NodePointer, typename Value>
+ template <typename NodePointer, typename Value, typename Policy>
     struct l_iterator
         : public boost::iterator<
             std::forward_iterator_tag, Value, std::ptrdiff_t,
@@ -40,7 +41,7 @@
     {
 #if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
         template <typename ConstNodePointer, typename NodePointer2,
- typename Value2>
+ typename Value2, typename Policy2>
         friend struct boost::unordered::iterator_detail::cl_iterator;
     private:
 #endif
@@ -66,7 +67,8 @@
 
         l_iterator& operator++() {
             ptr_ = static_cast<node_pointer>(ptr_->next_);
- if (ptr_ && ptr_->hash_ % bucket_count_ != bucket_)
+ if (ptr_ && Policy::to_bucket(bucket_count_, ptr_->hash_)
+ != bucket_)
                 ptr_ = node_pointer();
             return *this;
         }
@@ -86,14 +88,15 @@
         }
     };
 
- template <typename ConstNodePointer, typename NodePointer, typename Value>
+ template <typename ConstNodePointer, typename NodePointer, typename Value,
+ typename Policy>
     struct cl_iterator
         : public boost::iterator<
             std::forward_iterator_tag, Value, std::ptrdiff_t,
             ConstNodePointer, Value const&>
     {
         friend struct boost::unordered::iterator_detail::l_iterator
- <NodePointer, Value>;
+ <NodePointer, Value, Policy>;
     private:
 
         typedef NodePointer node_pointer;
@@ -109,7 +112,7 @@
             ptr_(x), bucket_(b), bucket_count_(c) {}
 
         cl_iterator(boost::unordered::iterator_detail::l_iterator<
- NodePointer, Value> const& x) :
+ NodePointer, Value, Policy> const& x) :
             ptr_(x.ptr_), bucket_(x.bucket_), bucket_count_(x.bucket_count_)
         {}
 
@@ -124,7 +127,8 @@
 
         cl_iterator& operator++() {
             ptr_ = static_cast<node_pointer>(ptr_->next_);
- if (ptr_ && ptr_->hash_ % bucket_count_ != bucket_)
+ if (ptr_ && Policy::to_bucket(bucket_count_, ptr_->hash_)
+ != bucket_)
                 ptr_ = node_pointer();
             return *this;
         }
@@ -302,7 +306,8 @@
         boost::unordered::detail::buckets<
             typename Types::allocator,
             typename Types::bucket,
- typename Types::node>,
+ typename Types::node,
+ typename Types::policy>,
         boost::unordered::detail::functions<
             typename Types::hasher,
             typename Types::key_equal>
@@ -318,6 +323,7 @@
         typedef typename Types::value_type value_type;
         typedef typename Types::table table_impl;
         typedef typename Types::link_pointer link_pointer;
+ typedef typename Types::policy policy;
 
         typedef boost::unordered::detail::functions<
             typename Types::hasher,
@@ -326,7 +332,8 @@
         typedef boost::unordered::detail::buckets<
             typename Types::allocator,
             typename Types::bucket,
- typename Types::node> buckets;
+ typename Types::node,
+ typename Types::policy> buckets;
 
         typedef typename buckets::node_allocator node_allocator;
         typedef typename buckets::node_allocator_traits node_allocator_traits;
@@ -338,9 +345,9 @@
         typedef boost::unordered::iterator_detail::
             c_iterator<const_node_pointer, node_pointer, value_type> c_iterator;
         typedef boost::unordered::iterator_detail::
- l_iterator<node_pointer, value_type> l_iterator;
+ l_iterator<node_pointer, value_type, policy> l_iterator;
         typedef boost::unordered::iterator_detail::
- cl_iterator<const_node_pointer, node_pointer, value_type>
+ cl_iterator<const_node_pointer, node_pointer, value_type, policy>
             cl_iterator;
 
         // Members
@@ -395,7 +402,7 @@
             // Or from rehash post-condition:
             // count > size / mlf_
 
- return boost::unordered::detail::next_prime(
+ return this->new_bucket_count(
                 boost::unordered::detail::double_to_size(floor(
                     static_cast<double>(size) /
                     static_cast<double>(mlf_))) + 1);
@@ -408,7 +415,7 @@
                 hasher const& hf,
                 key_equal const& eq,
                 node_allocator const& a) :
- buckets(a, boost::unordered::detail::next_prime(num_buckets)),
+ buckets(a, this->new_bucket_count(num_buckets)),
             functions(hf, eq),
             mlf_(1.0f),
             max_load_(0)
@@ -586,6 +593,11 @@
             return extractor::extract(x);
         }
 
+ std::size_t hash(key_type const& k) const
+ {
+ return this->apply_hash(this->hash_function(), k);
+ }
+
         // Find Node
 
         template <typename Key, typename Hash, typename Pred>
@@ -596,7 +608,7 @@
         {
             if (!this->size_) return node_pointer();
             return static_cast<table_impl const*>(this)->
- find_node_impl(hash_function(k), k, eq);
+ find_node_impl(this->apply_hash(hash_function, k), k, eq);
         }
 
         node_pointer find_node(
@@ -612,7 +624,7 @@
         {
             if (!this->size_) return node_pointer();
             return static_cast<table_impl const*>(this)->
- find_node_impl(this->hash_function()(k), k, this->key_eq());
+ find_node_impl(this->hash(k), k, this->key_eq());
         }
 
         node_pointer find_matching_node(node_pointer n) const
@@ -666,10 +678,10 @@
 
         if(!this->size_) {
             if(this->buckets_) this->delete_buckets();
- this->bucket_count_ = next_prime(min_buckets);
+ this->bucket_count_ = this->new_bucket_count(min_buckets);
         }
         else {
- min_buckets = next_prime((std::max)(min_buckets,
+ min_buckets = this->new_bucket_count((std::max)(min_buckets,
                 boost::unordered::detail::double_to_size(floor(
                     static_cast<double>(this->size_) /
                     static_cast<double>(mlf_))) + 1));

Modified: trunk/boost/unordered/detail/unique.hpp
==============================================================================
--- trunk/boost/unordered/detail/unique.hpp (original)
+++ trunk/boost/unordered/detail/unique.hpp 2012-02-18 10:47:59 EST (Sat, 18 Feb 2012)
@@ -132,6 +132,8 @@
 
         typedef boost::unordered::detail::table_impl<types> table;
         typedef boost::unordered::detail::set_extractor<value_type> extractor;
+
+ typedef boost::unordered::detail::pick_policy::type policy;
     };
 
     template <typename A, typename K, typename M, typename H, typename P>
@@ -156,6 +158,8 @@
         typedef boost::unordered::detail::table_impl<types> table;
         typedef boost::unordered::detail::map_extractor<key_type, value_type>
             extractor;
+
+ typedef boost::unordered::detail::pick_policy::type policy;
     };
 
     template <typename Types>
@@ -217,7 +221,7 @@
                 Key const& k,
                 Pred const& eq) const
         {
- std::size_t bucket_index = hash % this->bucket_count_;
+ std::size_t bucket_index = this->to_bucket(this->bucket_count_, hash);
             node_pointer n = this->get_start(bucket_index);
 
             for (;;)
@@ -232,7 +236,7 @@
                 }
                 else
                 {
- if (node_hash % this->bucket_count_ != bucket_index)
+ if (this->to_bucket(this->bucket_count_, node_hash) != bucket_index)
                         return node_pointer();
                 }
 
@@ -298,16 +302,16 @@
             node_pointer n = a.release();
             n->hash_ = hash;
     
- bucket_pointer b = this->get_bucket(hash % this->bucket_count_);
+ bucket_pointer b = this->get_bucket(this->to_bucket(this->bucket_count_, hash));
 
             if (!b->next_)
             {
                 previous_pointer start_node = this->get_previous_start();
                 
                 if (start_node->next_) {
- this->get_bucket(
- static_cast<node_pointer>(start_node->next_)->hash_ %
- this->bucket_count_)->next_ = n;
+ this->get_bucket(this->to_bucket(this->bucket_count_,
+ static_cast<node_pointer>(start_node->next_)->hash_)
+ )->next_ = n;
                 }
 
                 b->next_ = start_node;
@@ -328,7 +332,7 @@
         {
             typedef typename value_type::second_type mapped_type;
     
- std::size_t hash = this->hash_function()(k);
+ std::size_t hash = this->hash(k);
             node_pointer pos = this->find_node(hash, k);
     
             if (pos) return pos->value();
@@ -389,7 +393,7 @@
         emplace_return emplace_impl(key_type const& k,
             BOOST_UNORDERED_EMPLACE_ARGS)
         {
- std::size_t hash = this->hash_function()(k);
+ std::size_t hash = this->hash(k);
             node_pointer pos = this->find_node(hash, k);
     
             if (pos) return emplace_return(iterator(pos), false);
@@ -409,7 +413,7 @@
         emplace_return emplace_impl_with_node(node_constructor& a)
         {
             key_type const& k = this->get_key(a.value());
- std::size_t hash = this->hash_function()(k);
+ std::size_t hash = this->hash(k);
             node_pointer pos = this->find_node(hash, k);
 
             if (pos) return emplace_return(iterator(pos), false);
@@ -473,7 +477,7 @@
         void insert_range_empty(node_constructor& a, key_type const& k,
             InputIt i, InputIt j)
         {
- std::size_t hash = this->hash_function()(k);
+ std::size_t hash = this->hash(k);
             a.construct_node();
             a.construct_value2(*i);
             this->reserve_for_insert(this->size_ +
@@ -486,7 +490,7 @@
             InputIt i, InputIt j)
         {
             // No side effects in this initial code
- std::size_t hash = this->hash_function()(k);
+ std::size_t hash = this->hash(k);
             node_pointer pos = this->find_node(hash, k);
     
             if (!pos) {
@@ -523,8 +527,8 @@
         {
             if(!this->size_) return 0;
 
- std::size_t hash = this->hash_function()(k);
- std::size_t bucket_index = hash % this->bucket_count_;
+ std::size_t hash = this->hash(k);
+ std::size_t bucket_index = this->to_bucket(this->bucket_count_, hash);
             bucket_pointer bucket = this->get_bucket(bucket_index);
 
             previous_pointer prev = bucket->next_;
@@ -535,7 +539,7 @@
                 if (!prev->next_) return 0;
                 std::size_t node_hash =
                     static_cast<node_pointer>(prev->next_)->hash_;
- if (node_hash % this->bucket_count_ != bucket_index)
+ if (this->to_bucket(this->bucket_count_, node_hash) != bucket_index)
                     return 0;
                 if (node_hash == hash &&
                         this->key_eq()(k, this->get_key(
@@ -557,7 +561,7 @@
             node_pointer next = static_cast<node_pointer>(r->next_);
 
             bucket_pointer bucket = this->get_bucket(
- r->hash_ % this->bucket_count_);
+ this->to_bucket(this->bucket_count_, r->hash_));
             previous_pointer prev = unlink_node(*bucket, r);
 
             this->fix_buckets(bucket, prev, next);
@@ -571,7 +575,7 @@
         {
             if (r1 == r2) return r2;
 
- std::size_t bucket_index = r1->hash_ % this->bucket_count_;
+ std::size_t bucket_index = this->to_bucket(this->bucket_count_, r1->hash_);
             previous_pointer prev = unlink_nodes(
                 *this->get_bucket(bucket_index), r1, r2);
             this->fix_buckets_range(bucket_index, prev, r1, r2);
@@ -689,7 +693,8 @@
                 previous_pointer prev)
         {
             node_pointer n = static_cast<node_pointer>(prev->next_);
- bucket_pointer b = dst.get_bucket(n->hash_ % dst.bucket_count_);
+ bucket_pointer b = dst.get_bucket(dst.to_bucket(dst.bucket_count_,
+ n->hash_));
 
             if (!b->next_) {
                 b->next_ = prev;

Modified: trunk/boost/unordered/unordered_map.hpp
==============================================================================
--- trunk/boost/unordered/unordered_map.hpp (original)
+++ trunk/boost/unordered/unordered_map.hpp 2012-02-18 10:47:59 EST (Sat, 18 Feb 2012)
@@ -465,7 +465,8 @@
 
         size_type bucket(const key_type& k) const
         {
- return table_.hash_function()(k) % table_.bucket_count_;
+ return table_.to_bucket(table_.bucket_count_,
+ table_.hash(k));
         }
 
         local_iterator begin(size_type n)
@@ -946,7 +947,8 @@
 
         size_type bucket(const key_type& k) const
         {
- return table_.hash_function()(k) % table_.bucket_count_;
+ return table_.to_bucket(table_.bucket_count_,
+ table_.hash(k));
         }
 
         local_iterator begin(size_type n)

Modified: trunk/boost/unordered/unordered_set.hpp
==============================================================================
--- trunk/boost/unordered/unordered_set.hpp (original)
+++ trunk/boost/unordered/unordered_set.hpp 2012-02-18 10:47:59 EST (Sat, 18 Feb 2012)
@@ -450,7 +450,8 @@
 
         size_type bucket(const key_type& k) const
         {
- return table_.hash_function()(k) % table_.bucket_count_;
+ return table_.to_bucket(table_.bucket_count_,
+ table_.hash(k));
         }
 
         local_iterator begin(size_type n)
@@ -921,7 +922,8 @@
 
         size_type bucket(const key_type& k) const
         {
- return table_.hash_function()(k) % table_.bucket_count_;
+ return table_.to_bucket(table_.bucket_count_,
+ table_.hash(k));
         }
 
         local_iterator begin(size_type n)


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk