dense_hash_map.h
上传用户:market2
上传日期:2018-11-18
资源大小:18786k
文件大小:10k
源码类别:

外挂编程

开发平台:

Windows_Unix

  1. // Copyright (c) 2005, Google Inc.
  2. // All rights reserved.
  3. // 
  4. // Redistribution and use in source and binary forms, with or without
  5. // modification, are permitted provided that the following conditions are
  6. // met:
  7. // 
  8. //     * Redistributions of source code must retain the above copyright
  9. // notice, this list of conditions and the following disclaimer.
  10. //     * Redistributions in binary form must reproduce the above
  11. // copyright notice, this list of conditions and the following disclaimer
  12. // in the documentation and/or other materials provided with the
  13. // distribution.
  14. //     * Neither the name of Google Inc. nor the names of its
  15. // contributors may be used to endorse or promote products derived from
  16. // this software without specific prior written permission.
  17. // 
  18. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  19. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  20. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  21. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  22. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  23. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  24. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  25. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  26. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  28. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29. // ----
  30. // Author: Craig Silverstein
  31. //
  32. // This is just a very thin wrapper over densehashtable.h, just
  33. // like sgi stl's stl_hash_map is a very thin wrapper over
  34. // stl_hashtable.  The major thing we define is operator[], because
  35. // we have a concept of a data_type which stl_hashtable doesn't
  36. // (it only has a key and a value).
  37. //
  38. // NOTE: this is exactly like sparse_hash_map.h, with the word
  39. // "sparse" replaced by "dense", except for the addition of
  40. // set_empty_key().
  41. //
  42. //   YOU MUST CALL SET_EMPTY_KEY() IMMEDIATELY AFTER CONSTRUCTION.
  43. //
  44. // Otherwise your program will die in mysterious ways.
  45. //
  46. // In other respects, we adhere mostly to the STL semantics for
  47. // hash-map.  One important exception is that insert() invalidates
  48. // iterators entirely.  On the plus side, though, erase() doesn't
  49. // invalidate iterators at all, or even change the ordering of elements.
  50. //
  51. // Here are a few "power user" tips:
  52. //
  53. //    1) set_deleted_key():
  54. //         If you want to use erase() you must call set_deleted_key(),
  55. //         in addition to set_empty_key(), after construction.
  56. //         The deleted and empty keys must differ.
  57. //
  58. //    2) resize(0):
  59. //         When an item is deleted, its memory isn't freed right
  60. //         away.  This allows you to iterate over a hashtable,
  61. //         and call erase(), without invalidating the iterator.
  62. //         To force the memory to be freed, call resize(0).
  63. //
  64. // Guide to what kind of hash_map to use:
  65. //   (1) dense_hash_map: fastest, uses the most memory
  66. //   (2) sparse_hash_map: slowest, uses the least memory
  67. //   (3) hash_map (STL): in the middle
  68. // Typically I use sparse_hash_map when I care about space and/or when
  69. // I need to save the hashtable on disk.  I use hash_map otherwise.  I
  70. // don't personally use dense_hash_map ever; the only use of
  71. // dense_hash_map I know of is to work around malloc() bugs in some
  72. // systems (dense_hash_map has a particularly simple allocation scheme).
  73. //
  74. // - dense_hash_map has, typically, a factor of 2 memory overhead (if your
  75. //   data takes up X bytes, the hash_map uses X more bytes in overhead).
  76. // - sparse_hash_map has about 2 bits overhead per entry.
  77. // - sparse_hash_map can be 3-7 times slower than the others for lookup and,
  78. //   especially, inserts.  See time_hash_map.cc for details.
  79. //
  80. // See /usr/(local/)?doc/sparsehash-0.1/dense_hash_map.html
  81. // for information about how to use this class.
  82. #ifndef _DENSE_HASH_MAP_H_
  83. #define _DENSE_HASH_MAP_H_
  84. #include "sparseconfig.h"
  85. #include <stdio.h>                   // for FILE * in read()/write()
  86. #include <algorithm>                 // for the default template args
  87. #include <functional>                // for equal_to
  88. #include <memory>                    // for alloc<>
  89. #include <utility>                   // for pair<>
  90. #include HASH_FUN_H                  // defined in sparseconfig.h
  91. #include "densehashtable.h"
  92. _START_GOOGLE_NAMESPACE_
  93. using STL_NAMESPACE::pair;
  94. template <class Key, class T,
  95.           class HashFcn = HASH_NAMESPACE::hash<Key>,
  96.           class EqualKey = STL_NAMESPACE::equal_to<Key>,
  97.           class Alloc = STL_NAMESPACE::allocator<T> >
  98. class dense_hash_map {
  99.  private:
  100.   // Apparently select1st is not stl-standard, so we define our own
  101.   struct SelectKey {
  102.     const Key& operator()(const pair<const Key, T>& p) const {
  103.       return p.first;
  104.     }
  105.   };
  106.   // The actual data
  107.   typedef dense_hashtable<pair<const Key, T>, Key, HashFcn,
  108.                           SelectKey, EqualKey, Alloc> ht;
  109.   ht rep;
  110.  public:
  111.   typedef typename ht::key_type key_type;
  112.   typedef T data_type;
  113.   typedef T mapped_type;
  114.   typedef typename ht::value_type value_type;
  115.   typedef typename ht::hasher hasher;
  116.   typedef typename ht::key_equal key_equal;
  117.   typedef typename ht::size_type size_type;
  118.   typedef typename ht::difference_type difference_type;
  119.   typedef typename ht::pointer pointer;
  120.   typedef typename ht::const_pointer const_pointer;
  121.   typedef typename ht::reference reference;
  122.   typedef typename ht::const_reference const_reference;
  123.   typedef typename ht::iterator iterator;
  124.   typedef typename ht::const_iterator const_iterator;
  125.   // Iterator functions
  126.   iterator begin()                    { return rep.begin(); }
  127.   iterator end()                      { return rep.end(); }
  128.   const_iterator begin() const        { return rep.begin(); }
  129.   const_iterator end() const          { return rep.end(); }
  130.   // Accessor functions
  131.   hasher hash_funct() const { return rep.hash_funct(); }
  132.   key_equal key_eq() const  { return rep.key_eq(); }
  133.   // Constructors
  134.   explicit dense_hash_map(size_type n = 0,
  135.                           const hasher& hf = hasher(),
  136.                           const key_equal& eql = key_equal())
  137.     : rep(n, hf, eql) { }
  138.   template <class InputIterator>
  139.   dense_hash_map(InputIterator f, InputIterator l,
  140.                  size_type n = 0,
  141.                  const hasher& hf = hasher(),
  142.                  const key_equal& eql = key_equal()) {
  143.     rep.insert(f, l);
  144.   }
  145.   // We use the default copy constructor
  146.   // We use the default operator=()
  147.   // We use the default destructor
  148.   void clear()                        { rep.clear(); }
  149.   // This clears the hash map without resizing it down to the minimum
  150.   // bucket count, but rather keeps the number of buckets constant
  151.   void clear_no_resize()              { rep.clear_no_resize(); }
  152.   void swap(dense_hash_map& hs)       { rep.swap(hs.rep); }
  153.   // Functions concerning size
  154.   size_type size() const              { return rep.size(); }
  155.   size_type max_size() const          { return rep.max_size(); }
  156.   bool empty() const                  { return rep.empty(); }
  157.   size_type bucket_count() const      { return rep.bucket_count(); }
  158.   size_type max_bucket_count() const  { return rep.max_bucket_count(); }
  159.   void resize(size_type hint)         { rep.resize(hint); }
  160.   // Lookup routines
  161.   iterator find(const key_type& key)                 { return rep.find(key); }
  162.   const_iterator find(const key_type& key) const     { return rep.find(key); }
  163.   data_type& operator[](const key_type& key) {       // This is our value-add!
  164.     iterator it = find(key);
  165.     if (it != end()) {
  166.       return it->second;
  167.     } else {
  168.       return insert(value_type(key, data_type())).first->second;
  169.     }
  170.   }
  171.   size_type count(const key_type& key) const         { return rep.count(key); }
  172.   pair<iterator, iterator> equal_range(const key_type& key) {
  173.     return rep.equal_range(key);
  174.   }
  175.   pair<const_iterator, const_iterator> equal_range(const key_type& key) const {
  176.     return rep.equal_range(key);
  177.   }
  178.   // Insertion routines
  179.   pair<iterator, bool> insert(const value_type& obj) { return rep.insert(obj); }
  180.   template <class InputIterator>
  181.   void insert(InputIterator f, InputIterator l)      { rep.insert(f, l); }
  182.   void insert(const_iterator f, const_iterator l)    { rep.insert(f, l); }
  183.   // required for std::insert_iterator; the passed-in iterator is ignored
  184.   iterator insert(iterator, const value_type& obj)   { return insert(obj).first; }
  185.   // Deletion and empty routines
  186.   // THESE ARE NON-STANDARD!  I make you specify an "impossible" key
  187.   // value to identify deleted and empty buckets.  You can change the
  188.   // deleted key as time goes on, or get rid of it entirely to be insert-only.
  189.   void set_empty_key(const key_type& key)   {           // YOU MUST CALL THIS!
  190.     rep.set_empty_key(value_type(key, data_type()));    // rep wants a value
  191.   }
  192.   void set_deleted_key(const key_type& key)   {
  193.     rep.set_deleted_key(value_type(key, data_type()));  // rep wants a value
  194.   }
  195.   void clear_deleted_key()                    { rep.clear_deleted_key(); }
  196.   // These are standard
  197.   size_type erase(const key_type& key)               { return rep.erase(key); }
  198.   void erase(iterator it)                            { rep.erase(it); }
  199.   void erase(iterator f, iterator l)                 { rep.erase(f, l); }
  200.   // Comparison
  201.   bool operator==(const dense_hash_map& hs) const    { return rep == hs.rep; }
  202.   bool operator!=(const dense_hash_map& hs) const    { return rep != hs.rep; }
  203.   // I/O -- this is an add-on for writing metainformation to disk
  204.   bool write_metadata(FILE *fp)       { return rep.write_metadata(fp); }
  205.   bool read_metadata(FILE *fp)        { return rep.read_metadata(fp); }
  206.   bool write_nopointer_data(FILE *fp) { return rep.write_nopointer_data(fp); }
  207.   bool read_nopointer_data(FILE *fp)  { return rep.read_nopointer_data(fp); }
  208. };
  209. // We need a global swap as well
  210. template <class Key, class T, class HashFcn, class EqualKey, class Alloc>
  211. inline void swap(dense_hash_map<Key, T, HashFcn, EqualKey, Alloc>& hm1,
  212.                  dense_hash_map<Key, T, HashFcn, EqualKey, Alloc>& hm2) {
  213.   hm1.swap(hm2);
  214. }
  215. _END_GOOGLE_NAMESPACE_
  216. #endif /* _DENSE_HASH_MAP_H_ */