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
@@ -45,6 +45,7 @@
|
|
45
45
|
// remove_cv
|
46
46
|
// remove_reference
|
47
47
|
// remove_pointer
|
48
|
+
// is_same
|
48
49
|
// is_convertible
|
49
50
|
// We can add more type traits as required.
|
50
51
|
|
@@ -215,35 +216,8 @@ template<typename T> struct remove_pointer<T* const volatile> {
|
|
215
216
|
typedef T type; };
|
216
217
|
|
217
218
|
// Specified by TR1 [4.6] Relationships between types
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
// This class is an implementation detail for is_convertible, and you
|
222
|
-
// don't need to know how it works to use is_convertible. For those
|
223
|
-
// who care: we declare two different functions, one whose argument is
|
224
|
-
// of type To and one with a variadic argument list. We give them
|
225
|
-
// return types of different size, so we can use sizeof to trick the
|
226
|
-
// compiler into telling us which function it would have chosen if we
|
227
|
-
// had called it with an argument of type From. See Alexandrescu's
|
228
|
-
// _Modern C++ Design_ for more details on this sort of trick.
|
229
|
-
|
230
|
-
template <typename From, typename To>
|
231
|
-
struct ConvertHelper {
|
232
|
-
static small_ Test(To);
|
233
|
-
static big_ Test(...);
|
234
|
-
static From Create();
|
235
|
-
};
|
236
|
-
} // namespace internal
|
237
|
-
|
238
|
-
// Inherits from true_type if From is convertible to To, false_type otherwise.
|
239
|
-
template <typename From, typename To>
|
240
|
-
struct is_convertible
|
241
|
-
: integral_constant<bool,
|
242
|
-
sizeof(internal::ConvertHelper<From, To>::Test(
|
243
|
-
internal::ConvertHelper<From, To>::Create()))
|
244
|
-
== sizeof(small_)> {
|
245
|
-
};
|
246
|
-
#endif
|
219
|
+
template<typename T, typename U> struct is_same : public false_type { };
|
220
|
+
template<typename T> struct is_same<T, T> : public true_type { };
|
247
221
|
|
248
222
|
_END_GOOGLE_NAMESPACE_
|
249
223
|
|
@@ -0,0 +1,1011 @@
|
|
1
|
+
// Copyright (c) 2010, Google Inc.
|
2
|
+
// All rights reserved.
|
3
|
+
//
|
4
|
+
// Redistribution and use in source and binary forms, with or without
|
5
|
+
// modification, are permitted provided that the following conditions are
|
6
|
+
// met:
|
7
|
+
//
|
8
|
+
// * Redistributions of source code must retain the above copyright
|
9
|
+
// notice, this list of conditions and the following disclaimer.
|
10
|
+
// * Redistributions in binary form must reproduce the above
|
11
|
+
// copyright notice, this list of conditions and the following disclaimer
|
12
|
+
// in the documentation and/or other materials provided with the
|
13
|
+
// distribution.
|
14
|
+
// * Neither the name of Google Inc. nor the names of its
|
15
|
+
// contributors may be used to endorse or promote products derived from
|
16
|
+
// this software without specific prior written permission.
|
17
|
+
//
|
18
|
+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
19
|
+
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
20
|
+
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
21
|
+
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
22
|
+
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
23
|
+
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
24
|
+
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
25
|
+
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
26
|
+
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
27
|
+
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
28
|
+
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
29
|
+
|
30
|
+
// ----
|
31
|
+
// Author: Craig Silverstein
|
32
|
+
//
|
33
|
+
// This implements a uniform interface for all 6 hash implementations:
|
34
|
+
// dense_hashtable, dense_hash_map, dense_hash_set
|
35
|
+
// sparse_hashtable, sparse_hash_map, sparse_hash_set
|
36
|
+
// This is intended to be used for testing, to provide a single routine
|
37
|
+
// that can easily test all 6 implementations.
|
38
|
+
//
|
39
|
+
// The main reasons to specialize are to (1) provide dummy
|
40
|
+
// implementations for methods that are only needed for some of the
|
41
|
+
// implementations (for instance, set_empty_key()), and (2) provide a
|
42
|
+
// uniform interface to just the keys -- for instance, we provide
|
43
|
+
// wrappers around the iterators that define it.key, which gives the
|
44
|
+
// "key" part of the bucket (*it or it->first, depending on the class).
|
45
|
+
|
46
|
+
#ifndef UTIL_GTL_HASH_TEST_INTERFACE_H_
|
47
|
+
#define UTIL_GTL_HASH_TEST_INTERFACE_H_
|
48
|
+
|
49
|
+
#include "config.h"
|
50
|
+
#include HASH_MAP_H // for hash<>
|
51
|
+
#include <functional> // for equal_to<>
|
52
|
+
#include <google/sparsehash/sparsehashtable.h>
|
53
|
+
#include <google/sparse_hash_map>
|
54
|
+
#include <google/sparse_hash_set>
|
55
|
+
#include <google/sparsehash/densehashtable.h>
|
56
|
+
#include <google/dense_hash_map>
|
57
|
+
#include <google/dense_hash_set>
|
58
|
+
|
59
|
+
_START_GOOGLE_NAMESPACE_
|
60
|
+
|
61
|
+
// This is the "default" interface, which just passes everything
|
62
|
+
// through to the underlying hashtable. You'll need to subclass it to
|
63
|
+
// specialize behavior for an individual hashtable.
|
64
|
+
template <class HT>
|
65
|
+
class BaseHashtableInterface {
|
66
|
+
public:
|
67
|
+
virtual ~BaseHashtableInterface() {}
|
68
|
+
|
69
|
+
typedef typename HT::key_type key_type;
|
70
|
+
typedef typename HT::value_type value_type;
|
71
|
+
typedef typename HT::hasher hasher;
|
72
|
+
typedef typename HT::key_equal key_equal;
|
73
|
+
typedef typename HT::allocator_type allocator_type;
|
74
|
+
|
75
|
+
typedef typename HT::size_type size_type;
|
76
|
+
typedef typename HT::difference_type difference_type;
|
77
|
+
typedef typename HT::pointer pointer;
|
78
|
+
typedef typename HT::const_pointer const_pointer;
|
79
|
+
typedef typename HT::reference reference;
|
80
|
+
typedef typename HT::const_reference const_reference;
|
81
|
+
|
82
|
+
class const_iterator;
|
83
|
+
|
84
|
+
class iterator : public HT::iterator {
|
85
|
+
public:
|
86
|
+
iterator() : parent_(NULL) { } // this allows code like "iterator it;"
|
87
|
+
iterator(typename HT::iterator it,
|
88
|
+
const BaseHashtableInterface* parent)
|
89
|
+
: HT::iterator(it), parent_(parent) { }
|
90
|
+
key_type key() { return parent_->it_to_key(*this); }
|
91
|
+
private:
|
92
|
+
friend class BaseHashtableInterface::const_iterator; // for its ctor
|
93
|
+
const BaseHashtableInterface* parent_;
|
94
|
+
};
|
95
|
+
|
96
|
+
class const_iterator : public HT::const_iterator {
|
97
|
+
public:
|
98
|
+
const_iterator() : parent_(NULL) { }
|
99
|
+
const_iterator(typename HT::const_iterator it,
|
100
|
+
const BaseHashtableInterface* parent)
|
101
|
+
: HT::const_iterator(it), parent_(parent) { }
|
102
|
+
const_iterator(typename HT::iterator it,
|
103
|
+
BaseHashtableInterface* parent)
|
104
|
+
: HT::const_iterator(it), parent_(parent) { }
|
105
|
+
// The parameter type here *should* just be "iterator", but MSVC
|
106
|
+
// gets confused by that, so I'm overly specific.
|
107
|
+
const_iterator(typename BaseHashtableInterface<HT>::iterator it)
|
108
|
+
: HT::const_iterator(it), parent_(it.parent_) { }
|
109
|
+
key_type key() { return parent_->it_to_key(*this); }
|
110
|
+
private:
|
111
|
+
const BaseHashtableInterface* parent_;
|
112
|
+
};
|
113
|
+
|
114
|
+
class const_local_iterator;
|
115
|
+
|
116
|
+
class local_iterator : public HT::local_iterator {
|
117
|
+
public:
|
118
|
+
local_iterator() : parent_(NULL) { }
|
119
|
+
local_iterator(typename HT::local_iterator it,
|
120
|
+
const BaseHashtableInterface* parent)
|
121
|
+
: HT::local_iterator(it), parent_(parent) { }
|
122
|
+
key_type key() { return parent_->it_to_key(*this); }
|
123
|
+
private:
|
124
|
+
friend class BaseHashtableInterface::const_local_iterator; // for its ctor
|
125
|
+
const BaseHashtableInterface* parent_;
|
126
|
+
};
|
127
|
+
|
128
|
+
class const_local_iterator : public HT::const_local_iterator {
|
129
|
+
public:
|
130
|
+
const_local_iterator() : parent_(NULL) { }
|
131
|
+
const_local_iterator(typename HT::const_local_iterator it,
|
132
|
+
const BaseHashtableInterface* parent)
|
133
|
+
: HT::const_local_iterator(it), parent_(parent) { }
|
134
|
+
const_local_iterator(typename HT::local_iterator it,
|
135
|
+
BaseHashtableInterface* parent)
|
136
|
+
: HT::const_local_iterator(it), parent_(parent) { }
|
137
|
+
const_local_iterator(local_iterator it)
|
138
|
+
: HT::const_local_iterator(it), parent_(it.parent_) { }
|
139
|
+
key_type key() { return parent_->it_to_key(*this); }
|
140
|
+
private:
|
141
|
+
const BaseHashtableInterface* parent_;
|
142
|
+
};
|
143
|
+
|
144
|
+
iterator begin() {
|
145
|
+
return iterator(ht_.begin(), this);
|
146
|
+
}
|
147
|
+
iterator end() {
|
148
|
+
return iterator(ht_.end(), this);
|
149
|
+
}
|
150
|
+
const_iterator begin() const {
|
151
|
+
return const_iterator(ht_.begin(), this);
|
152
|
+
}
|
153
|
+
const_iterator end() const {
|
154
|
+
return const_iterator(ht_.end(), this);
|
155
|
+
}
|
156
|
+
local_iterator begin(size_type i) {
|
157
|
+
return local_iterator(ht_.begin(i), this);
|
158
|
+
}
|
159
|
+
local_iterator end(size_type i) {
|
160
|
+
return local_iterator(ht_.end(i), this);
|
161
|
+
}
|
162
|
+
const_local_iterator begin(size_type i) const {
|
163
|
+
return const_local_iterator(ht_.begin(i), this);
|
164
|
+
}
|
165
|
+
const_local_iterator end(size_type i) const {
|
166
|
+
return const_local_iterator(ht_.end(i), this);
|
167
|
+
}
|
168
|
+
|
169
|
+
hasher hash_funct() const { return ht_.hash_funct(); }
|
170
|
+
hasher hash_function() const { return ht_.hash_function(); }
|
171
|
+
key_equal key_eq() const { return ht_.key_eq(); }
|
172
|
+
allocator_type get_allocator() const { return ht_.get_allocator(); }
|
173
|
+
|
174
|
+
BaseHashtableInterface(size_type expected_max_items_in_table,
|
175
|
+
const hasher& hf,
|
176
|
+
const key_equal& eql,
|
177
|
+
const allocator_type& alloc)
|
178
|
+
: ht_(expected_max_items_in_table, hf, eql, alloc) { }
|
179
|
+
|
180
|
+
// Not all ht_'s support this constructor: you should only call it
|
181
|
+
// from a subclass if you know your ht supports it. Otherwise call
|
182
|
+
// the previous constructor, followed by 'insert(f, l);'.
|
183
|
+
template <class InputIterator>
|
184
|
+
BaseHashtableInterface(InputIterator f, InputIterator l,
|
185
|
+
size_type expected_max_items_in_table,
|
186
|
+
const hasher& hf,
|
187
|
+
const key_equal& eql,
|
188
|
+
const allocator_type& alloc)
|
189
|
+
: ht_(f, l, expected_max_items_in_table, hf, eql, alloc) {
|
190
|
+
}
|
191
|
+
|
192
|
+
// This is the version of the constructor used by dense_*, which
|
193
|
+
// requires an empty key in the constructor.
|
194
|
+
template <class InputIterator>
|
195
|
+
BaseHashtableInterface(InputIterator f, InputIterator l, key_type empty_k,
|
196
|
+
size_type expected_max_items_in_table,
|
197
|
+
const hasher& hf,
|
198
|
+
const key_equal& eql,
|
199
|
+
const allocator_type& alloc)
|
200
|
+
: ht_(f, l, empty_k, expected_max_items_in_table, hf, eql, alloc) {
|
201
|
+
}
|
202
|
+
|
203
|
+
// This is the constructor appropriate for {dense,sparse}hashtable.
|
204
|
+
template <class ExtractKey, class SetKey>
|
205
|
+
BaseHashtableInterface(size_type expected_max_items_in_table,
|
206
|
+
const hasher& hf,
|
207
|
+
const key_equal& eql,
|
208
|
+
const ExtractKey& ek,
|
209
|
+
const SetKey& sk,
|
210
|
+
const allocator_type& alloc)
|
211
|
+
: ht_(expected_max_items_in_table, hf, eql, ek, sk, alloc) { }
|
212
|
+
|
213
|
+
|
214
|
+
void clear() { ht_.clear(); }
|
215
|
+
void swap(BaseHashtableInterface& other) { ht_.swap(other.ht_); }
|
216
|
+
|
217
|
+
// Only part of the API for some hashtable implementations.
|
218
|
+
void clear_no_resize() { clear(); }
|
219
|
+
|
220
|
+
size_type size() const { return ht_.size(); }
|
221
|
+
size_type max_size() const { return ht_.max_size(); }
|
222
|
+
bool empty() const { return ht_.empty(); }
|
223
|
+
size_type bucket_count() const { return ht_.bucket_count(); }
|
224
|
+
size_type max_bucket_count() const { return ht_.max_bucket_count(); }
|
225
|
+
|
226
|
+
size_type bucket_size(size_type i) const {
|
227
|
+
return ht_.bucket_size(i);
|
228
|
+
}
|
229
|
+
size_type bucket(const key_type& key) const {
|
230
|
+
return ht_.bucket(key);
|
231
|
+
}
|
232
|
+
|
233
|
+
float load_factor() const { return ht_.load_factor(); }
|
234
|
+
float max_load_factor() const { return ht_.max_load_factor(); }
|
235
|
+
void max_load_factor(float grow) { ht_.max_load_factor(grow); }
|
236
|
+
float min_load_factor() const { return ht_.min_load_factor(); }
|
237
|
+
void min_load_factor(float shrink) { ht_.min_load_factor(shrink); }
|
238
|
+
void set_resizing_parameters(float shrink, float grow) {
|
239
|
+
ht_.set_resizing_parameters(shrink, grow);
|
240
|
+
}
|
241
|
+
|
242
|
+
void resize(size_type hint) { ht_.resize(hint); }
|
243
|
+
void rehash(size_type hint) { ht_.rehash(hint); }
|
244
|
+
|
245
|
+
iterator find(const key_type& key) {
|
246
|
+
return iterator(ht_.find(key), this);
|
247
|
+
}
|
248
|
+
const_iterator find(const key_type& key) const {
|
249
|
+
return const_iterator(ht_.find(key), this);
|
250
|
+
}
|
251
|
+
|
252
|
+
// Rather than try to implement operator[], which doesn't make much
|
253
|
+
// sense for set types, we implement two methods: bracket_equal and
|
254
|
+
// bracket_assign. By default, bracket_equal(a, b) returns true if
|
255
|
+
// ht[a] == b, and false otherwise. (Note that this follows
|
256
|
+
// operator[] semantics exactly, including inserting a if it's not
|
257
|
+
// already in the hashtable, before doing the equality test.) For
|
258
|
+
// sets, which have no operator[], b is ignored, and bracket_equal
|
259
|
+
// returns true if key is in the set and false otherwise.
|
260
|
+
// bracket_assign(a, b) is equivalent to ht[a] = b. For sets, b is
|
261
|
+
// ignored, and bracket_assign is equivalent to ht.insert(a).
|
262
|
+
template<typename AssignValue>
|
263
|
+
bool bracket_equal(const key_type& key, const AssignValue& expected) {
|
264
|
+
return ht_[key] == expected;
|
265
|
+
}
|
266
|
+
|
267
|
+
template<typename AssignValue>
|
268
|
+
void bracket_assign(const key_type& key, const AssignValue& value) {
|
269
|
+
ht_[key] = value;
|
270
|
+
}
|
271
|
+
|
272
|
+
size_type count(const key_type& key) const { return ht_.count(key); }
|
273
|
+
|
274
|
+
pair<iterator, iterator> equal_range(const key_type& key) {
|
275
|
+
pair<typename HT::iterator, typename HT::iterator> r
|
276
|
+
= ht_.equal_range(key);
|
277
|
+
return pair<iterator, iterator>(iterator(r.first, this),
|
278
|
+
iterator(r.second, this));
|
279
|
+
}
|
280
|
+
pair<const_iterator, const_iterator> equal_range(const key_type& key) const {
|
281
|
+
pair<typename HT::const_iterator, typename HT::const_iterator> r
|
282
|
+
= ht_.equal_range(key);
|
283
|
+
return pair<const_iterator, const_iterator>(const_iterator(r.first, this),
|
284
|
+
const_iterator(r.second, this));
|
285
|
+
}
|
286
|
+
|
287
|
+
const_iterator random_element(class ACMRandom* r) const {
|
288
|
+
return const_iterator(ht_.random_element(r), this);
|
289
|
+
}
|
290
|
+
iterator random_element(class ACMRandom* r) {
|
291
|
+
return iterator(ht_.random_element(r), this);
|
292
|
+
}
|
293
|
+
|
294
|
+
pair<iterator, bool> insert(const value_type& obj) {
|
295
|
+
pair<typename HT::iterator, bool> r = ht_.insert(obj);
|
296
|
+
return pair<iterator, bool>(iterator(r.first, this), r.second);
|
297
|
+
}
|
298
|
+
template <class InputIterator>
|
299
|
+
void insert(InputIterator f, InputIterator l) {
|
300
|
+
ht_.insert(f, l);
|
301
|
+
}
|
302
|
+
void insert(typename HT::const_iterator f, typename HT::const_iterator l) {
|
303
|
+
ht_.insert(f, l);
|
304
|
+
}
|
305
|
+
iterator insert(typename HT::iterator, const value_type& obj) {
|
306
|
+
return iterator(insert(obj).first, this);
|
307
|
+
}
|
308
|
+
|
309
|
+
// These will commonly need to be overridden by the child.
|
310
|
+
void set_empty_key(const key_type& k) { ht_.set_empty_key(k); }
|
311
|
+
void clear_empty_key() { ht_.clear_empty_key(); }
|
312
|
+
key_type empty_key() const { return ht_.empty_key(); }
|
313
|
+
|
314
|
+
void set_deleted_key(const key_type& k) { ht_.set_deleted_key(k); }
|
315
|
+
void clear_deleted_key() { ht_.clear_deleted_key(); }
|
316
|
+
key_type deleted_key() const { return ht_.deleted_key(); }
|
317
|
+
|
318
|
+
size_type erase(const key_type& key) { return ht_.erase(key); }
|
319
|
+
void erase(typename HT::iterator it) { ht_.erase(it); }
|
320
|
+
void erase(typename HT::iterator f, typename HT::iterator l) {
|
321
|
+
ht_.erase(f, l);
|
322
|
+
}
|
323
|
+
|
324
|
+
bool operator==(const BaseHashtableInterface& other) const {
|
325
|
+
return ht_ == other.ht_;
|
326
|
+
}
|
327
|
+
bool operator!=(const BaseHashtableInterface& other) const {
|
328
|
+
return ht_ != other.ht_;
|
329
|
+
}
|
330
|
+
|
331
|
+
template <typename OUTPUT>
|
332
|
+
bool write_metadata(OUTPUT *fp) {
|
333
|
+
return ht_.write_metadata(fp);
|
334
|
+
}
|
335
|
+
template <typename INPUT>
|
336
|
+
bool read_metadata(INPUT *fp) {
|
337
|
+
return ht_.read_metadata(fp);
|
338
|
+
}
|
339
|
+
template <typename OUTPUT>
|
340
|
+
bool write_nopointer_data(OUTPUT *fp) {
|
341
|
+
return ht_.write_nopointer_data(fp);
|
342
|
+
}
|
343
|
+
template <typename INPUT>
|
344
|
+
bool read_nopointer_data(INPUT *fp) {
|
345
|
+
return ht_.read_nopointer_data(fp);
|
346
|
+
}
|
347
|
+
|
348
|
+
// low-level stats
|
349
|
+
int num_table_copies() const { return ht_.num_table_copies(); }
|
350
|
+
|
351
|
+
// Not part of the hashtable API, but is provided to make testing easier.
|
352
|
+
virtual key_type get_key(const value_type& value) const = 0;
|
353
|
+
// All subclasses should define get_data(value_type) as well. I don't
|
354
|
+
// provide an abstract-virtual definition here, because the return type
|
355
|
+
// differs between subclasses (not all subclasses define data_type).
|
356
|
+
//virtual data_type get_data(const value_type& value) const = 0;
|
357
|
+
//virtual data_type default_data() const = 0;
|
358
|
+
|
359
|
+
// These allow introspection into the interface. "Supports" means
|
360
|
+
// that the implementation of this functionality isn't a noop.
|
361
|
+
virtual bool supports_clear_no_resize() const = 0;
|
362
|
+
virtual bool supports_empty_key() const = 0;
|
363
|
+
virtual bool supports_deleted_key() const = 0;
|
364
|
+
virtual bool supports_brackets() const = 0; // has a 'real' operator[]
|
365
|
+
virtual bool supports_readwrite() const = 0;
|
366
|
+
virtual bool supports_num_table_copies() const = 0;
|
367
|
+
|
368
|
+
protected:
|
369
|
+
HT ht_;
|
370
|
+
|
371
|
+
// These are what subclasses have to define to get class-specific behavior
|
372
|
+
virtual key_type it_to_key(const iterator& it) const = 0;
|
373
|
+
virtual key_type it_to_key(const const_iterator& it) const = 0;
|
374
|
+
virtual key_type it_to_key(const local_iterator& it) const = 0;
|
375
|
+
virtual key_type it_to_key(const const_local_iterator& it) const = 0;
|
376
|
+
};
|
377
|
+
|
378
|
+
// ---------------------------------------------------------------------
|
379
|
+
|
380
|
+
template <class Key, class T,
|
381
|
+
class HashFcn = HASH_NAMESPACE::hash<Key>,
|
382
|
+
class EqualKey = STL_NAMESPACE::equal_to<Key>,
|
383
|
+
class Alloc = libc_allocator_with_realloc<pair<const Key, T> > >
|
384
|
+
class HashtableInterface_SparseHashMap
|
385
|
+
: public BaseHashtableInterface< sparse_hash_map<Key, T, HashFcn,
|
386
|
+
EqualKey, Alloc> > {
|
387
|
+
private:
|
388
|
+
typedef sparse_hash_map<Key, T, HashFcn, EqualKey, Alloc> ht;
|
389
|
+
typedef BaseHashtableInterface<ht> p; // parent
|
390
|
+
|
391
|
+
public:
|
392
|
+
explicit HashtableInterface_SparseHashMap(
|
393
|
+
typename p::size_type expected_max_items = 0,
|
394
|
+
const typename p::hasher& hf = typename p::hasher(),
|
395
|
+
const typename p::key_equal& eql = typename p::key_equal(),
|
396
|
+
const typename p::allocator_type& alloc = typename p::allocator_type())
|
397
|
+
: BaseHashtableInterface<ht>(expected_max_items, hf, eql, alloc) { }
|
398
|
+
|
399
|
+
template <class InputIterator>
|
400
|
+
HashtableInterface_SparseHashMap(
|
401
|
+
InputIterator f, InputIterator l,
|
402
|
+
typename p::size_type expected_max_items = 0,
|
403
|
+
const typename p::hasher& hf = typename p::hasher(),
|
404
|
+
const typename p::key_equal& eql = typename p::key_equal(),
|
405
|
+
const typename p::allocator_type& alloc = typename p::allocator_type())
|
406
|
+
: BaseHashtableInterface<ht>(f, l, expected_max_items, hf, eql, alloc) { }
|
407
|
+
|
408
|
+
typename p::key_type get_key(const typename p::value_type& value) const {
|
409
|
+
return value.first;
|
410
|
+
}
|
411
|
+
typename ht::data_type get_data(const typename p::value_type& value) const {
|
412
|
+
return value.second;
|
413
|
+
}
|
414
|
+
typename ht::data_type default_data() const {
|
415
|
+
return typename ht::data_type();
|
416
|
+
}
|
417
|
+
|
418
|
+
bool supports_clear_no_resize() const { return false; }
|
419
|
+
bool supports_empty_key() const { return false; }
|
420
|
+
bool supports_deleted_key() const { return true; }
|
421
|
+
bool supports_brackets() const { return true; }
|
422
|
+
bool supports_readwrite() const { return true; }
|
423
|
+
bool supports_num_table_copies() const { return false; }
|
424
|
+
|
425
|
+
void set_empty_key(const typename p::key_type& k) { }
|
426
|
+
void clear_empty_key() { }
|
427
|
+
typename p::key_type empty_key() const { return typename p::key_type(); }
|
428
|
+
int num_table_copies() const { return 0; }
|
429
|
+
|
430
|
+
protected:
|
431
|
+
template <class K2, class T2, class H2, class E2, class A2>
|
432
|
+
friend void swap(HashtableInterface_SparseHashMap<K2,T2,H2,E2,A2>& a,
|
433
|
+
HashtableInterface_SparseHashMap<K2,T2,H2,E2,A2>& b);
|
434
|
+
|
435
|
+
typename p::key_type it_to_key(const typename p::iterator& it) const {
|
436
|
+
return it->first;
|
437
|
+
}
|
438
|
+
typename p::key_type it_to_key(const typename p::const_iterator& it) const {
|
439
|
+
return it->first;
|
440
|
+
}
|
441
|
+
typename p::key_type it_to_key(const typename p::local_iterator& it) const {
|
442
|
+
return it->first;
|
443
|
+
}
|
444
|
+
typename p::key_type it_to_key(const typename p::const_local_iterator& it)
|
445
|
+
const {
|
446
|
+
return it->first;
|
447
|
+
}
|
448
|
+
};
|
449
|
+
|
450
|
+
template <class K, class T, class H, class E, class A>
|
451
|
+
void swap(HashtableInterface_SparseHashMap<K,T,H,E,A>& a,
|
452
|
+
HashtableInterface_SparseHashMap<K,T,H,E,A>& b) {
|
453
|
+
swap(a.ht_, b.ht_);
|
454
|
+
}
|
455
|
+
|
456
|
+
// ---------------------------------------------------------------------
|
457
|
+
|
458
|
+
template <class Value,
|
459
|
+
class HashFcn = HASH_NAMESPACE::hash<Value>,
|
460
|
+
class EqualKey = STL_NAMESPACE::equal_to<Value>,
|
461
|
+
class Alloc = libc_allocator_with_realloc<Value> >
|
462
|
+
class HashtableInterface_SparseHashSet
|
463
|
+
: public BaseHashtableInterface< sparse_hash_set<Value, HashFcn,
|
464
|
+
EqualKey, Alloc> > {
|
465
|
+
private:
|
466
|
+
typedef sparse_hash_set<Value, HashFcn, EqualKey, Alloc> ht;
|
467
|
+
typedef BaseHashtableInterface<ht> p; // parent
|
468
|
+
|
469
|
+
public:
|
470
|
+
// Bizarrely, MSVC 8.0 has trouble with the (perfectly fine)
|
471
|
+
// typename's in this constructor, and this constructor alone, out
|
472
|
+
// of all the ones in the file. So for MSVC, we take some typenames
|
473
|
+
// out, which is technically invalid C++, but MSVC doesn't seem to
|
474
|
+
// mind.
|
475
|
+
#ifdef _MSC_VER
|
476
|
+
explicit HashtableInterface_SparseHashSet(
|
477
|
+
typename p::size_type expected_max_items = 0,
|
478
|
+
const typename p::hasher& hf = p::hasher(),
|
479
|
+
const typename p::key_equal& eql = p::key_equal(),
|
480
|
+
const typename p::allocator_type& alloc = p::allocator_type())
|
481
|
+
: BaseHashtableInterface<ht>(expected_max_items, hf, eql, alloc) { }
|
482
|
+
#else
|
483
|
+
explicit HashtableInterface_SparseHashSet(
|
484
|
+
typename p::size_type expected_max_items = 0,
|
485
|
+
const typename p::hasher& hf = typename p::hasher(),
|
486
|
+
const typename p::key_equal& eql = typename p::key_equal(),
|
487
|
+
const typename p::allocator_type& alloc = typename p::allocator_type())
|
488
|
+
: BaseHashtableInterface<ht>(expected_max_items, hf, eql, alloc) { }
|
489
|
+
#endif
|
490
|
+
|
491
|
+
template <class InputIterator>
|
492
|
+
HashtableInterface_SparseHashSet(
|
493
|
+
InputIterator f, InputIterator l,
|
494
|
+
typename p::size_type expected_max_items = 0,
|
495
|
+
const typename p::hasher& hf = typename p::hasher(),
|
496
|
+
const typename p::key_equal& eql = typename p::key_equal(),
|
497
|
+
const typename p::allocator_type& alloc = typename p::allocator_type())
|
498
|
+
: BaseHashtableInterface<ht>(f, l, expected_max_items, hf, eql, alloc) { }
|
499
|
+
|
500
|
+
template<typename AssignValue>
|
501
|
+
bool bracket_equal(const typename p::key_type& key, const AssignValue&) {
|
502
|
+
return this->ht_.find(key) != this->ht_.end();
|
503
|
+
}
|
504
|
+
|
505
|
+
template<typename AssignValue>
|
506
|
+
void bracket_assign(const typename p::key_type& key, const AssignValue&) {
|
507
|
+
this->ht_.insert(key);
|
508
|
+
}
|
509
|
+
|
510
|
+
typename p::key_type get_key(const typename p::value_type& value) const {
|
511
|
+
return value;
|
512
|
+
}
|
513
|
+
// For sets, the only 'data' is that an item is actually inserted.
|
514
|
+
bool get_data(const typename p::value_type&) const {
|
515
|
+
return true;
|
516
|
+
}
|
517
|
+
bool default_data() const {
|
518
|
+
return true;
|
519
|
+
}
|
520
|
+
|
521
|
+
bool supports_clear_no_resize() const { return false; }
|
522
|
+
bool supports_empty_key() const { return false; }
|
523
|
+
bool supports_deleted_key() const { return true; }
|
524
|
+
bool supports_brackets() const { return false; }
|
525
|
+
bool supports_readwrite() const { return true; }
|
526
|
+
bool supports_num_table_copies() const { return false; }
|
527
|
+
|
528
|
+
void set_empty_key(const typename p::key_type& k) { }
|
529
|
+
void clear_empty_key() { }
|
530
|
+
typename p::key_type empty_key() const { return typename p::key_type(); }
|
531
|
+
int num_table_copies() const { return 0; }
|
532
|
+
|
533
|
+
protected:
|
534
|
+
template <class K2, class H2, class E2, class A2>
|
535
|
+
friend void swap(HashtableInterface_SparseHashSet<K2,H2,E2,A2>& a,
|
536
|
+
HashtableInterface_SparseHashSet<K2,H2,E2,A2>& b);
|
537
|
+
|
538
|
+
typename p::key_type it_to_key(const typename p::iterator& it) const {
|
539
|
+
return *it;
|
540
|
+
}
|
541
|
+
typename p::key_type it_to_key(const typename p::const_iterator& it) const {
|
542
|
+
return *it;
|
543
|
+
}
|
544
|
+
typename p::key_type it_to_key(const typename p::local_iterator& it) const {
|
545
|
+
return *it;
|
546
|
+
}
|
547
|
+
typename p::key_type it_to_key(const typename p::const_local_iterator& it)
|
548
|
+
const {
|
549
|
+
return *it;
|
550
|
+
}
|
551
|
+
};
|
552
|
+
|
553
|
+
template <class K, class H, class E, class A>
|
554
|
+
void swap(HashtableInterface_SparseHashSet<K,H,E,A>& a,
|
555
|
+
HashtableInterface_SparseHashSet<K,H,E,A>& b) {
|
556
|
+
swap(a.ht_, b.ht_);
|
557
|
+
}
|
558
|
+
|
559
|
+
// ---------------------------------------------------------------------
|
560
|
+
|
561
|
+
template <class Value, class Key, class HashFcn, class ExtractKey,
|
562
|
+
class SetKey, class EqualKey, class Alloc>
|
563
|
+
class HashtableInterface_SparseHashtable
|
564
|
+
: public BaseHashtableInterface< sparse_hashtable<Value, Key, HashFcn,
|
565
|
+
ExtractKey, SetKey,
|
566
|
+
EqualKey, Alloc> > {
|
567
|
+
private:
|
568
|
+
typedef sparse_hashtable<Value, Key, HashFcn, ExtractKey, SetKey,
|
569
|
+
EqualKey, Alloc> ht;
|
570
|
+
typedef BaseHashtableInterface<ht> p; // parent
|
571
|
+
|
572
|
+
public:
|
573
|
+
explicit HashtableInterface_SparseHashtable(
|
574
|
+
typename p::size_type expected_max_items = 0,
|
575
|
+
const typename p::hasher& hf = typename p::hasher(),
|
576
|
+
const typename p::key_equal& eql = typename p::key_equal(),
|
577
|
+
const typename p::allocator_type& alloc = typename p::allocator_type())
|
578
|
+
: BaseHashtableInterface<ht>(expected_max_items, hf, eql,
|
579
|
+
ExtractKey(), SetKey(), alloc) { }
|
580
|
+
|
581
|
+
template <class InputIterator>
|
582
|
+
HashtableInterface_SparseHashtable(
|
583
|
+
InputIterator f, InputIterator l,
|
584
|
+
typename p::size_type expected_max_items = 0,
|
585
|
+
const typename p::hasher& hf = typename p::hasher(),
|
586
|
+
const typename p::key_equal& eql = typename p::key_equal(),
|
587
|
+
const typename p::allocator_type& alloc = typename p::allocator_type())
|
588
|
+
: BaseHashtableInterface<ht>(expected_max_items, hf, eql,
|
589
|
+
ExtractKey(), SetKey(), alloc) {
|
590
|
+
this->insert(f, l);
|
591
|
+
}
|
592
|
+
|
593
|
+
float max_load_factor() const {
|
594
|
+
float shrink, grow;
|
595
|
+
this->ht_.get_resizing_parameters(&shrink, &grow);
|
596
|
+
return grow;
|
597
|
+
}
|
598
|
+
void max_load_factor(float new_grow) {
|
599
|
+
float shrink, grow;
|
600
|
+
this->ht_.get_resizing_parameters(&shrink, &grow);
|
601
|
+
this->ht_.set_resizing_parameters(shrink, new_grow);
|
602
|
+
}
|
603
|
+
float min_load_factor() const {
|
604
|
+
float shrink, grow;
|
605
|
+
this->ht_.get_resizing_parameters(&shrink, &grow);
|
606
|
+
return shrink;
|
607
|
+
}
|
608
|
+
void min_load_factor(float new_shrink) {
|
609
|
+
float shrink, grow;
|
610
|
+
this->ht_.get_resizing_parameters(&shrink, &grow);
|
611
|
+
this->ht_.set_resizing_parameters(new_shrink, grow);
|
612
|
+
}
|
613
|
+
|
614
|
+
template<typename AssignValue>
|
615
|
+
bool bracket_equal(const typename p::key_type&, const AssignValue&) {
|
616
|
+
return false;
|
617
|
+
}
|
618
|
+
|
619
|
+
template<typename AssignValue>
|
620
|
+
void bracket_assign(const typename p::key_type&, const AssignValue&) {
|
621
|
+
}
|
622
|
+
|
623
|
+
typename p::key_type get_key(const typename p::value_type& value) const {
|
624
|
+
return extract_key(value);
|
625
|
+
}
|
626
|
+
typename p::value_type get_data(const typename p::value_type& value) const {
|
627
|
+
return value;
|
628
|
+
}
|
629
|
+
typename p::value_type default_data() const {
|
630
|
+
return typename p::value_type();
|
631
|
+
}
|
632
|
+
|
633
|
+
bool supports_clear_no_resize() const { return false; }
|
634
|
+
bool supports_empty_key() const { return false; }
|
635
|
+
bool supports_deleted_key() const { return true; }
|
636
|
+
bool supports_brackets() const { return false; }
|
637
|
+
bool supports_readwrite() const { return true; }
|
638
|
+
bool supports_num_table_copies() const { return true; }
|
639
|
+
|
640
|
+
void set_empty_key(const typename p::key_type& k) { }
|
641
|
+
void clear_empty_key() { }
|
642
|
+
typename p::key_type empty_key() const { return typename p::key_type(); }
|
643
|
+
|
644
|
+
// These tr1 names aren't defined for sparse_hashtable.
|
645
|
+
typename p::hasher hash_function() { return this->hash_funct(); }
|
646
|
+
void rehash(typename p::size_type hint) { this->resize(hint); }
|
647
|
+
|
648
|
+
// TODO(csilvers): also support/test destructive_begin()/destructive_end()?
|
649
|
+
|
650
|
+
protected:
|
651
|
+
template <class V2, class K2, class HF2, class EK2, class SK2, class Eq2,
|
652
|
+
class A2>
|
653
|
+
friend void swap(
|
654
|
+
HashtableInterface_SparseHashtable<V2,K2,HF2,EK2,SK2,Eq2,A2>& a,
|
655
|
+
HashtableInterface_SparseHashtable<V2,K2,HF2,EK2,SK2,Eq2,A2>& b);
|
656
|
+
|
657
|
+
typename p::key_type it_to_key(const typename p::iterator& it) const {
|
658
|
+
return extract_key(*it);
|
659
|
+
}
|
660
|
+
typename p::key_type it_to_key(const typename p::const_iterator& it) const {
|
661
|
+
return extract_key(*it);
|
662
|
+
}
|
663
|
+
typename p::key_type it_to_key(const typename p::local_iterator& it) const {
|
664
|
+
return extract_key(*it);
|
665
|
+
}
|
666
|
+
typename p::key_type it_to_key(const typename p::const_local_iterator& it)
|
667
|
+
const {
|
668
|
+
return extract_key(*it);
|
669
|
+
}
|
670
|
+
|
671
|
+
private:
|
672
|
+
ExtractKey extract_key;
|
673
|
+
};
|
674
|
+
|
675
|
+
template <class V, class K, class HF, class EK, class SK, class Eq, class A>
|
676
|
+
void swap(HashtableInterface_SparseHashtable<V,K,HF,EK,SK,Eq,A>& a,
|
677
|
+
HashtableInterface_SparseHashtable<V,K,HF,EK,SK,Eq,A>& b) {
|
678
|
+
swap(a.ht_, b.ht_);
|
679
|
+
}
|
680
|
+
|
681
|
+
// ---------------------------------------------------------------------
|
682
|
+
|
683
|
+
// Unlike dense_hash_map, the wrapper class takes an extra template
|
684
|
+
// value saying what the empty key is.
|
685
|
+
|
686
|
+
template <class Key, class T, const Key& EMPTY_KEY,
|
687
|
+
class HashFcn = HASH_NAMESPACE::hash<Key>,
|
688
|
+
class EqualKey = STL_NAMESPACE::equal_to<Key>,
|
689
|
+
class Alloc = libc_allocator_with_realloc<pair<const Key, T> > >
|
690
|
+
class HashtableInterface_DenseHashMap
|
691
|
+
: public BaseHashtableInterface< dense_hash_map<Key, T, HashFcn,
|
692
|
+
EqualKey, Alloc> > {
|
693
|
+
private:
|
694
|
+
typedef dense_hash_map<Key, T, HashFcn, EqualKey, Alloc> ht;
|
695
|
+
typedef BaseHashtableInterface<ht> p; // parent
|
696
|
+
|
697
|
+
public:
|
698
|
+
explicit HashtableInterface_DenseHashMap(
|
699
|
+
typename p::size_type expected_max_items = 0,
|
700
|
+
const typename p::hasher& hf = typename p::hasher(),
|
701
|
+
const typename p::key_equal& eql = typename p::key_equal(),
|
702
|
+
const typename p::allocator_type& alloc = typename p::allocator_type())
|
703
|
+
: BaseHashtableInterface<ht>(expected_max_items, hf, eql, alloc) {
|
704
|
+
this->set_empty_key(EMPTY_KEY);
|
705
|
+
}
|
706
|
+
|
707
|
+
template <class InputIterator>
|
708
|
+
HashtableInterface_DenseHashMap(
|
709
|
+
InputIterator f, InputIterator l,
|
710
|
+
typename p::size_type expected_max_items = 0,
|
711
|
+
const typename p::hasher& hf = typename p::hasher(),
|
712
|
+
const typename p::key_equal& eql = typename p::key_equal(),
|
713
|
+
const typename p::allocator_type& alloc = typename p::allocator_type())
|
714
|
+
: BaseHashtableInterface<ht>(f, l, EMPTY_KEY,
|
715
|
+
expected_max_items, hf, eql, alloc) {
|
716
|
+
}
|
717
|
+
|
718
|
+
void clear_no_resize() { this->ht_.clear_no_resize(); }
|
719
|
+
|
720
|
+
typename p::key_type get_key(const typename p::value_type& value) const {
|
721
|
+
return value.first;
|
722
|
+
}
|
723
|
+
typename ht::data_type get_data(const typename p::value_type& value) const {
|
724
|
+
return value.second;
|
725
|
+
}
|
726
|
+
typename ht::data_type default_data() const {
|
727
|
+
return typename ht::data_type();
|
728
|
+
}
|
729
|
+
|
730
|
+
bool supports_clear_no_resize() const { return true; }
|
731
|
+
bool supports_empty_key() const { return true; }
|
732
|
+
bool supports_deleted_key() const { return true; }
|
733
|
+
bool supports_brackets() const { return true; }
|
734
|
+
bool supports_readwrite() const { return false; }
|
735
|
+
bool supports_num_table_copies() const { return false; }
|
736
|
+
|
737
|
+
template <typename OUTPUT> bool write_metadata(OUTPUT *fp) { return false; }
|
738
|
+
template <typename INPUT> bool read_metadata(INPUT *fp) { return false; }
|
739
|
+
template <typename OUTPUT> bool write_nopointer_data(OUTPUT *) {
|
740
|
+
return false;
|
741
|
+
}
|
742
|
+
template <typename INPUT> bool read_nopointer_data(INPUT *) {
|
743
|
+
return false;
|
744
|
+
}
|
745
|
+
int num_table_copies() const { return 0; }
|
746
|
+
|
747
|
+
protected:
|
748
|
+
template <class K2, class T2, const K2& Empty2, class H2, class E2, class A2>
|
749
|
+
friend void swap(HashtableInterface_DenseHashMap<K2,T2,Empty2,H2,E2,A2>& a,
|
750
|
+
HashtableInterface_DenseHashMap<K2,T2,Empty2,H2,E2,A2>& b);
|
751
|
+
|
752
|
+
typename p::key_type it_to_key(const typename p::iterator& it) const {
|
753
|
+
return it->first;
|
754
|
+
}
|
755
|
+
typename p::key_type it_to_key(const typename p::const_iterator& it) const {
|
756
|
+
return it->first;
|
757
|
+
}
|
758
|
+
typename p::key_type it_to_key(const typename p::local_iterator& it) const {
|
759
|
+
return it->first;
|
760
|
+
}
|
761
|
+
typename p::key_type it_to_key(const typename p::const_local_iterator& it)
|
762
|
+
const {
|
763
|
+
return it->first;
|
764
|
+
}
|
765
|
+
};
|
766
|
+
|
767
|
+
template <class K, class T, const K& Empty, class H, class E, class A>
|
768
|
+
void swap(HashtableInterface_DenseHashMap<K,T,Empty,H,E,A>& a,
|
769
|
+
HashtableInterface_DenseHashMap<K,T,Empty,H,E,A>& b) {
|
770
|
+
swap(a.ht_, b.ht_);
|
771
|
+
}
|
772
|
+
|
773
|
+
// ---------------------------------------------------------------------
|
774
|
+
|
775
|
+
// Unlike dense_hash_set, the wrapper class takes an extra template
|
776
|
+
// value saying what the empty key is.
|
777
|
+
|
778
|
+
template <class Value, const Value& EMPTY_KEY,
|
779
|
+
class HashFcn = HASH_NAMESPACE::hash<Value>,
|
780
|
+
class EqualKey = STL_NAMESPACE::equal_to<Value>,
|
781
|
+
class Alloc = libc_allocator_with_realloc<Value> >
|
782
|
+
class HashtableInterface_DenseHashSet
|
783
|
+
: public BaseHashtableInterface< dense_hash_set<Value, HashFcn,
|
784
|
+
EqualKey, Alloc> > {
|
785
|
+
private:
|
786
|
+
typedef dense_hash_set<Value, HashFcn, EqualKey, Alloc> ht;
|
787
|
+
typedef BaseHashtableInterface<ht> p; // parent
|
788
|
+
|
789
|
+
public:
|
790
|
+
explicit HashtableInterface_DenseHashSet(
|
791
|
+
typename p::size_type expected_max_items = 0,
|
792
|
+
const typename p::hasher& hf = typename p::hasher(),
|
793
|
+
const typename p::key_equal& eql = typename p::key_equal(),
|
794
|
+
const typename p::allocator_type& alloc = typename p::allocator_type())
|
795
|
+
: BaseHashtableInterface<ht>(expected_max_items, hf, eql, alloc) {
|
796
|
+
this->set_empty_key(EMPTY_KEY);
|
797
|
+
}
|
798
|
+
|
799
|
+
template <class InputIterator>
|
800
|
+
HashtableInterface_DenseHashSet(
|
801
|
+
InputIterator f, InputIterator l,
|
802
|
+
typename p::size_type expected_max_items = 0,
|
803
|
+
const typename p::hasher& hf = typename p::hasher(),
|
804
|
+
const typename p::key_equal& eql = typename p::key_equal(),
|
805
|
+
const typename p::allocator_type& alloc = typename p::allocator_type())
|
806
|
+
: BaseHashtableInterface<ht>(f, l, EMPTY_KEY,
|
807
|
+
expected_max_items, hf, eql, alloc) {
|
808
|
+
}
|
809
|
+
|
810
|
+
void clear_no_resize() { this->ht_.clear_no_resize(); }
|
811
|
+
|
812
|
+
template<typename AssignValue>
|
813
|
+
bool bracket_equal(const typename p::key_type& key, const AssignValue&) {
|
814
|
+
return this->ht_.find(key) != this->ht_.end();
|
815
|
+
}
|
816
|
+
|
817
|
+
template<typename AssignValue>
|
818
|
+
void bracket_assign(const typename p::key_type& key, const AssignValue&) {
|
819
|
+
this->ht_.insert(key);
|
820
|
+
}
|
821
|
+
|
822
|
+
typename p::key_type get_key(const typename p::value_type& value) const {
|
823
|
+
return value;
|
824
|
+
}
|
825
|
+
bool get_data(const typename p::value_type&) const {
|
826
|
+
return true;
|
827
|
+
}
|
828
|
+
bool default_data() const {
|
829
|
+
return true;
|
830
|
+
}
|
831
|
+
|
832
|
+
bool supports_clear_no_resize() const { return true; }
|
833
|
+
bool supports_empty_key() const { return true; }
|
834
|
+
bool supports_deleted_key() const { return true; }
|
835
|
+
bool supports_brackets() const { return false; }
|
836
|
+
bool supports_readwrite() const { return false; }
|
837
|
+
bool supports_num_table_copies() const { return false; }
|
838
|
+
|
839
|
+
template <typename OUTPUT> bool write_metadata(OUTPUT *fp) { return false; }
|
840
|
+
template <typename INPUT> bool read_metadata(INPUT *fp) { return false; }
|
841
|
+
template <typename OUTPUT> bool write_nopointer_data(OUTPUT *) {
|
842
|
+
return false;
|
843
|
+
}
|
844
|
+
template <typename INPUT> bool read_nopointer_data(INPUT *) {
|
845
|
+
return false;
|
846
|
+
}
|
847
|
+
int num_table_copies() const { return 0; }
|
848
|
+
|
849
|
+
protected:
|
850
|
+
template <class K2, const K2& Empty2, class H2, class E2, class A2>
|
851
|
+
friend void swap(HashtableInterface_DenseHashSet<K2,Empty2,H2,E2,A2>& a,
|
852
|
+
HashtableInterface_DenseHashSet<K2,Empty2,H2,E2,A2>& b);
|
853
|
+
|
854
|
+
typename p::key_type it_to_key(const typename p::iterator& it) const {
|
855
|
+
return *it;
|
856
|
+
}
|
857
|
+
typename p::key_type it_to_key(const typename p::const_iterator& it) const {
|
858
|
+
return *it;
|
859
|
+
}
|
860
|
+
typename p::key_type it_to_key(const typename p::local_iterator& it) const {
|
861
|
+
return *it;
|
862
|
+
}
|
863
|
+
typename p::key_type it_to_key(const typename p::const_local_iterator& it)
|
864
|
+
const {
|
865
|
+
return *it;
|
866
|
+
}
|
867
|
+
};
|
868
|
+
|
869
|
+
template <class K, const K& Empty, class H, class E, class A>
|
870
|
+
void swap(HashtableInterface_DenseHashSet<K,Empty,H,E,A>& a,
|
871
|
+
HashtableInterface_DenseHashSet<K,Empty,H,E,A>& b) {
|
872
|
+
swap(a.ht_, b.ht_);
|
873
|
+
}
|
874
|
+
|
875
|
+
// ---------------------------------------------------------------------
|
876
|
+
|
877
|
+
// Unlike dense_hashtable, the wrapper class takes an extra template
|
878
|
+
// value saying what the empty key is.
|
879
|
+
|
880
|
+
template <class Value, class Key, const Key& EMPTY_KEY, class HashFcn,
|
881
|
+
class ExtractKey, class SetKey, class EqualKey, class Alloc>
|
882
|
+
class HashtableInterface_DenseHashtable
|
883
|
+
: public BaseHashtableInterface< dense_hashtable<Value, Key, HashFcn,
|
884
|
+
ExtractKey, SetKey,
|
885
|
+
EqualKey, Alloc> > {
|
886
|
+
private:
|
887
|
+
typedef dense_hashtable<Value, Key, HashFcn, ExtractKey, SetKey,
|
888
|
+
EqualKey, Alloc> ht;
|
889
|
+
typedef BaseHashtableInterface<ht> p; // parent
|
890
|
+
|
891
|
+
public:
|
892
|
+
explicit HashtableInterface_DenseHashtable(
|
893
|
+
typename p::size_type expected_max_items = 0,
|
894
|
+
const typename p::hasher& hf = typename p::hasher(),
|
895
|
+
const typename p::key_equal& eql = typename p::key_equal(),
|
896
|
+
const typename p::allocator_type& alloc = typename p::allocator_type())
|
897
|
+
: BaseHashtableInterface<ht>(expected_max_items, hf, eql,
|
898
|
+
ExtractKey(), SetKey(), alloc) {
|
899
|
+
this->set_empty_key(EMPTY_KEY);
|
900
|
+
}
|
901
|
+
|
902
|
+
template <class InputIterator>
|
903
|
+
HashtableInterface_DenseHashtable(
|
904
|
+
InputIterator f, InputIterator l,
|
905
|
+
typename p::size_type expected_max_items = 0,
|
906
|
+
const typename p::hasher& hf = typename p::hasher(),
|
907
|
+
const typename p::key_equal& eql = typename p::key_equal(),
|
908
|
+
const typename p::allocator_type& alloc = typename p::allocator_type())
|
909
|
+
: BaseHashtableInterface<ht>(expected_max_items, hf, eql,
|
910
|
+
ExtractKey(), SetKey(), alloc) {
|
911
|
+
this->set_empty_key(EMPTY_KEY);
|
912
|
+
this->insert(f, l);
|
913
|
+
}
|
914
|
+
|
915
|
+
void clear_no_resize() { this->ht_.clear_no_resize(); }
|
916
|
+
|
917
|
+
float max_load_factor() const {
|
918
|
+
float shrink, grow;
|
919
|
+
this->ht_.get_resizing_parameters(&shrink, &grow);
|
920
|
+
return grow;
|
921
|
+
}
|
922
|
+
void max_load_factor(float new_grow) {
|
923
|
+
float shrink, grow;
|
924
|
+
this->ht_.get_resizing_parameters(&shrink, &grow);
|
925
|
+
this->ht_.set_resizing_parameters(shrink, new_grow);
|
926
|
+
}
|
927
|
+
float min_load_factor() const {
|
928
|
+
float shrink, grow;
|
929
|
+
this->ht_.get_resizing_parameters(&shrink, &grow);
|
930
|
+
return shrink;
|
931
|
+
}
|
932
|
+
void min_load_factor(float new_shrink) {
|
933
|
+
float shrink, grow;
|
934
|
+
this->ht_.get_resizing_parameters(&shrink, &grow);
|
935
|
+
this->ht_.set_resizing_parameters(new_shrink, grow);
|
936
|
+
}
|
937
|
+
|
938
|
+
template<typename AssignValue>
|
939
|
+
bool bracket_equal(const typename p::key_type&, const AssignValue&) {
|
940
|
+
return false;
|
941
|
+
}
|
942
|
+
|
943
|
+
template<typename AssignValue>
|
944
|
+
void bracket_assign(const typename p::key_type&, const AssignValue&) {
|
945
|
+
}
|
946
|
+
|
947
|
+
typename p::key_type get_key(const typename p::value_type& value) const {
|
948
|
+
return extract_key(value);
|
949
|
+
}
|
950
|
+
typename p::value_type get_data(const typename p::value_type& value) const {
|
951
|
+
return value;
|
952
|
+
}
|
953
|
+
typename p::value_type default_data() const {
|
954
|
+
return typename p::value_type();
|
955
|
+
}
|
956
|
+
|
957
|
+
bool supports_clear_no_resize() const { return true; }
|
958
|
+
bool supports_empty_key() const { return true; }
|
959
|
+
bool supports_deleted_key() const { return true; }
|
960
|
+
bool supports_brackets() const { return false; }
|
961
|
+
bool supports_readwrite() const { return false; }
|
962
|
+
bool supports_num_table_copies() const { return true; }
|
963
|
+
|
964
|
+
template <typename OUTPUT> bool write_metadata(OUTPUT *fp) { return false; }
|
965
|
+
template <typename INPUT> bool read_metadata(INPUT *fp) { return false; }
|
966
|
+
template <typename OUTPUT> bool write_nopointer_data(OUTPUT *) {
|
967
|
+
return false;
|
968
|
+
}
|
969
|
+
template <typename INPUT> bool read_nopointer_data(INPUT *) {
|
970
|
+
return false;
|
971
|
+
}
|
972
|
+
|
973
|
+
// These tr1 names aren't defined for dense_hashtable.
|
974
|
+
typename p::hasher hash_function() { return this->hash_funct(); }
|
975
|
+
void rehash(typename p::size_type hint) { this->resize(hint); }
|
976
|
+
|
977
|
+
protected:
|
978
|
+
template <class V2, class K2, const K2& Empty2,
|
979
|
+
class HF2, class EK2, class SK2, class Eq2, class A2>
|
980
|
+
friend void swap(
|
981
|
+
HashtableInterface_DenseHashtable<V2,K2,Empty2,HF2,EK2,SK2,Eq2,A2>& a,
|
982
|
+
HashtableInterface_DenseHashtable<V2,K2,Empty2,HF2,EK2,SK2,Eq2,A2>& b);
|
983
|
+
|
984
|
+
typename p::key_type it_to_key(const typename p::iterator& it) const {
|
985
|
+
return extract_key(*it);
|
986
|
+
}
|
987
|
+
typename p::key_type it_to_key(const typename p::const_iterator& it) const {
|
988
|
+
return extract_key(*it);
|
989
|
+
}
|
990
|
+
typename p::key_type it_to_key(const typename p::local_iterator& it) const {
|
991
|
+
return extract_key(*it);
|
992
|
+
}
|
993
|
+
typename p::key_type it_to_key(const typename p::const_local_iterator& it)
|
994
|
+
const {
|
995
|
+
return extract_key(*it);
|
996
|
+
}
|
997
|
+
|
998
|
+
private:
|
999
|
+
ExtractKey extract_key;
|
1000
|
+
};
|
1001
|
+
|
1002
|
+
template <class V, class K, const K& Empty,
|
1003
|
+
class HF, class EK, class SK, class Eq, class A>
|
1004
|
+
void swap(HashtableInterface_DenseHashtable<V,K,Empty,HF,EK,SK,Eq,A>& a,
|
1005
|
+
HashtableInterface_DenseHashtable<V,K,Empty,HF,EK,SK,Eq,A>& b) {
|
1006
|
+
swap(a.ht_, b.ht_);
|
1007
|
+
}
|
1008
|
+
|
1009
|
+
_END_GOOGLE_NAMESPACE_
|
1010
|
+
|
1011
|
+
#endif // UTIL_GTL_HASH_TEST_INTERFACE_H_
|