Here is the patch to fix the redundant rehash/reserve issue.
2012-11-07 François Dumont <fdum...@gcc.gnu.org>
PR libstdc++/54075
* include/bits/hashtable.h (_Hashtable<>::rehash): Reset hash
policy state if no rehash.
* testsuite/23_containers/unordered_set/modifiers/reserve.cc
(test02): New.
I had prepared and tested it in 4.7 branch but I can apply the same on
trunk.
Ok to commit ? If so, where ?
François
On 11/06/2012 10:33 PM, paolo.carlini at oracle dot com wrote:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54075
--- Comment #39 from Paolo Carlini <paolo.carlini at oracle dot com> 2012-11-06
21:33:57 UTC ---
Ok thanks. I guess depending on the complexity of the fixes we can apply some
only to mainline first and reconsider the 4_7 branch later. Please do your best
to work on both issues: we just entered Stage 3 thus no new features from now
on, we are all concentrated on bug fixes until the release.
Index: include/bits/hashtable.h
===================================================================
--- include/bits/hashtable.h (revision 193258)
+++ include/bits/hashtable.h (working copy)
@@ -1597,6 +1597,9 @@
// level.
_M_rehash_policy._M_prev_resize = 0;
}
+ else
+ // No rehash, restore previous state to keep a consistent state.
+ _M_rehash_policy._M_reset(__saved_state);
}
template<typename _Key, typename _Value,
Index: testsuite/23_containers/unordered_set/modifiers/reserve.cc
===================================================================
--- testsuite/23_containers/unordered_set/modifiers/reserve.cc (revision 193258)
+++ testsuite/23_containers/unordered_set/modifiers/reserve.cc (working copy)
@@ -40,8 +40,28 @@
}
}
+void test02()
+{
+ const int N = 1000;
+
+ typedef std::unordered_set<int> Set;
+ Set s;
+ s.reserve(N);
+ s.reserve(N);
+
+ std::size_t bkts = s.bucket_count();
+ for (int i = 0; i != N; ++i)
+ {
+ s.insert(i);
+ // As long as we insert less than the reserved number of elements we
+ // shouldn't experiment any rehash.
+ VERIFY( s.bucket_count() == bkts );
+ }
+}
+
int main()
{
test01();
+ test02();
return 0;
}