hashtable

来自「Mac OS X 10.4.9 for x86 Source Code gcc」· 代码 · 共 1,432 行 · 第 1/4 页

TXT
1,432
字号
    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 copy_code (hash_node<Value, false>*, const hash_node<Value, false>*) const { }  void m_swap(hash_code_base& x) {    m_extract.m_swap(x);    m_eq.m_swap(x);    m_ranged_hash.m_swap(x);  }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 copy_code (hash_node<Value, false>*, const hash_node<Value, false>*) const { }  void m_swap(hash_code_base& x) {    m_extract.m_swap(x);    m_eq.m_swap(x);    m_h1.m_swap(x);    m_h2.m_swap(x);  }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 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) {    m_extract.m_swap(x);    m_eq.m_swap(x);    m_h1.m_swap(x);    m_h2.m_swap(x);  }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.// mutable_iterators: bool.  true if hashtable::iterator is a mutable// iterator, false if iterator and const_iterator are both const // iterators.  This is true for unordered_map and unordered_multimap,// false for unordered_set and unordered_multiset.// unique_keys: bool.  true if the return value of hashtable::count(k)

⌨️ 快捷键说明

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