google_hash 0.6.2 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
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); }