google_hash 0.6.2 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. data/README +61 -27
  2. data/Rakefile +4 -1
  3. data/TODO +5 -0
  4. data/VERSION +1 -1
  5. data/changelog +3 -0
  6. data/ext/extconf.rb +10 -5
  7. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/AUTHORS +0 -0
  8. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/COPYING +0 -0
  9. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/ChangeLog +47 -0
  10. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/INSTALL +0 -0
  11. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/Makefile.am +29 -14
  12. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/Makefile.in +77 -42
  13. data/ext/sparsehash-1.8.1/NEWS +71 -0
  14. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/README +0 -0
  15. data/ext/{sparsehash-1.5.2/README.windows → sparsehash-1.8.1/README_windows.txt} +25 -25
  16. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/TODO +0 -0
  17. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/aclocal.m4 +0 -0
  18. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/compile +0 -0
  19. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/config.guess +0 -0
  20. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/config.sub +0 -0
  21. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/configure +3690 -4560
  22. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/configure.ac +1 -1
  23. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/depcomp +0 -0
  24. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/doc/dense_hash_map.html +65 -5
  25. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/doc/dense_hash_set.html +65 -5
  26. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/doc/designstyle.css +0 -0
  27. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/doc/implementation.html +11 -5
  28. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/doc/index.html +0 -0
  29. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/doc/performance.html +0 -0
  30. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/doc/sparse_hash_map.html +65 -5
  31. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/doc/sparse_hash_set.html +65 -5
  32. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/doc/sparsetable.html +0 -0
  33. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/experimental/Makefile +0 -0
  34. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/experimental/README +0 -0
  35. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/experimental/example.c +0 -0
  36. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/experimental/libchash.c +0 -0
  37. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/experimental/libchash.h +0 -0
  38. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/google-sparsehash.sln +17 -1
  39. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/install-sh +0 -0
  40. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/m4/acx_pthread.m4 +0 -0
  41. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/m4/google_namespace.m4 +0 -0
  42. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/m4/namespaces.m4 +0 -0
  43. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/m4/stl_hash.m4 +0 -0
  44. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/m4/stl_hash_fun.m4 +0 -0
  45. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/m4/stl_namespace.m4 +0 -0
  46. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/missing +0 -0
  47. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/mkinstalldirs +0 -0
  48. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/packages/deb.sh +0 -0
  49. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/packages/deb/README +0 -0
  50. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/packages/deb/changelog +24 -0
  51. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/packages/deb/compat +0 -0
  52. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/packages/deb/control +1 -1
  53. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/packages/deb/copyright +0 -0
  54. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/packages/deb/docs +0 -0
  55. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/packages/deb/rules +0 -0
  56. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/packages/deb/sparsehash.dirs +0 -0
  57. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/packages/deb/sparsehash.install +0 -0
  58. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/packages/rpm.sh +0 -0
  59. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/packages/rpm/rpm.spec +1 -1
  60. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/config.h.in +3 -0
  61. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/config.h.include +0 -0
  62. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/google/dense_hash_map +43 -27
  63. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/google/dense_hash_set +40 -19
  64. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/google/sparse_hash_map +32 -23
  65. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/google/sparse_hash_set +31 -21
  66. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/google/sparsehash/densehashtable.h +481 -298
  67. data/ext/sparsehash-1.8.1/src/google/sparsehash/hashtable-common.h +178 -0
  68. data/ext/sparsehash-1.8.1/src/google/sparsehash/libc_allocator_with_realloc.h +121 -0
  69. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/google/sparsehash/sparsehashtable.h +404 -233
  70. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/google/sparsetable +173 -83
  71. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/google/type_traits.h +3 -29
  72. data/ext/sparsehash-1.8.1/src/hash_test_interface.h +1011 -0
  73. data/ext/sparsehash-1.8.1/src/hashtable_test.cc +1733 -0
  74. data/ext/sparsehash-1.8.1/src/libc_allocator_with_realloc_test.cc +129 -0
  75. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/simple_test.cc +1 -1
  76. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/sparsetable_unittest.cc +202 -6
  77. data/ext/sparsehash-1.8.1/src/testutil.h +251 -0
  78. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/time_hash_map.cc +128 -54
  79. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/type_traits_unittest.cc +30 -20
  80. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/windows/config.h +0 -0
  81. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/windows/google/sparsehash/sparseconfig.h +0 -0
  82. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/windows/port.cc +0 -0
  83. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/windows/port.h +0 -0
  84. data/ext/sparsehash-1.8.1/vsprojects/hashtable_test/hashtable_test.vcproj +197 -0
  85. data/ext/{sparsehash-1.5.2/vsprojects/hashtable_unittest/hashtable_unittest.vcproj → sparsehash-1.8.1/vsprojects/simple_test/simple_test.vcproj} +9 -8
  86. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/vsprojects/sparsetable_unittest/sparsetable_unittest.vcproj +0 -2
  87. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/vsprojects/time_hash_map/time_hash_map.vcproj +3 -2
  88. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/vsprojects/type_traits_unittest/type_traits_unittest.vcproj +0 -2
  89. data/ext/template/google_hash.cpp.erb +2 -1
  90. data/ext/template/main.cpp.erb +1 -1
  91. data/results.txt +6 -22
  92. data/spec/benchmark.rb +57 -0
  93. data/spec/spec.google_hash.rb +1 -8
  94. metadata +140 -130
  95. data/ext/benchmark.rb +0 -47
  96. data/ext/sparsehash-1.5.2/NEWS +0 -0
  97. data/ext/sparsehash-1.5.2/src/hashtable_unittest.cc +0 -1375
  98. data/ext/sparsehash-1.5.2/src/words +0 -8944
  99. data/types.txt +0 -18
@@ -7,7 +7,15 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sparsetable_unittest", "vsp
7
7
  ProjectSection(ProjectDependencies) = postProject
8
8
  EndProjectSection
9
9
  EndProject
10
- Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hashtable_unittest", "vsprojects\hashtable_unittest\hashtable_unittest.vcproj", "{FCDB3718-F01C-4DE4-B9F5-E10F2C5C0535}"
10
+ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hashtable_test", "vsprojects\hashtable_test\hashtable_test.vcproj", "{FCDB3718-F01C-4DE4-B9F5-E10F2C5C0535}"
11
+ ProjectSection(ProjectDependencies) = postProject
12
+ EndProjectSection
13
+ EndProject
14
+ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "simple_test", "vsprojects\simple_test\simple_test.vcproj", "{FCDB3718-F01C-4DE4-B9F5-E10F2C5C0538}"
15
+ ProjectSection(ProjectDependencies) = postProject
16
+ EndProjectSection
17
+ EndProject
18
+ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libc_allocator_with_realloc_test", "vsprojects\libc_allocator_with_realloc_test\libc_allocator_with_realloc_test.vcproj", "{FCDB3718-F01C-4DE4-B9F5-E10F2C5C0539}"
11
19
  ProjectSection(ProjectDependencies) = postProject
12
20
  EndProjectSection
13
21
  EndProject
@@ -35,6 +43,14 @@ Global
35
43
  {FCDB3718-F01C-4DE4-B9F5-E10F2C5C0535}.Debug.Build.0 = Debug|Win32
36
44
  {FCDB3718-F01C-4DE4-B9F5-E10F2C5C0535}.Release.ActiveCfg = Release|Win32
37
45
  {FCDB3718-F01C-4DE4-B9F5-E10F2C5C0535}.Release.Build.0 = Release|Win32
46
+ {FCDB3718-F01C-4DE4-B9F5-E10F2C5C0538}.Debug.ActiveCfg = Debug|Win32
47
+ {FCDB3718-F01C-4DE4-B9F5-E10F2C5C0538}.Debug.Build.0 = Debug|Win32
48
+ {FCDB3718-F01C-4DE4-B9F5-E10F2C5C0538}.Release.ActiveCfg = Release|Win32
49
+ {FCDB3718-F01C-4DE4-B9F5-E10F2C5C0538}.Release.Build.0 = Release|Win32
50
+ {FCDB3718-F01C-4DE4-B9F5-E10F2C5C0539}.Debug.ActiveCfg = Debug|Win32
51
+ {FCDB3718-F01C-4DE4-B9F5-E10F2C5C0539}.Debug.Build.0 = Debug|Win32
52
+ {FCDB3718-F01C-4DE4-B9F5-E10F2C5C0539}.Release.ActiveCfg = Release|Win32
53
+ {FCDB3718-F01C-4DE4-B9F5-E10F2C5C0539}.Release.Build.0 = Release|Win32
38
54
  {A74E5DB8-5295-487A-AB1D-23859F536F45}.Debug.ActiveCfg = Debug|Win32
39
55
  {A74E5DB8-5295-487A-AB1D-23859F536F45}.Debug.Build.0 = Debug|Win32
40
56
  {A74E5DB8-5295-487A-AB1D-23859F536F45}.Release.ActiveCfg = Release|Win32
@@ -1,3 +1,27 @@
1
+ sparsehash (1.8.1-1) unstable; urgency=low
2
+
3
+ * New upstream release.
4
+
5
+ -- Google Inc. <opensource@google.com> Thu, 29 Jul 2010 15:01:29 -0700
6
+
7
+ sparsehash (1.8-1) unstable; urgency=low
8
+
9
+ * New upstream release.
10
+
11
+ -- Google Inc. <opensource@google.com> Thu, 29 Jul 2010 09:53:26 -0700
12
+
13
+ sparsehash (1.7-1) unstable; urgency=low
14
+
15
+ * New upstream release.
16
+
17
+ -- Google Inc. <opensource@google.com> Wed, 31 Mar 2010 12:32:03 -0700
18
+
19
+ sparsehash (1.6-1) unstable; urgency=low
20
+
21
+ * New upstream release.
22
+
23
+ -- Google Inc. <opensource@google.com> Fri, 08 Jan 2010 14:47:55 -0800
24
+
1
25
  sparsehash (1.5.2-1) unstable; urgency=low
2
26
 
3
27
  * New upstream release.
@@ -1,7 +1,7 @@
1
1
  Source: sparsehash
2
2
  Section: libdevel
3
3
  Priority: optional
4
- Maintainer: Google Inc. <opensource@google.com>
4
+ Maintainer: Google Inc. <google-sparsehash@googlegroups.com>
5
5
  Build-Depends: debhelper (>= 4.0.0)
6
6
  Standards-Version: 3.6.1
7
7
 
@@ -10,7 +10,7 @@ Group: Development/Libraries
10
10
  URL: http://code.google.com/p/google-sparsehash
11
11
  License: BSD
12
12
  Vendor: Google
13
- Packager: Google <opensource@google.com>
13
+ Packager: Google <google-sparsehash@googlegroups.com>
14
14
  Source: http://%{NAME}.googlecode.com/files/%{NAME}-%{VERSION}.tar.gz
15
15
  Distribution: Redhat 7 and above.
16
16
  Buildroot: %{_tmppath}/%{name}-root
@@ -102,6 +102,9 @@
102
102
  /* Define to the one symbol short name of this package. */
103
103
  #undef PACKAGE_TARNAME
104
104
 
105
+ /* Define to the home page for this package. */
106
+ #undef PACKAGE_URL
107
+
105
108
  /* Define to the version of this package. */
106
109
  #undef PACKAGE_VERSION
107
110
 
@@ -42,12 +42,20 @@
42
42
  //
43
43
  // YOU MUST CALL SET_EMPTY_KEY() IMMEDIATELY AFTER CONSTRUCTION.
44
44
  //
45
- // Otherwise your program will die in mysterious ways.
45
+ // Otherwise your program will die in mysterious ways. (Note if you
46
+ // use the constructor that takes an InputIterator range, you pass in
47
+ // the empty key in the constructor, rather than after. As a result,
48
+ // this constructor differs from the standard STL version.)
46
49
  //
47
50
  // In other respects, we adhere mostly to the STL semantics for
48
- // hash-map. One important exception is that insert() invalidates
49
- // iterators entirely. On the plus side, though, erase() doesn't
50
- // invalidate iterators at all, or even change the ordering of elements.
51
+ // hash-map. One important exception is that insert() may invalidate
52
+ // iterators entirely -- STL semantics are that insert() may reorder
53
+ // iterators, but they all still refer to something valid in the
54
+ // hashtable. Not so for us. Likewise, insert() may invalidate
55
+ // pointers into the hashtable. (Whether insert invalidates iterators
56
+ // and pointers depends on whether it results in a hashtable resize).
57
+ // On the plus side, delete() doesn't invalidate iterators or pointers
58
+ // at all, or even change the ordering of elements.
51
59
  //
52
60
  // Here are a few "power user" tips:
53
61
  //
@@ -67,18 +75,19 @@
67
75
  // Setting the minimum load factor to 0.0 guarantees that
68
76
  // the hash table will never shrink.
69
77
  //
70
- // Guide to what kind of hash_map to use:
71
- // (1) dense_hash_map: fastest, uses the most memory
78
+ // Roughly speaking:
79
+ // (1) dense_hash_map: fastest, uses the most memory unless entries are small
72
80
  // (2) sparse_hash_map: slowest, uses the least memory
73
- // (3) hash_map (STL): in the middle
81
+ // (3) hash_map / unordered_map (STL): in the middle
82
+ //
74
83
  // Typically I use sparse_hash_map when I care about space and/or when
75
84
  // I need to save the hashtable on disk. I use hash_map otherwise. I
76
85
  // don't personally use dense_hash_set ever; some people use it for
77
86
  // small sets with lots of lookups.
78
87
  //
79
- // - dense_hash_map has, typically, a factor of 2 memory overhead (if your
80
- // data takes up X bytes, the hash_map uses X more bytes in overhead).
81
- // - sparse_hash_map has about 2 bits overhead per entry.
88
+ // - dense_hash_map has, typically, about 78% memory overhead (if your
89
+ // data takes up X bytes, the hash_map uses .78X more bytes in overhead).
90
+ // - sparse_hash_map has about 4 bits overhead per entry.
82
91
  // - sparse_hash_map can be 3-7 times slower than the others for lookup and,
83
92
  // especially, inserts. See time_hash_map.cc for details.
84
93
  //
@@ -95,6 +104,7 @@
95
104
  #include <memory> // for alloc<>
96
105
  #include <utility> // for pair<>
97
106
  #include HASH_FUN_H // defined in config.h
107
+ #include <google/sparsehash/libc_allocator_with_realloc.h>
98
108
  #include <google/sparsehash/densehashtable.h>
99
109
 
100
110
 
@@ -105,7 +115,7 @@ using STL_NAMESPACE::pair;
105
115
  template <class Key, class T,
106
116
  class HashFcn = SPARSEHASH_HASH<Key>, // defined in sparseconfig.h
107
117
  class EqualKey = STL_NAMESPACE::equal_to<Key>,
108
- class Alloc = STL_NAMESPACE::allocator<T> >
118
+ class Alloc = libc_allocator_with_realloc<pair<const Key, T> > >
109
119
  class dense_hash_map {
110
120
  private:
111
121
  // Apparently select1st is not stl-standard, so we define our own
@@ -125,8 +135,8 @@ class dense_hash_map {
125
135
  };
126
136
 
127
137
  // The actual data
128
- typedef dense_hashtable<pair<const Key, T>, Key, HashFcn,
129
- SelectKey, SetKey, EqualKey, Alloc> ht;
138
+ typedef dense_hashtable<pair<const Key, T>, Key, HashFcn, SelectKey,
139
+ SetKey, EqualKey, Alloc> ht;
130
140
  ht rep;
131
141
 
132
142
  public:
@@ -164,7 +174,7 @@ class dense_hash_map {
164
174
  const_local_iterator end(size_type i) const { return rep.end(i); }
165
175
 
166
176
  // Accessor functions
167
- // TODO(csilvers): implement Alloc get_allocator() const;
177
+ allocator_type get_allocator() const { return rep.get_allocator(); }
168
178
  hasher hash_funct() const { return rep.hash_funct(); }
169
179
  hasher hash_function() const { return hash_funct(); }
170
180
  key_equal key_eq() const { return rep.key_eq(); }
@@ -173,15 +183,20 @@ class dense_hash_map {
173
183
  // Constructors
174
184
  explicit dense_hash_map(size_type expected_max_items_in_table = 0,
175
185
  const hasher& hf = hasher(),
176
- const key_equal& eql = key_equal())
177
- : rep(expected_max_items_in_table, hf, eql) { }
186
+ const key_equal& eql = key_equal(),
187
+ const allocator_type& alloc = allocator_type())
188
+ : rep(expected_max_items_in_table, hf, eql, SelectKey(), SetKey(), alloc) {
189
+ }
178
190
 
179
191
  template <class InputIterator>
180
192
  dense_hash_map(InputIterator f, InputIterator l,
193
+ const key_type& empty_key_val,
181
194
  size_type expected_max_items_in_table = 0,
182
195
  const hasher& hf = hasher(),
183
- const key_equal& eql = key_equal())
184
- : rep(expected_max_items_in_table, hf, eql) {
196
+ const key_equal& eql = key_equal(),
197
+ const allocator_type& alloc = allocator_type())
198
+ : rep(expected_max_items_in_table, hf, eql, SelectKey(), SetKey(), alloc) {
199
+ set_empty_key(empty_key_val);
185
200
  rep.insert(f, l);
186
201
  }
187
202
  // We use the default copy constructor
@@ -231,7 +246,7 @@ class dense_hash_map {
231
246
  }
232
247
  // Deprecated; use min_load_factor() or max_load_factor() instead.
233
248
  void set_resizing_parameters(float shrink, float grow) {
234
- return rep.set_resizing_parameters(shrink, grow);
249
+ rep.set_resizing_parameters(shrink, grow);
235
250
  }
236
251
 
237
252
  void resize(size_type hint) { rep.resize(hint); }
@@ -242,12 +257,10 @@ class dense_hash_map {
242
257
  const_iterator find(const key_type& key) const { return rep.find(key); }
243
258
 
244
259
  data_type& operator[](const key_type& key) { // This is our value-add!
245
- iterator it = find(key);
246
- if (it != end()) {
247
- return it->second;
248
- } else {
249
- return insert(value_type(key, data_type())).first->second;
250
- }
260
+ // If key is in the hashtable, returns find(key)->second,
261
+ // otherwise returns insert(value_type(key, T()).first->second.
262
+ // Note it does not create an empty T unless the find fails.
263
+ return rep.template find_or_insert<T>(key);
251
264
  }
252
265
 
253
266
  size_type count(const key_type& key) const { return rep.count(key); }
@@ -275,10 +288,13 @@ class dense_hash_map {
275
288
  void set_empty_key(const key_type& key) { // YOU MUST CALL THIS!
276
289
  rep.set_empty_key(value_type(key, data_type())); // rep wants a value
277
290
  }
278
- void set_deleted_key(const key_type& key) {
279
- rep.set_deleted_key(key);
291
+ key_type empty_key() const {
292
+ return rep.empty_key().first; // rep returns a value
280
293
  }
294
+
295
+ void set_deleted_key(const key_type& key) { rep.set_deleted_key(key); }
281
296
  void clear_deleted_key() { rep.clear_deleted_key(); }
297
+ key_type deleted_key() const { return rep.deleted_key(); }
282
298
 
283
299
  // These are standard
284
300
  size_type erase(const key_type& key) { return rep.erase(key); }
@@ -46,12 +46,20 @@
46
46
  //
47
47
  // YOU MUST CALL SET_EMPTY_KEY() IMMEDIATELY AFTER CONSTRUCTION.
48
48
  //
49
- // Otherwise your program will die in mysterious ways.
49
+ // Otherwise your program will die in mysterious ways. (Note if you
50
+ // use the constructor that takes an InputIterator range, you pass in
51
+ // the empty key in the constructor, rather than after. As a result,
52
+ // this constructor differs from the standard STL version.)
50
53
  //
51
54
  // In other respects, we adhere mostly to the STL semantics for
52
- // hash-set. One important exception is that insert() invalidates
53
- // iterators entirely. On the plus side, though, erase() doesn't
54
- // invalidate iterators at all, or even change the ordering of elements.
55
+ // hash-map. One important exception is that insert() may invalidate
56
+ // iterators entirely -- STL semantics are that insert() may reorder
57
+ // iterators, but they all still refer to something valid in the
58
+ // hashtable. Not so for us. Likewise, insert() may invalidate
59
+ // pointers into the hashtable. (Whether insert invalidates iterators
60
+ // and pointers depends on whether it results in a hashtable resize).
61
+ // On the plus side, delete() doesn't invalidate iterators or pointers
62
+ // at all, or even change the ordering of elements.
55
63
  //
56
64
  // Here are a few "power user" tips:
57
65
  //
@@ -71,19 +79,20 @@
71
79
  // Setting the minimum load factor to 0.0 guarantees that
72
80
  // the hash table will never shrink.
73
81
  //
74
- // Guide to what kind of hash_set to use:
75
- // (1) dense_hash_set: fastest, uses the most memory
82
+ // Roughly speaking:
83
+ // (1) dense_hash_set: fastest, uses the most memory unless entries are small
76
84
  // (2) sparse_hash_set: slowest, uses the least memory
77
- // (3) hash_set (STL): in the middle
85
+ // (3) hash_set / unordered_set (STL): in the middle
86
+ //
78
87
  // Typically I use sparse_hash_set when I care about space and/or when
79
88
  // I need to save the hashtable on disk. I use hash_set otherwise. I
80
89
  // don't personally use dense_hash_set ever; some people use it for
81
90
  // small sets with lots of lookups.
82
91
  //
83
- // - dense_hash_set has, typically, a factor of 2 memory overhead (if your
84
- // data takes up X bytes, the hash_set uses X more bytes in overhead).
85
- // - sparse_hash_set has about 2 bits overhead per entry.
86
- // - sparse_hash_map can be 3-7 times slower than the others for lookup and,
92
+ // - dense_hash_set has, typically, about 78% memory overhead (if your
93
+ // data takes up X bytes, the hash_set uses .78X more bytes in overhead).
94
+ // - sparse_hash_set has about 4 bits overhead per entry.
95
+ // - sparse_hash_set can be 3-7 times slower than the others for lookup and,
87
96
  // especially, inserts. See time_hash_map.cc for details.
88
97
  //
89
98
  // See /usr/(local/)?doc/sparsehash-*/dense_hash_set.html
@@ -99,6 +108,7 @@
99
108
  #include <memory> // for alloc<>
100
109
  #include <utility> // for pair<>
101
110
  #include HASH_FUN_H // defined in config.h
111
+ #include <google/sparsehash/libc_allocator_with_realloc.h>
102
112
  #include <google/sparsehash/densehashtable.h>
103
113
 
104
114
 
@@ -109,7 +119,7 @@ using STL_NAMESPACE::pair;
109
119
  template <class Value,
110
120
  class HashFcn = SPARSEHASH_HASH<Value>, // defined in sparseconfig.h
111
121
  class EqualKey = STL_NAMESPACE::equal_to<Value>,
112
- class Alloc = STL_NAMESPACE::allocator<Value> >
122
+ class Alloc = libc_allocator_with_realloc<Value> >
113
123
  class dense_hash_set {
114
124
  private:
115
125
  // Apparently identity is not stl-standard, so we define our own
@@ -124,8 +134,8 @@ class dense_hash_set {
124
134
  };
125
135
 
126
136
  // The actual data
127
- typedef dense_hashtable<Value, Value, HashFcn,
128
- Identity, SetKey, EqualKey, Alloc> ht;
137
+ typedef dense_hashtable<Value, Value, HashFcn, Identity, SetKey,
138
+ EqualKey, Alloc> ht;
129
139
  ht rep;
130
140
 
131
141
  public:
@@ -158,22 +168,29 @@ class dense_hash_set {
158
168
 
159
169
 
160
170
  // Accessor functions
171
+ allocator_type get_allocator() const { return rep.get_allocator(); }
161
172
  hasher hash_funct() const { return rep.hash_funct(); }
173
+ hasher hash_function() const { return hash_funct(); } // tr1 name
162
174
  key_equal key_eq() const { return rep.key_eq(); }
163
175
 
164
176
 
165
177
  // Constructors
166
178
  explicit dense_hash_set(size_type expected_max_items_in_table = 0,
167
179
  const hasher& hf = hasher(),
168
- const key_equal& eql = key_equal())
169
- : rep(expected_max_items_in_table, hf, eql) { }
180
+ const key_equal& eql = key_equal(),
181
+ const allocator_type& alloc = allocator_type())
182
+ : rep(expected_max_items_in_table, hf, eql, Identity(), SetKey(), alloc) {
183
+ }
170
184
 
171
185
  template <class InputIterator>
172
186
  dense_hash_set(InputIterator f, InputIterator l,
187
+ const key_type& empty_key_val,
173
188
  size_type expected_max_items_in_table = 0,
174
189
  const hasher& hf = hasher(),
175
- const key_equal& eql = key_equal())
176
- : rep(expected_max_items_in_table, hf, eql) {
190
+ const key_equal& eql = key_equal(),
191
+ const allocator_type& alloc = allocator_type())
192
+ : rep(expected_max_items_in_table, hf, eql, Identity(), SetKey(), alloc) {
193
+ set_empty_key(empty_key_val);
177
194
  rep.insert(f, l);
178
195
  }
179
196
  // We use the default copy constructor
@@ -223,7 +240,7 @@ class dense_hash_set {
223
240
  }
224
241
  // Deprecated; use min_load_factor() or max_load_factor() instead.
225
242
  void set_resizing_parameters(float shrink, float grow) {
226
- return rep.set_resizing_parameters(shrink, grow);
243
+ rep.set_resizing_parameters(shrink, grow);
227
244
  }
228
245
 
229
246
  void resize(size_type hint) { rep.resize(hint); }
@@ -238,6 +255,7 @@ class dense_hash_set {
238
255
  return rep.equal_range(key);
239
256
  }
240
257
 
258
+
241
259
  // Insertion routines
242
260
  pair<iterator, bool> insert(const value_type& obj) {
243
261
  pair<typename ht::iterator, bool> p = rep.insert(obj);
@@ -255,8 +273,11 @@ class dense_hash_set {
255
273
  // value to identify deleted and empty buckets. You can change the
256
274
  // deleted key as time goes on, or get rid of it entirely to be insert-only.
257
275
  void set_empty_key(const key_type& key) { rep.set_empty_key(key); }
276
+ key_type empty_key() const { return rep.empty_key(); }
277
+
258
278
  void set_deleted_key(const key_type& key) { rep.set_deleted_key(key); }
259
279
  void clear_deleted_key() { rep.clear_deleted_key(); }
280
+ key_type deleted_key() const { return rep.deleted_key(); }
260
281
 
261
282
  // These are standard
262
283
  size_type erase(const key_type& key) { return rep.erase(key); }
@@ -37,9 +37,14 @@
37
37
  // (it only has a key and a value).
38
38
  //
39
39
  // We adhere mostly to the STL semantics for hash-map. One important
40
- // exception is that insert() invalidates iterators entirely. On the
41
- // plus side, though, delete() doesn't invalidate iterators at all, or
42
- // even change the ordering of elements.
40
+ // exception is that insert() may invalidate iterators entirely -- STL
41
+ // semantics are that insert() may reorder iterators, but they all
42
+ // still refer to something valid in the hashtable. Not so for us.
43
+ // Likewise, insert() may invalidate pointers into the hashtable.
44
+ // (Whether insert invalidates iterators and pointers depends on
45
+ // whether it results in a hashtable resize). On the plus side,
46
+ // delete() doesn't invalidate iterators or pointers at all, or even
47
+ // change the ordering of elements.
43
48
  //
44
49
  // Here are a few "power user" tips:
45
50
  //
@@ -58,18 +63,19 @@
58
63
  // Setting the minimum load factor to 0.0 guarantees that
59
64
  // the hash table will never shrink.
60
65
  //
61
- // Guide to what kind of hash_map to use:
62
- // (1) dense_hash_map: fastest, uses the most memory
66
+ // Roughly speaking:
67
+ // (1) dense_hash_map: fastest, uses the most memory unless entries are small
63
68
  // (2) sparse_hash_map: slowest, uses the least memory
64
69
  // (3) hash_map / unordered_map (STL): in the middle
70
+ //
65
71
  // Typically I use sparse_hash_map when I care about space and/or when
66
72
  // I need to save the hashtable on disk. I use hash_map otherwise. I
67
73
  // don't personally use dense_hash_map ever; some people use it for
68
74
  // small maps with lots of lookups.
69
75
  //
70
- // - dense_hash_map has, typically, a factor of 2 memory overhead (if your
71
- // data takes up X bytes, the hash_map uses X more bytes in overhead).
72
- // - sparse_hash_map has about 2 bits overhead per entry.
76
+ // - dense_hash_map has, typically, about 78% memory overhead (if your
77
+ // data takes up X bytes, the hash_map uses .78X more bytes in overhead).
78
+ // - sparse_hash_map has about 4 bits overhead per entry.
73
79
  // - sparse_hash_map can be 3-7 times slower than the others for lookup and,
74
80
  // especially, inserts. See time_hash_map.cc for details.
75
81
  //
@@ -86,6 +92,7 @@
86
92
  #include <memory> // for alloc<>
87
93
  #include <utility> // for pair<>
88
94
  #include HASH_FUN_H // defined in config.h
95
+ #include <google/sparsehash/libc_allocator_with_realloc.h>
89
96
  #include <google/sparsehash/sparsehashtable.h>
90
97
 
91
98
 
@@ -96,7 +103,7 @@ using STL_NAMESPACE::pair;
96
103
  template <class Key, class T,
97
104
  class HashFcn = SPARSEHASH_HASH<Key>, // defined in sparseconfig.h
98
105
  class EqualKey = STL_NAMESPACE::equal_to<Key>,
99
- class Alloc = STL_NAMESPACE::allocator<T> >
106
+ class Alloc = libc_allocator_with_realloc<pair<const Key, T> > >
100
107
  class sparse_hash_map {
101
108
  private:
102
109
  // Apparently select1st is not stl-standard, so we define our own
@@ -116,8 +123,8 @@ class sparse_hash_map {
116
123
  };
117
124
 
118
125
  // The actual data
119
- typedef sparse_hashtable<pair<const Key, T>, Key, HashFcn,
120
- SelectKey, SetKey, EqualKey, Alloc> ht;
126
+ typedef sparse_hashtable<pair<const Key, T>, Key, HashFcn, SelectKey,
127
+ SetKey, EqualKey, Alloc> ht;
121
128
  ht rep;
122
129
 
123
130
  public:
@@ -154,7 +161,7 @@ class sparse_hash_map {
154
161
  const_local_iterator end(size_type i) const { return rep.end(i); }
155
162
 
156
163
  // Accessor functions
157
- // TODO(csilvers): implement Alloc get_allocator() const;
164
+ allocator_type get_allocator() const { return rep.get_allocator(); }
158
165
  hasher hash_funct() const { return rep.hash_funct(); }
159
166
  hasher hash_function() const { return hash_funct(); }
160
167
  key_equal key_eq() const { return rep.key_eq(); }
@@ -163,15 +170,18 @@ class sparse_hash_map {
163
170
  // Constructors
164
171
  explicit sparse_hash_map(size_type expected_max_items_in_table = 0,
165
172
  const hasher& hf = hasher(),
166
- const key_equal& eql = key_equal())
167
- : rep(expected_max_items_in_table, hf, eql) { }
173
+ const key_equal& eql = key_equal(),
174
+ const allocator_type& alloc = allocator_type())
175
+ : rep(expected_max_items_in_table, hf, eql, SelectKey(), SetKey(), alloc) {
176
+ }
168
177
 
169
178
  template <class InputIterator>
170
179
  sparse_hash_map(InputIterator f, InputIterator l,
171
180
  size_type expected_max_items_in_table = 0,
172
181
  const hasher& hf = hasher(),
173
- const key_equal& eql = key_equal())
174
- : rep(expected_max_items_in_table, hf, eql) {
182
+ const key_equal& eql = key_equal(),
183
+ const allocator_type& alloc = allocator_type())
184
+ : rep(expected_max_items_in_table, hf, eql, SelectKey(), SetKey(), alloc) {
175
185
  rep.insert(f, l);
176
186
  }
177
187
  // We use the default copy constructor
@@ -218,7 +228,7 @@ class sparse_hash_map {
218
228
  }
219
229
  // Deprecated; use min_load_factor() or max_load_factor() instead.
220
230
  void set_resizing_parameters(float shrink, float grow) {
221
- return rep.set_resizing_parameters(shrink, grow);
231
+ rep.set_resizing_parameters(shrink, grow);
222
232
  }
223
233
 
224
234
  void resize(size_type hint) { rep.resize(hint); }
@@ -229,12 +239,10 @@ class sparse_hash_map {
229
239
  const_iterator find(const key_type& key) const { return rep.find(key); }
230
240
 
231
241
  data_type& operator[](const key_type& key) { // This is our value-add!
232
- iterator it = find(key);
233
- if (it != end()) {
234
- return it->second;
235
- } else {
236
- return insert(value_type(key, data_type())).first->second;
237
- }
242
+ // If key is in the hashtable, returns find(key)->second,
243
+ // otherwise returns insert(value_type(key, T()).first->second.
244
+ // Note it does not create an empty T unless the find fails.
245
+ return rep.template find_or_insert<data_type>(key);
238
246
  }
239
247
 
240
248
  size_type count(const key_type& key) const { return rep.count(key); }
@@ -263,6 +271,7 @@ class sparse_hash_map {
263
271
  rep.set_deleted_key(key);
264
272
  }
265
273
  void clear_deleted_key() { rep.clear_deleted_key(); }
274
+ key_type deleted_key() const { return rep.deleted_key(); }
266
275
 
267
276
  // These are standard
268
277
  size_type erase(const key_type& key) { return rep.erase(key); }