1*38fd1498Szrj // std::__detail definitions -*- C++ -*- 2*38fd1498Szrj 3*38fd1498Szrj // Copyright (C) 2007-2018 Free Software Foundation, Inc. 4*38fd1498Szrj // 5*38fd1498Szrj // This file is part of the GNU ISO C++ Library. This library is free 6*38fd1498Szrj // software; you can redistribute it and/or modify it under the 7*38fd1498Szrj // terms of the GNU General Public License as published by the 8*38fd1498Szrj // Free Software Foundation; either version 3, or (at your option) 9*38fd1498Szrj // any later version. 10*38fd1498Szrj 11*38fd1498Szrj // This library is distributed in the hope that it will be useful, 12*38fd1498Szrj // but WITHOUT ANY WARRANTY; without even the implied warranty of 13*38fd1498Szrj // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14*38fd1498Szrj // GNU General Public License for more details. 15*38fd1498Szrj 16*38fd1498Szrj // Under Section 7 of GPL version 3, you are granted additional 17*38fd1498Szrj // permissions described in the GCC Runtime Library Exception, version 18*38fd1498Szrj // 3.1, as published by the Free Software Foundation. 19*38fd1498Szrj 20*38fd1498Szrj // You should have received a copy of the GNU General Public License and 21*38fd1498Szrj // a copy of the GCC Runtime Library Exception along with this program; 22*38fd1498Szrj // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23*38fd1498Szrj // <http://www.gnu.org/licenses/>. 24*38fd1498Szrj 25*38fd1498Szrj #if __cplusplus < 201103L 26*38fd1498Szrj # error "hashtable_c++0x.cc must be compiled with -std=gnu++0x" 27*38fd1498Szrj #endif 28*38fd1498Szrj 29*38fd1498Szrj #include <initializer_list> 30*38fd1498Szrj #include <tuple> 31*38fd1498Szrj #include <ext/aligned_buffer.h> 32*38fd1498Szrj #include <ext/alloc_traits.h> 33*38fd1498Szrj #include <bits/hashtable_policy.h> 34*38fd1498Szrj 35*38fd1498Szrj namespace std _GLIBCXX_VISIBILITY(default) 36*38fd1498Szrj { 37*38fd1498Szrj _GLIBCXX_BEGIN_NAMESPACE_VERSION 38*38fd1498Szrj 39*38fd1498Szrj #include "../shared/hashtable-aux.cc" 40*38fd1498Szrj 41*38fd1498Szrj namespace __detail 42*38fd1498Szrj { 43*38fd1498Szrj // Return a prime no smaller than n. 44*38fd1498Szrj std::size_t _M_next_bkt(std::size_t __n) const45*38fd1498Szrj _Prime_rehash_policy::_M_next_bkt(std::size_t __n) const 46*38fd1498Szrj { 47*38fd1498Szrj // Optimize lookups involving the first elements of __prime_list. 48*38fd1498Szrj // (useful to speed-up, eg, constructors) 49*38fd1498Szrj static const unsigned char __fast_bkt[13] 50*38fd1498Szrj = { 2, 2, 3, 5, 5, 7, 7, 11, 11, 11, 11, 13, 13 }; 51*38fd1498Szrj 52*38fd1498Szrj if (__n <= 12) 53*38fd1498Szrj { 54*38fd1498Szrj _M_next_resize = 55*38fd1498Szrj __builtin_ceil(__fast_bkt[__n] * (long double)_M_max_load_factor); 56*38fd1498Szrj return __fast_bkt[__n]; 57*38fd1498Szrj } 58*38fd1498Szrj 59*38fd1498Szrj // Number of primes (without sentinel). 60*38fd1498Szrj constexpr auto __n_primes 61*38fd1498Szrj = sizeof(__prime_list) / sizeof(unsigned long) - 1; 62*38fd1498Szrj 63*38fd1498Szrj // Don't include the last prime in the search, so that anything 64*38fd1498Szrj // higher than the second-to-last prime returns a past-the-end 65*38fd1498Szrj // iterator that can be dereferenced to get the last prime. 66*38fd1498Szrj constexpr auto __last_prime = __prime_list + __n_primes - 1; 67*38fd1498Szrj 68*38fd1498Szrj // Look for 'n + 1' to make sure returned value will be greater than n. 69*38fd1498Szrj const unsigned long* __next_bkt = 70*38fd1498Szrj std::lower_bound(__prime_list + 6, __last_prime, __n + 1); 71*38fd1498Szrj 72*38fd1498Szrj if (__next_bkt == __last_prime) 73*38fd1498Szrj // Set next resize to the max value so that we never try to rehash again 74*38fd1498Szrj // as we already reach the biggest possible bucket number. 75*38fd1498Szrj // Note that it might result in max_load_factor not being respected. 76*38fd1498Szrj _M_next_resize = std::size_t(-1); 77*38fd1498Szrj else 78*38fd1498Szrj _M_next_resize = 79*38fd1498Szrj __builtin_ceil(*__next_bkt * (long double)_M_max_load_factor); 80*38fd1498Szrj 81*38fd1498Szrj return *__next_bkt; 82*38fd1498Szrj } 83*38fd1498Szrj 84*38fd1498Szrj // Finds the smallest prime p such that alpha p > __n_elt + __n_ins. 85*38fd1498Szrj // If p > __n_bkt, return make_pair(true, p); otherwise return 86*38fd1498Szrj // make_pair(false, 0). In principle this isn't very different from 87*38fd1498Szrj // _M_bkt_for_elements. 88*38fd1498Szrj 89*38fd1498Szrj // The only tricky part is that we're caching the element count at 90*38fd1498Szrj // which we need to rehash, so we don't have to do a floating-point 91*38fd1498Szrj // multiply for every insertion. 92*38fd1498Szrj 93*38fd1498Szrj std::pair<bool, std::size_t> 94*38fd1498Szrj _Prime_rehash_policy:: _M_need_rehash(std::size_t __n_bkt,std::size_t __n_elt,std::size_t __n_ins) const95*38fd1498Szrj _M_need_rehash(std::size_t __n_bkt, std::size_t __n_elt, 96*38fd1498Szrj std::size_t __n_ins) const 97*38fd1498Szrj { 98*38fd1498Szrj if (__n_elt + __n_ins >= _M_next_resize) 99*38fd1498Szrj { 100*38fd1498Szrj long double __min_bkts = (__n_elt + __n_ins) 101*38fd1498Szrj / (long double)_M_max_load_factor; 102*38fd1498Szrj if (__min_bkts >= __n_bkt) 103*38fd1498Szrj return std::make_pair(true, 104*38fd1498Szrj _M_next_bkt(std::max<std::size_t>(__builtin_floor(__min_bkts) + 1, 105*38fd1498Szrj __n_bkt * _S_growth_factor))); 106*38fd1498Szrj 107*38fd1498Szrj _M_next_resize 108*38fd1498Szrj = __builtin_floor(__n_bkt * (long double)_M_max_load_factor); 109*38fd1498Szrj return std::make_pair(false, 0); 110*38fd1498Szrj } 111*38fd1498Szrj else 112*38fd1498Szrj return std::make_pair(false, 0); 113*38fd1498Szrj } 114*38fd1498Szrj } // namespace __detail 115*38fd1498Szrj 116*38fd1498Szrj _GLIBCXX_END_NAMESPACE_VERSION 117*38fd1498Szrj } // namespace std 118