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.
- data/README +61 -27
- data/Rakefile +4 -1
- data/TODO +5 -0
- data/VERSION +1 -1
- data/changelog +3 -0
- data/ext/extconf.rb +10 -5
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/AUTHORS +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/COPYING +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/ChangeLog +47 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/INSTALL +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/Makefile.am +29 -14
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/Makefile.in +77 -42
- data/ext/sparsehash-1.8.1/NEWS +71 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/README +0 -0
- data/ext/{sparsehash-1.5.2/README.windows → sparsehash-1.8.1/README_windows.txt} +25 -25
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/TODO +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/aclocal.m4 +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/compile +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/config.guess +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/config.sub +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/configure +3690 -4560
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/configure.ac +1 -1
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/depcomp +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/doc/dense_hash_map.html +65 -5
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/doc/dense_hash_set.html +65 -5
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/doc/designstyle.css +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/doc/implementation.html +11 -5
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/doc/index.html +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/doc/performance.html +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/doc/sparse_hash_map.html +65 -5
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/doc/sparse_hash_set.html +65 -5
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/doc/sparsetable.html +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/experimental/Makefile +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/experimental/README +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/experimental/example.c +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/experimental/libchash.c +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/experimental/libchash.h +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/google-sparsehash.sln +17 -1
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/install-sh +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/m4/acx_pthread.m4 +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/m4/google_namespace.m4 +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/m4/namespaces.m4 +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/m4/stl_hash.m4 +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/m4/stl_hash_fun.m4 +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/m4/stl_namespace.m4 +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/missing +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/mkinstalldirs +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/packages/deb.sh +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/packages/deb/README +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/packages/deb/changelog +24 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/packages/deb/compat +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/packages/deb/control +1 -1
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/packages/deb/copyright +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/packages/deb/docs +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/packages/deb/rules +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/packages/deb/sparsehash.dirs +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/packages/deb/sparsehash.install +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/packages/rpm.sh +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/packages/rpm/rpm.spec +1 -1
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/config.h.in +3 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/config.h.include +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/google/dense_hash_map +43 -27
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/google/dense_hash_set +40 -19
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/google/sparse_hash_map +32 -23
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/google/sparse_hash_set +31 -21
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/google/sparsehash/densehashtable.h +481 -298
- data/ext/sparsehash-1.8.1/src/google/sparsehash/hashtable-common.h +178 -0
- data/ext/sparsehash-1.8.1/src/google/sparsehash/libc_allocator_with_realloc.h +121 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/google/sparsehash/sparsehashtable.h +404 -233
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/google/sparsetable +173 -83
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/google/type_traits.h +3 -29
- data/ext/sparsehash-1.8.1/src/hash_test_interface.h +1011 -0
- data/ext/sparsehash-1.8.1/src/hashtable_test.cc +1733 -0
- data/ext/sparsehash-1.8.1/src/libc_allocator_with_realloc_test.cc +129 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/simple_test.cc +1 -1
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/sparsetable_unittest.cc +202 -6
- data/ext/sparsehash-1.8.1/src/testutil.h +251 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/time_hash_map.cc +128 -54
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/type_traits_unittest.cc +30 -20
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/windows/config.h +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/windows/google/sparsehash/sparseconfig.h +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/windows/port.cc +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/windows/port.h +0 -0
- data/ext/sparsehash-1.8.1/vsprojects/hashtable_test/hashtable_test.vcproj +197 -0
- data/ext/{sparsehash-1.5.2/vsprojects/hashtable_unittest/hashtable_unittest.vcproj → sparsehash-1.8.1/vsprojects/simple_test/simple_test.vcproj} +9 -8
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/vsprojects/sparsetable_unittest/sparsetable_unittest.vcproj +0 -2
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/vsprojects/time_hash_map/time_hash_map.vcproj +3 -2
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/vsprojects/type_traits_unittest/type_traits_unittest.vcproj +0 -2
- data/ext/template/google_hash.cpp.erb +2 -1
- data/ext/template/main.cpp.erb +1 -1
- data/results.txt +6 -22
- data/spec/benchmark.rb +57 -0
- data/spec/spec.google_hash.rb +1 -8
- metadata +140 -130
- data/ext/benchmark.rb +0 -47
- data/ext/sparsehash-1.5.2/NEWS +0 -0
- data/ext/sparsehash-1.5.2/src/hashtable_unittest.cc +0 -1375
- data/ext/sparsehash-1.5.2/src/words +0 -8944
- data/types.txt +0 -18
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -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}") = "
|
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
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -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.
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -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 <
|
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
|
|
File without changes
|
@@ -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()
|
49
|
-
// iterators entirely
|
50
|
-
//
|
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
|
-
//
|
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,
|
80
|
-
// data takes up X bytes, the hash_map uses
|
81
|
-
// - sparse_hash_map has about
|
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 =
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
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
|
-
|
279
|
-
rep.
|
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-
|
53
|
-
// iterators entirely
|
54
|
-
//
|
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
|
-
//
|
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,
|
84
|
-
// data takes up X bytes, the hash_set uses
|
85
|
-
// - sparse_hash_set has about
|
86
|
-
// -
|
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 =
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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()
|
41
|
-
//
|
42
|
-
//
|
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
|
-
//
|
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,
|
71
|
-
// data takes up X bytes, the hash_map uses
|
72
|
-
// - sparse_hash_map has about
|
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 =
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
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); }
|