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.
- 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); }
|