⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hashtable

📁 linux下编程用 编译软件
💻
📖 第 1 页 / 共 4 页
字号:
  template<int dummy>    struct X    {      static const int n_primes = 256;      static const unsigned long primes[n_primes + 1];    };  template<int dummy>    const int X<dummy>::n_primes;  template<int dummy>    const unsigned long X<dummy>::primes[n_primes + 1] =    {      2ul, 3ul, 5ul, 7ul, 11ul, 13ul, 17ul, 19ul, 23ul, 29ul, 31ul,      37ul, 41ul, 43ul, 47ul, 53ul, 59ul, 61ul, 67ul, 71ul, 73ul, 79ul,      83ul, 89ul, 97ul, 103ul, 109ul, 113ul, 127ul, 137ul, 139ul, 149ul,      157ul, 167ul, 179ul, 193ul, 199ul, 211ul, 227ul, 241ul, 257ul,      277ul, 293ul, 313ul, 337ul, 359ul, 383ul, 409ul, 439ul, 467ul,      503ul, 541ul, 577ul, 619ul, 661ul, 709ul, 761ul, 823ul, 887ul,      953ul, 1031ul, 1109ul, 1193ul, 1289ul, 1381ul, 1493ul, 1613ul,      1741ul, 1879ul, 2029ul, 2179ul, 2357ul, 2549ul, 2753ul, 2971ul,      3209ul, 3469ul, 3739ul, 4027ul, 4349ul, 4703ul, 5087ul, 5503ul,      5953ul, 6427ul, 6949ul, 7517ul, 8123ul, 8783ul, 9497ul, 10273ul,      11113ul, 12011ul, 12983ul, 14033ul, 15173ul, 16411ul, 17749ul,      19183ul, 20753ul, 22447ul, 24281ul, 26267ul, 28411ul, 30727ul,      33223ul, 35933ul, 38873ul, 42043ul, 45481ul, 49201ul, 53201ul,      57557ul, 62233ul, 67307ul, 72817ul, 78779ul, 85229ul, 92203ul,      99733ul, 107897ul, 116731ul, 126271ul, 136607ul, 147793ul,      159871ul, 172933ul, 187091ul, 202409ul, 218971ul, 236897ul,      256279ul, 277261ul, 299951ul, 324503ul, 351061ul, 379787ul,      410857ul, 444487ul, 480881ul, 520241ul, 562841ul, 608903ul,      658753ul, 712697ul, 771049ul, 834181ul, 902483ul, 976369ul,      1056323ul, 1142821ul, 1236397ul, 1337629ul, 1447153ul, 1565659ul,      1693859ul, 1832561ul, 1982627ul, 2144977ul, 2320627ul, 2510653ul,      2716249ul, 2938679ul, 3179303ul, 3439651ul, 3721303ul, 4026031ul,      4355707ul, 4712381ul, 5098259ul, 5515729ul, 5967347ul, 6456007ul,      6984629ul, 7556579ul, 8175383ul, 8844859ul, 9569143ul, 10352717ul,      11200489ul, 12117689ul, 13109983ul, 14183539ul, 15345007ul,      16601593ul, 17961079ul, 19431899ul, 21023161ul, 22744717ul,      24607243ul, 26622317ul, 28802401ul, 31160981ul, 33712729ul,      36473443ul, 39460231ul, 42691603ul, 46187573ul, 49969847ul,      54061849ul, 58488943ul, 63278561ul, 68460391ul, 74066549ul,      80131819ul, 86693767ul, 93793069ul, 101473717ul, 109783337ul,      118773397ul, 128499677ul, 139022417ul, 150406843ul, 162723577ul,      176048909ul, 190465427ul, 206062531ul, 222936881ul, 241193053ul,      260944219ul, 282312799ul, 305431229ul, 330442829ul, 357502601ul,      386778277ul, 418451333ul, 452718089ul, 489790921ul, 529899637ul,      573292817ul, 620239453ul, 671030513ul, 725980837ul, 785430967ul,      849749479ul, 919334987ul, 994618837ul, 1076067617ul, 1164186217ul,      1259520799ul, 1362662261ul, 1474249943ul, 1594975441ul,      1725587117ul, 1866894511ul, 2019773507ul, 2185171673ul,      2364114217ul, 2557710269ul, 2767159799ul, 2993761039ul,      3238918481ul, 3504151727ul, 3791104843ul, 4101556399ul,      4294967291ul,      4294967291ul // sentinel so we don't have to test result of lower_bound    };  inline  prime_rehash_policy::  prime_rehash_policy(float z)  : m_max_load_factor(z), m_growth_factor(2.f), m_next_resize(0)  { }  inline float  prime_rehash_policy::  max_load_factor() const  { return m_max_load_factor; }  // Return a prime no smaller than n.  inline std::size_t  prime_rehash_policy::  next_bkt(std::size_t n) const  {    const unsigned long* const last = X<0>::primes + X<0>::n_primes;    const unsigned long* p = std::lower_bound (X<0>::primes, last, n);    m_next_resize = static_cast<std::size_t>(std::ceil(*p * m_max_load_factor));    return *p;  }  // Return the smallest prime p such that alpha p >= n, where alpha  // is the load factor.  inline std::size_t  prime_rehash_policy::  bkt_for_elements(std::size_t n) const  {    const unsigned long* const last = X<0>::primes + X<0>::n_primes;    const float min_bkts = n / m_max_load_factor;    const unsigned long* p = std::lower_bound (X<0>::primes, last,					       min_bkts, lt());    m_next_resize = static_cast<std::size_t>(std::ceil(*p * m_max_load_factor));    return *p;  }  // Finds the smallest prime p such that alpha p > n_elt + n_ins.  // If p > n_bkt, return make_pair(true, p); otherwise return  // make_pair(false, 0).  In principle this isn't very different from   // bkt_for_elements.    // The only tricky part is that we're caching the element count at  // which we need to rehash, so we don't have to do a floating-point  // multiply for every insertion.    inline std::pair<bool, std::size_t>  prime_rehash_policy::  need_rehash(std::size_t n_bkt, std::size_t n_elt, std::size_t n_ins) const  {    if (n_elt + n_ins > m_next_resize)      {	float min_bkts = (float(n_ins) + float(n_elt)) / m_max_load_factor;	if (min_bkts > n_bkt)	  {	    min_bkts = std::max (min_bkts, m_growth_factor * n_bkt);	    const unsigned long* const last = X<0>::primes + X<0>::n_primes;	    const unsigned long* p = std::lower_bound (X<0>::primes, last,						       min_bkts, lt());	    m_next_resize = 	      static_cast<std::size_t>(std::ceil(*p * m_max_load_factor));	    return std::make_pair(true, *p);	  }	else 	  {	    m_next_resize = 	      static_cast<std::size_t>(std::ceil(n_bkt * m_max_load_factor));	    return std::make_pair(false, 0);	  }      }    else      return std::make_pair(false, 0);  }} // namespace Internal//----------------------------------------------------------------------// Base classes for std::tr1::hashtable.  We define these base classes// because in some cases we want to do different things depending on// the value of a policy class.  In some cases the policy class affects// which member functions and nested typedefs are defined; we handle that// by specializing base class templates.  Several of the base class templates// need to access other members of class template hashtable, so we use// the "curiously recurring template pattern" for them.namespace Internal{  // class template map_base.  If the hashtable has a value type of the  // form pair<T1, T2> and a key extraction policy that returns the  // first part of the pair, the hashtable gets a mapped_type typedef.  // If it satisfies those criteria and also has unique keys, then it  // also gets an operator[].    template<typename K, typename V, typename Ex, bool unique, typename Hashtable>    struct map_base { };	    template<typename K, typename Pair, typename Hashtable>    struct map_base<K, Pair, extract1st<Pair>, false, Hashtable>    {      typedef typename Pair::second_type mapped_type;    };  template<typename K, typename Pair, typename Hashtable>    struct map_base<K, Pair, extract1st<Pair>, true, Hashtable>    {      typedef typename Pair::second_type mapped_type;            mapped_type&      operator[](const K& k)      {	Hashtable* h = static_cast<Hashtable*>(this);	typename Hashtable::iterator it = 	  h->insert(std::make_pair(k, mapped_type())).first;	return it->second;      }    };  // class template rehash_base.  Give hashtable the max_load_factor  // functions iff the rehash policy is prime_rehash_policy.  template<typename RehashPolicy, typename Hashtable>    struct rehash_base { };  template<typename Hashtable>    struct rehash_base<prime_rehash_policy, Hashtable>    {      float      max_load_factor() const      {	const Hashtable* This = static_cast<const Hashtable*>(this);	return This->rehash_policy().max_load_factor();      }      void      max_load_factor(float z)      {	Hashtable* This = static_cast<Hashtable*>(this);	This->rehash_policy(prime_rehash_policy(z));          }    };  // Class template hash_code_base.  Encapsulates two policy issues that  // aren't quite orthogonal.  //   (1) the difference between using a ranged hash function and using  //       the combination of a hash function and a range-hashing function.  //       In the former case we don't have such things as hash codes, so  //       we have a dummy type as placeholder.  //   (2) Whether or not we cache hash codes.  Caching hash codes is  //       meaningless if we have a ranged hash function.  // We also put the key extraction and equality comparison function   // objects here, for convenience.    // Primary template: unused except as a hook for specializations.    template<typename Key, typename Value,	   typename ExtractKey, typename Equal,	   typename H1, typename H2, typename H,	   bool cache_hash_code>    struct hash_code_base;  // Specialization: ranged hash function, no caching hash codes.  H1  // and H2 are provided but ignored.  We define a dummy hash code type.  template<typename Key, typename Value,	   typename ExtractKey, typename Equal,	   typename H1, typename H2, typename H>    struct hash_code_base<Key, Value, ExtractKey, Equal, H1, H2, H, false>    {    protected:      hash_code_base(const ExtractKey& ex, const Equal& eq,		     const H1&, const H2&, const H& h)      : m_extract(ex), m_eq(eq), m_ranged_hash(h) { }      typedef void* hash_code_t;        hash_code_t      m_hash_code(const Key& k) const      { return 0; }        std::size_t      bucket_index(const Key& k, hash_code_t, std::size_t N) const      { return m_ranged_hash (k, N); }      std::size_t      bucket_index(const hash_node<Value, false>* p, std::size_t N) const      { return m_ranged_hash (m_extract (p->m_v), N); }        bool      compare(const Key& k, hash_code_t, hash_node<Value, false>* n) const      { return m_eq (k, m_extract(n->m_v)); }      void      store_code(hash_node<Value, false>*, hash_code_t) const      { }      void      copy_code(hash_node<Value, false>*, const hash_node<Value, false>*) const      { }            void      m_swap(hash_code_base& x)      {	std::swap(m_extract, x.m_extract);	std::swap(m_eq, x.m_eq);	std::swap(m_ranged_hash, x.m_ranged_hash);      }    protected:      ExtractKey m_extract;      Equal m_eq;      H m_ranged_hash;    };  // No specialization for ranged hash function while caching hash codes.  // That combination is meaningless, and trying to do it is an error.      // Specialization: ranged hash function, cache hash codes.  This  // combination is meaningless, so we provide only a declaration  // and no definition.    template<typename Key, typename Value,	    typename ExtractKey, typename Equal,	    typename H1, typename H2, typename H>    struct hash_code_base<Key, Value, ExtractKey, Equal, H1, H2, H, true>;  // Specialization: hash function and range-hashing function, no  // caching of hash codes.  H is provided but ignored.  Provides  // typedef and accessor required by TR1.    template<typename Key, typename Value,	   typename ExtractKey, typename Equal,	   typename H1, typename H2>    struct hash_code_base<Key, Value, ExtractKey, Equal, H1, H2,			  default_ranged_hash, false>    {      typedef H1 hasher;            hasher      hash_function() const      { return m_h1; }    protected:      hash_code_base(const ExtractKey& ex, const Equal& eq,		     const H1& h1, const H2& h2, const default_ranged_hash&)      : m_extract(ex), m_eq(eq), m_h1(h1), m_h2(h2) { }      typedef std::size_t hash_code_t;            hash_code_t      m_hash_code(const Key& k) const      { return m_h1(k); }            std::size_t      bucket_index(const Key&, hash_code_t c, std::size_t N) const      { return m_h2 (c, N); }      std::size_t      bucket_index(const hash_node<Value, false>* p, std::size_t N) const      { return m_h2 (m_h1 (m_extract (p->m_v)), N); }      bool      compare(const Key& k, hash_code_t, hash_node<Value, false>* n) const      { return m_eq (k, m_extract(n->m_v)); }      void      store_code(hash_node<Value, false>*, hash_code_t) const      { }      void      copy_code(hash_node<Value, false>*, const hash_node<Value, false>*) const      { }      void      m_swap(hash_code_base& x)      {	std::swap(m_extract, x.m_extract);	std::swap(m_eq, x.m_eq);	std::swap(m_h1, x.m_h1);	std::swap(m_h2, x.m_h2);      }    protected:      ExtractKey m_extract;      Equal m_eq;      H1 m_h1;      H2 m_h2;    };  // Specialization: hash function and range-hashing function,   // caching hash codes.  H is provided but ignored.  Provides  // typedef and accessor required by TR1.  template<typename Key, typename Value,	   typename ExtractKey, typename Equal,	   typename H1, typename H2>    struct hash_code_base<Key, Value, ExtractKey, Equal, H1, H2,			  default_ranged_hash, true>    {      typedef H1 hasher;            hasher      hash_function() const      { return m_h1; }    protected:      hash_code_base(const ExtractKey& ex, const Equal& eq,		     const H1& h1, const H2& h2, const default_ranged_hash&)      : m_extract(ex), m_eq(eq), m_h1(h1), m_h2(h2) { }      typedef std::size_t hash_code_t;        hash_code_t      m_hash_code(const Key& k) const      { return m_h1(k); }        std::size_t      bucket_index(const Key&, hash_code_t c, std::size_t N) const      { return m_h2 (c, N); }      std::size_t      bucket_index(const hash_node<Value, true>* p, std::size_t N) const      { return m_h2 (p->hash_code, N); }      bool      compare(const Key& k, hash_code_t c, hash_node<Value, true>* n) const      { return c == n->hash_code && m_eq(k, m_extract(n->m_v)); }      void      store_code(hash_node<Value, true>* n, hash_code_t c) const      { n->hash_code = c; }      void      copy_code(hash_node<Value, true>* to,		const hash_node<Value, true>* from) const      { to->hash_code = from->hash_code; }      void      m_swap(hash_code_base& x)      {	std::swap(m_extract, x.m_extract);	std::swap(m_eq, x.m_eq);	std::swap(m_h1, x.m_h1);	std::swap(m_h2, x.m_h2);      }          protected:      ExtractKey m_extract;      Equal m_eq;      H1 m_h1;      H2 m_h2;    };} // namespace internalnamespace std{ namespace tr1{  //----------------------------------------------------------------------  // Class template hashtable, class definition.    // Meaning of class template hashtable's template parameters    // Key and Value: arbitrary CopyConstructible types.    // Allocator: an allocator type ([lib.allocator.requirements]) whose  // value type is Value.    // ExtractKey: function object that takes a object of type Value  // and returns a value of type Key.    // Equal: function object that takes two objects of type k and returns  // a bool-like value that is true if the two objects are considered equal.    // H1: the hash function.  A unary function object with argument type  // Key and result type size_t.  Return values should be distributed  // over the entire range [0, numeric_limits<size_t>:::max()].    // H2: the range-hashing function (in the terminology of Tavori and  // Dreizin).  A binary function object whose argument types and result  // type are all size_t.  Given arguments r and N, the return value is  // in the range [0, N).    // H: the ranged hash function (Tavori and Dreizin). A binary function  // whose argument types are Key and size_t and whose result type is  // size_t.  Given arguments k and N, the return value is in the range  // [0, N).  Default: h(k, N) = h2(h1(k), N).  If H is anything other  // than the default, H1 and H2 are ignored.    // RehashPolicy: Policy class with three members, all of which govern  // the bucket count. n_bkt(n) returns a bucket count no smaller  // than n.  bkt_for_elements(n) returns a bucket count appropriate  // for an element count of n.  need_rehash(n_bkt, n_elt, n_ins)  // determines whether, if the current bucket count is n_bkt and the  // current element count is n_elt, we need to increase the bucket  // count.  If so, returns make_pair(true, n), where n is the new  // bucket count.  If not, returns make_pair(false, <anything>).    // ??? Right now it is hard-wired that the number of buckets never  // shrinks.  Should we allow RehashPolicy to change that?    // cache_hash_code: bool.  true if we store the value of the hash  // function along with the value.  This is a time-space tradeoff.  // Storing it may improve lookup speed by reducing the number of times  // we need to call the Equal function.    // constant_iterators: bool.  true if iterator and const_iterator are  // both constant iterator types.  This is true for unordered_set and  // unordered_multiset, false for unordered_map and unordered_multimap.    // unique_keys: bool.  true if the return value of hashtable::count(k)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -