google_hash 0.8.1 → 0.8.2
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog.txt +2 -0
- data/VERSION +1 -1
- data/ext/clean.bat +0 -0
- data/ext/clean.sh +4 -0
- data/ext/extconf.rb +4 -5
- data/ext/go.bat +0 -0
- data/ext/sparsehash-2.0.2/AUTHORS +2 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/COPYING +0 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/ChangeLog +60 -0
- data/ext/sparsehash-2.0.2/INSTALL +365 -0
- data/ext/sparsehash-2.0.2/Makefile +1336 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/Makefile.am +97 -40
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/Makefile.in +538 -256
- data/ext/sparsehash-2.0.2/NEWS +188 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/README +4 -10
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/README_windows.txt +3 -3
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/TODO +0 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/aclocal.m4 +266 -166
- data/ext/sparsehash-2.0.2/allocator.patch +31 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/config.guess +235 -234
- data/ext/sparsehash-2.0.2/config.status +1238 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/config.sub +198 -64
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/configure +1118 -1000
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/configure.ac +4 -5
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/depcomp +136 -36
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/doc/dense_hash_map.html +182 -67
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/doc/dense_hash_set.html +173 -74
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/doc/designstyle.css +0 -6
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/doc/implementation.html +0 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/doc/index.html +4 -5
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/doc/performance.html +1 -1
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/doc/sparse_hash_map.html +190 -58
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/doc/sparse_hash_set.html +180 -65
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/doc/sparsetable.html +1 -1
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/experimental/Makefile +0 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/experimental/README +0 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/experimental/example.c +1 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/experimental/libchash.c +1 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/experimental/libchash.h +1 -0
- data/ext/sparsehash-2.0.2/install-sh +520 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/m4/acx_pthread.m4 +34 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/m4/google_namespace.m4 +0 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/m4/namespaces.m4 +0 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/m4/stl_hash.m4 +0 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/m4/stl_hash_fun.m4 +0 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/missing +60 -44
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/packages/deb.sh +0 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/packages/deb/README +0 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/packages/deb/changelog +42 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/packages/deb/compat +0 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/packages/deb/control +1 -1
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/packages/deb/copyright +5 -4
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/packages/deb/docs +0 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/packages/deb/rules +0 -0
- data/ext/sparsehash-2.0.2/packages/deb/sparsehash.dirs +5 -0
- data/ext/sparsehash-2.0.2/packages/deb/sparsehash.install +6 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/packages/rpm.sh +1 -1
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/packages/rpm/rpm.spec +5 -3
- data/ext/{sparsehash-1.8.1/google-sparsehash.sln → sparsehash-2.0.2/sparsehash.sln} +0 -0
- data/ext/sparsehash-2.0.2/src/config.h +132 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/src/config.h.in +0 -3
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/src/config.h.include +0 -1
- data/ext/sparsehash-2.0.2/src/google/dense_hash_map +34 -0
- data/ext/sparsehash-2.0.2/src/google/dense_hash_set +34 -0
- data/ext/sparsehash-2.0.2/src/google/sparse_hash_map +34 -0
- data/ext/sparsehash-2.0.2/src/google/sparse_hash_set +34 -0
- data/ext/sparsehash-2.0.2/src/google/sparsehash/densehashtable.h +34 -0
- data/ext/sparsehash-2.0.2/src/google/sparsehash/hashtable-common.h +34 -0
- data/ext/sparsehash-2.0.2/src/google/sparsehash/libc_allocator_with_realloc.h +34 -0
- data/ext/sparsehash-2.0.2/src/google/sparsehash/sparsehashtable.h +34 -0
- data/ext/sparsehash-2.0.2/src/google/sparsetable +34 -0
- data/ext/sparsehash-2.0.2/src/google/template_util.h +34 -0
- data/ext/sparsehash-2.0.2/src/google/type_traits.h +34 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/src/hash_test_interface.h +64 -37
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/src/hashtable_test.cc +415 -141
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/src/libc_allocator_with_realloc_test.cc +16 -23
- data/ext/sparsehash-2.0.2/src/simple_compat_test.cc +106 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/src/simple_test.cc +8 -5
- data/ext/{sparsehash-1.8.1/src/google → sparsehash-2.0.2/src/sparsehash}/dense_hash_map +80 -37
- data/ext/{sparsehash-1.8.1/src/google → sparsehash-2.0.2/src/sparsehash}/dense_hash_set +64 -34
- data/ext/{sparsehash-1.8.1/src/google/sparsehash → sparsehash-2.0.2/src/sparsehash/internal}/densehashtable.h +247 -173
- data/ext/sparsehash-2.0.2/src/sparsehash/internal/hashtable-common.h +381 -0
- data/ext/{sparsehash-1.8.1/src/google/sparsehash → sparsehash-2.0.2/src/sparsehash/internal}/libc_allocator_with_realloc.h +5 -7
- data/ext/{sparsehash-1.8.1/src/google/sparsehash → sparsehash-2.0.2/src/sparsehash/internal}/sparsehashtable.h +154 -93
- data/ext/{sparsehash-1.8.1/src/google → sparsehash-2.0.2/src/sparsehash}/sparse_hash_map +96 -36
- data/ext/{sparsehash-1.8.1/src/google → sparsehash-2.0.2/src/sparsehash}/sparse_hash_set +85 -32
- data/ext/{sparsehash-1.8.1/src/google → sparsehash-2.0.2/src/sparsehash}/sparsetable +520 -258
- data/ext/sparsehash-2.0.2/src/sparsehash/template_util.h +134 -0
- data/ext/{sparsehash-1.8.1/src/google → sparsehash-2.0.2/src/sparsehash}/type_traits.h +153 -35
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/src/sparsetable_unittest.cc +108 -22
- data/ext/sparsehash-2.0.2/src/stamp-h1 +1 -0
- data/ext/sparsehash-2.0.2/src/template_util_unittest.cc +134 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/src/testutil.h +16 -1
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/src/time_hash_map.cc +259 -94
- data/ext/sparsehash-2.0.2/src/type_traits_unittest.cc +636 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/src/windows/config.h +4 -4
- data/ext/sparsehash-2.0.2/src/windows/google/sparsehash/sparseconfig.h +49 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/src/windows/port.cc +1 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/src/windows/port.h +4 -13
- data/ext/sparsehash-2.0.2/src/windows/sparsehash/internal/sparseconfig.h +49 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/vsprojects/hashtable_test/hashtable_test.vcproj +11 -11
- data/ext/sparsehash-2.0.2/vsprojects/libc_allocator_with_realloc_test/libc_allocator_with_realloc_test.vcproj +161 -0
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/vsprojects/simple_test/simple_test.vcproj +10 -10
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/vsprojects/sparsetable_unittest/sparsetable_unittest.vcproj +4 -4
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/vsprojects/time_hash_map/time_hash_map.vcproj +10 -10
- data/ext/{sparsehash-1.8.1 → sparsehash-2.0.2}/vsprojects/type_traits_unittest/type_traits_unittest.vcproj +3 -3
- data/ext/spec.bat +0 -0
- data/ext/template/google_hash.cpp.erb +6 -5
- metadata +106 -86
- data/ext/sparsehash-1.8.1/AUTHORS +0 -2
- data/ext/sparsehash-1.8.1/INSTALL +0 -236
- data/ext/sparsehash-1.8.1/NEWS +0 -71
- data/ext/sparsehash-1.8.1/compile +0 -99
- data/ext/sparsehash-1.8.1/install-sh +0 -323
- data/ext/sparsehash-1.8.1/m4/stl_namespace.m4 +0 -25
- data/ext/sparsehash-1.8.1/mkinstalldirs +0 -158
- data/ext/sparsehash-1.8.1/packages/deb/sparsehash.dirs +0 -2
- data/ext/sparsehash-1.8.1/packages/deb/sparsehash.install +0 -2
- data/ext/sparsehash-1.8.1/src/google/sparsehash/hashtable-common.h +0 -178
- data/ext/sparsehash-1.8.1/src/type_traits_unittest.cc +0 -502
- data/ext/sparsehash-1.8.1/src/windows/google/sparsehash/sparseconfig.h +0 -32
@@ -0,0 +1,34 @@
|
|
1
|
+
// Copyright (c) 2012, 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
|
+
// Header files have moved from the google directory to the sparsehash
|
31
|
+
// directory. This forwarding file is provided only for backwards
|
32
|
+
// compatibility. Use <sparsehash/*> in all new code.
|
33
|
+
|
34
|
+
#include <sparsehash/template_util.h>
|
@@ -0,0 +1,34 @@
|
|
1
|
+
// Copyright (c) 2012, 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
|
+
// Header files have moved from the google directory to the sparsehash
|
31
|
+
// directory. This forwarding file is provided only for backwards
|
32
|
+
// compatibility. Use <sparsehash/*> in all new code.
|
33
|
+
|
34
|
+
#include <sparsehash/type_traits.h>
|
@@ -27,8 +27,7 @@
|
|
27
27
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
28
28
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
29
29
|
|
30
|
-
//
|
31
|
-
// Author: Craig Silverstein
|
30
|
+
// ---
|
32
31
|
//
|
33
32
|
// This implements a uniform interface for all 6 hash implementations:
|
34
33
|
// dense_hashtable, dense_hash_map, dense_hash_set
|
@@ -46,15 +45,15 @@
|
|
46
45
|
#ifndef UTIL_GTL_HASH_TEST_INTERFACE_H_
|
47
46
|
#define UTIL_GTL_HASH_TEST_INTERFACE_H_
|
48
47
|
|
49
|
-
#include
|
50
|
-
#include
|
51
|
-
#include <
|
52
|
-
#include <
|
53
|
-
#include <
|
54
|
-
#include <
|
55
|
-
#include <
|
56
|
-
#include <
|
57
|
-
#include
|
48
|
+
#include <sparsehash/internal/sparseconfig.h>
|
49
|
+
#include <functional> // for equal_to<>
|
50
|
+
#include <sparsehash/internal/sparsehashtable.h>
|
51
|
+
#include <sparsehash/sparse_hash_map>
|
52
|
+
#include <sparsehash/sparse_hash_set>
|
53
|
+
#include <sparsehash/internal/densehashtable.h>
|
54
|
+
#include <sparsehash/dense_hash_map>
|
55
|
+
#include <sparsehash/dense_hash_set>
|
56
|
+
#include HASH_FUN_H // for hash<>
|
58
57
|
|
59
58
|
_START_GOOGLE_NAMESPACE_
|
60
59
|
|
@@ -271,17 +270,18 @@ class BaseHashtableInterface {
|
|
271
270
|
|
272
271
|
size_type count(const key_type& key) const { return ht_.count(key); }
|
273
272
|
|
274
|
-
pair<iterator, iterator> equal_range(const key_type& key) {
|
275
|
-
pair<typename HT::iterator, typename HT::iterator> r
|
273
|
+
std::pair<iterator, iterator> equal_range(const key_type& key) {
|
274
|
+
std::pair<typename HT::iterator, typename HT::iterator> r
|
276
275
|
= ht_.equal_range(key);
|
277
|
-
return pair<iterator, iterator>(iterator(r.first, this),
|
276
|
+
return std::pair<iterator, iterator>(iterator(r.first, this),
|
278
277
|
iterator(r.second, this));
|
279
278
|
}
|
280
|
-
pair<const_iterator, const_iterator> equal_range(const key_type& key)
|
281
|
-
|
279
|
+
std::pair<const_iterator, const_iterator> equal_range(const key_type& key)
|
280
|
+
const {
|
281
|
+
std::pair<typename HT::const_iterator, typename HT::const_iterator> r
|
282
282
|
= ht_.equal_range(key);
|
283
|
-
return pair<const_iterator, const_iterator>(
|
284
|
-
|
283
|
+
return std::pair<const_iterator, const_iterator>(
|
284
|
+
const_iterator(r.first, this), const_iterator(r.second, this));
|
285
285
|
}
|
286
286
|
|
287
287
|
const_iterator random_element(class ACMRandom* r) const {
|
@@ -291,9 +291,9 @@ class BaseHashtableInterface {
|
|
291
291
|
return iterator(ht_.random_element(r), this);
|
292
292
|
}
|
293
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);
|
294
|
+
std::pair<iterator, bool> insert(const value_type& obj) {
|
295
|
+
std::pair<typename HT::iterator, bool> r = ht_.insert(obj);
|
296
|
+
return std::pair<iterator, bool>(iterator(r.first, this), r.second);
|
297
297
|
}
|
298
298
|
template <class InputIterator>
|
299
299
|
void insert(InputIterator f, InputIterator l) {
|
@@ -328,6 +328,15 @@ class BaseHashtableInterface {
|
|
328
328
|
return ht_ != other.ht_;
|
329
329
|
}
|
330
330
|
|
331
|
+
template <typename ValueSerializer, typename OUTPUT>
|
332
|
+
bool serialize(ValueSerializer serializer, OUTPUT *fp) {
|
333
|
+
return ht_.serialize(serializer, fp);
|
334
|
+
}
|
335
|
+
template <typename ValueSerializer, typename INPUT>
|
336
|
+
bool unserialize(ValueSerializer serializer, INPUT *fp) {
|
337
|
+
return ht_.unserialize(serializer, fp);
|
338
|
+
}
|
339
|
+
|
331
340
|
template <typename OUTPUT>
|
332
341
|
bool write_metadata(OUTPUT *fp) {
|
333
342
|
return ht_.write_metadata(fp);
|
@@ -364,6 +373,7 @@ class BaseHashtableInterface {
|
|
364
373
|
virtual bool supports_brackets() const = 0; // has a 'real' operator[]
|
365
374
|
virtual bool supports_readwrite() const = 0;
|
366
375
|
virtual bool supports_num_table_copies() const = 0;
|
376
|
+
virtual bool supports_serialization() const = 0;
|
367
377
|
|
368
378
|
protected:
|
369
379
|
HT ht_;
|
@@ -378,9 +388,9 @@ class BaseHashtableInterface {
|
|
378
388
|
// ---------------------------------------------------------------------
|
379
389
|
|
380
390
|
template <class Key, class T,
|
381
|
-
class HashFcn =
|
382
|
-
class EqualKey =
|
383
|
-
class Alloc = libc_allocator_with_realloc<pair<const Key, T> > >
|
391
|
+
class HashFcn = SPARSEHASH_HASH<Key>,
|
392
|
+
class EqualKey = std::equal_to<Key>,
|
393
|
+
class Alloc = libc_allocator_with_realloc<std::pair<const Key, T> > >
|
384
394
|
class HashtableInterface_SparseHashMap
|
385
395
|
: public BaseHashtableInterface< sparse_hash_map<Key, T, HashFcn,
|
386
396
|
EqualKey, Alloc> > {
|
@@ -421,12 +431,16 @@ class HashtableInterface_SparseHashMap
|
|
421
431
|
bool supports_brackets() const { return true; }
|
422
432
|
bool supports_readwrite() const { return true; }
|
423
433
|
bool supports_num_table_copies() const { return false; }
|
434
|
+
bool supports_serialization() const { return true; }
|
424
435
|
|
425
436
|
void set_empty_key(const typename p::key_type& k) { }
|
426
437
|
void clear_empty_key() { }
|
427
438
|
typename p::key_type empty_key() const { return typename p::key_type(); }
|
439
|
+
|
428
440
|
int num_table_copies() const { return 0; }
|
429
441
|
|
442
|
+
typedef typename ht::NopointerSerializer NopointerSerializer;
|
443
|
+
|
430
444
|
protected:
|
431
445
|
template <class K2, class T2, class H2, class E2, class A2>
|
432
446
|
friend void swap(HashtableInterface_SparseHashMap<K2,T2,H2,E2,A2>& a,
|
@@ -456,8 +470,8 @@ void swap(HashtableInterface_SparseHashMap<K,T,H,E,A>& a,
|
|
456
470
|
// ---------------------------------------------------------------------
|
457
471
|
|
458
472
|
template <class Value,
|
459
|
-
class HashFcn =
|
460
|
-
class EqualKey =
|
473
|
+
class HashFcn = SPARSEHASH_HASH<Value>,
|
474
|
+
class EqualKey = std::equal_to<Value>,
|
461
475
|
class Alloc = libc_allocator_with_realloc<Value> >
|
462
476
|
class HashtableInterface_SparseHashSet
|
463
477
|
: public BaseHashtableInterface< sparse_hash_set<Value, HashFcn,
|
@@ -524,12 +538,16 @@ class HashtableInterface_SparseHashSet
|
|
524
538
|
bool supports_brackets() const { return false; }
|
525
539
|
bool supports_readwrite() const { return true; }
|
526
540
|
bool supports_num_table_copies() const { return false; }
|
541
|
+
bool supports_serialization() const { return true; }
|
527
542
|
|
528
543
|
void set_empty_key(const typename p::key_type& k) { }
|
529
544
|
void clear_empty_key() { }
|
530
545
|
typename p::key_type empty_key() const { return typename p::key_type(); }
|
546
|
+
|
531
547
|
int num_table_copies() const { return 0; }
|
532
548
|
|
549
|
+
typedef typename ht::NopointerSerializer NopointerSerializer;
|
550
|
+
|
533
551
|
protected:
|
534
552
|
template <class K2, class H2, class E2, class A2>
|
535
553
|
friend void swap(HashtableInterface_SparseHashSet<K2,H2,E2,A2>& a,
|
@@ -636,6 +654,7 @@ class HashtableInterface_SparseHashtable
|
|
636
654
|
bool supports_brackets() const { return false; }
|
637
655
|
bool supports_readwrite() const { return true; }
|
638
656
|
bool supports_num_table_copies() const { return true; }
|
657
|
+
bool supports_serialization() const { return true; }
|
639
658
|
|
640
659
|
void set_empty_key(const typename p::key_type& k) { }
|
641
660
|
void clear_empty_key() { }
|
@@ -647,6 +666,8 @@ class HashtableInterface_SparseHashtable
|
|
647
666
|
|
648
667
|
// TODO(csilvers): also support/test destructive_begin()/destructive_end()?
|
649
668
|
|
669
|
+
typedef typename ht::NopointerSerializer NopointerSerializer;
|
670
|
+
|
650
671
|
protected:
|
651
672
|
template <class V2, class K2, class HF2, class EK2, class SK2, class Eq2,
|
652
673
|
class A2>
|
@@ -684,9 +705,9 @@ void swap(HashtableInterface_SparseHashtable<V,K,HF,EK,SK,Eq,A>& a,
|
|
684
705
|
// value saying what the empty key is.
|
685
706
|
|
686
707
|
template <class Key, class T, const Key& EMPTY_KEY,
|
687
|
-
class HashFcn =
|
688
|
-
class EqualKey =
|
689
|
-
class Alloc = libc_allocator_with_realloc<pair<const Key, T> > >
|
708
|
+
class HashFcn = SPARSEHASH_HASH<Key>,
|
709
|
+
class EqualKey = std::equal_to<Key>,
|
710
|
+
class Alloc = libc_allocator_with_realloc<std::pair<const Key, T> > >
|
690
711
|
class HashtableInterface_DenseHashMap
|
691
712
|
: public BaseHashtableInterface< dense_hash_map<Key, T, HashFcn,
|
692
713
|
EqualKey, Alloc> > {
|
@@ -733,9 +754,11 @@ class HashtableInterface_DenseHashMap
|
|
733
754
|
bool supports_brackets() const { return true; }
|
734
755
|
bool supports_readwrite() const { return false; }
|
735
756
|
bool supports_num_table_copies() const { return false; }
|
757
|
+
bool supports_serialization() const { return true; }
|
736
758
|
|
737
|
-
|
738
|
-
template <typename
|
759
|
+
typedef typename ht::NopointerSerializer NopointerSerializer;
|
760
|
+
template <typename OUTPUT> bool write_metadata(OUTPUT *) { return false; }
|
761
|
+
template <typename INPUT> bool read_metadata(INPUT *) { return false; }
|
739
762
|
template <typename OUTPUT> bool write_nopointer_data(OUTPUT *) {
|
740
763
|
return false;
|
741
764
|
}
|
@@ -776,8 +799,8 @@ void swap(HashtableInterface_DenseHashMap<K,T,Empty,H,E,A>& a,
|
|
776
799
|
// value saying what the empty key is.
|
777
800
|
|
778
801
|
template <class Value, const Value& EMPTY_KEY,
|
779
|
-
class HashFcn =
|
780
|
-
class EqualKey =
|
802
|
+
class HashFcn = SPARSEHASH_HASH<Value>,
|
803
|
+
class EqualKey = std::equal_to<Value>,
|
781
804
|
class Alloc = libc_allocator_with_realloc<Value> >
|
782
805
|
class HashtableInterface_DenseHashSet
|
783
806
|
: public BaseHashtableInterface< dense_hash_set<Value, HashFcn,
|
@@ -835,9 +858,11 @@ class HashtableInterface_DenseHashSet
|
|
835
858
|
bool supports_brackets() const { return false; }
|
836
859
|
bool supports_readwrite() const { return false; }
|
837
860
|
bool supports_num_table_copies() const { return false; }
|
861
|
+
bool supports_serialization() const { return true; }
|
838
862
|
|
839
|
-
|
840
|
-
template <typename
|
863
|
+
typedef typename ht::NopointerSerializer NopointerSerializer;
|
864
|
+
template <typename OUTPUT> bool write_metadata(OUTPUT *) { return false; }
|
865
|
+
template <typename INPUT> bool read_metadata(INPUT *) { return false; }
|
841
866
|
template <typename OUTPUT> bool write_nopointer_data(OUTPUT *) {
|
842
867
|
return false;
|
843
868
|
}
|
@@ -960,9 +985,11 @@ class HashtableInterface_DenseHashtable
|
|
960
985
|
bool supports_brackets() const { return false; }
|
961
986
|
bool supports_readwrite() const { return false; }
|
962
987
|
bool supports_num_table_copies() const { return true; }
|
988
|
+
bool supports_serialization() const { return true; }
|
963
989
|
|
964
|
-
|
965
|
-
template <typename
|
990
|
+
typedef typename ht::NopointerSerializer NopointerSerializer;
|
991
|
+
template <typename OUTPUT> bool write_metadata(OUTPUT *) { return false; }
|
992
|
+
template <typename INPUT> bool read_metadata(INPUT *) { return false; }
|
966
993
|
template <typename OUTPUT> bool write_nopointer_data(OUTPUT *) {
|
967
994
|
return false;
|
968
995
|
}
|
@@ -27,71 +27,86 @@
|
|
27
27
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
28
28
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
29
29
|
|
30
|
-
//
|
31
|
-
// Author: Craig Silverstein
|
30
|
+
// ---
|
32
31
|
//
|
33
|
-
// This tests
|
34
|
-
// This tests
|
35
|
-
// This tests
|
36
|
-
// This tests
|
37
|
-
// This tests
|
38
|
-
// This tests
|
32
|
+
// This tests densehashtable
|
33
|
+
// This tests dense_hash_set
|
34
|
+
// This tests dense_hash_map
|
35
|
+
// This tests sparsehashtable
|
36
|
+
// This tests sparse_hash_set
|
37
|
+
// This tests sparse_hash_map
|
39
38
|
//
|
40
|
-
// This test
|
41
|
-
// unreadable.
|
39
|
+
// This test replaces hashtable_unittest.cc, which was becoming
|
40
|
+
// unreadable. This file is opaque but hopefully not unreadable -- at
|
41
|
+
// least, not the tests!
|
42
42
|
//
|
43
43
|
// Note that since all these classes are templatized, it's important
|
44
44
|
// to call every public method on the class: not just to make sure
|
45
45
|
// they work, but to make sure they even compile.
|
46
46
|
|
47
|
-
#
|
48
|
-
|
49
|
-
// This causes some "type conversion too small" errors when using this
|
50
|
-
// allocator with sparsetable buckets. We're testing to make sure we
|
51
|
-
// handle that situation ok, so we don't need the compiler warnings.
|
52
|
-
#pragma warning(disable:4244)
|
53
|
-
#endif
|
54
|
-
|
55
|
-
#include "config.h"
|
47
|
+
#include <sparsehash/internal/sparseconfig.h>
|
48
|
+
#include <config.h>
|
56
49
|
#include <math.h>
|
50
|
+
#include <stddef.h> // for size_t
|
57
51
|
#include <stdlib.h>
|
58
52
|
#include <string.h>
|
53
|
+
#ifdef HAVE_STDINT_H
|
54
|
+
# include <stdint.h>
|
55
|
+
#endif // for uintptr_t
|
59
56
|
#include <iostream>
|
60
57
|
#include <set>
|
58
|
+
#include <sstream>
|
59
|
+
#include <typeinfo> // for class typeinfo (returned by typeid)
|
61
60
|
#include <vector>
|
62
|
-
#include <
|
63
|
-
#include <
|
61
|
+
#include <sparsehash/type_traits.h>
|
62
|
+
#include <sparsehash/sparsetable>
|
64
63
|
#include "hash_test_interface.h"
|
65
64
|
#include "testutil.h"
|
65
|
+
namespace testing = GOOGLE_NAMESPACE::testing;
|
66
66
|
|
67
|
-
using
|
68
|
-
using
|
69
|
-
using
|
67
|
+
using std::cout;
|
68
|
+
using std::pair;
|
69
|
+
using std::set;
|
70
|
+
using std::string;
|
71
|
+
using std::vector;
|
70
72
|
using GOOGLE_NAMESPACE::dense_hash_map;
|
71
73
|
using GOOGLE_NAMESPACE::dense_hash_set;
|
74
|
+
using GOOGLE_NAMESPACE::sparse_hash_map;
|
75
|
+
using GOOGLE_NAMESPACE::sparse_hash_set;
|
76
|
+
using GOOGLE_NAMESPACE::sparsetable;
|
72
77
|
using GOOGLE_NAMESPACE::HashtableInterface_SparseHashMap;
|
73
78
|
using GOOGLE_NAMESPACE::HashtableInterface_SparseHashSet;
|
74
79
|
using GOOGLE_NAMESPACE::HashtableInterface_SparseHashtable;
|
75
80
|
using GOOGLE_NAMESPACE::HashtableInterface_DenseHashMap;
|
76
81
|
using GOOGLE_NAMESPACE::HashtableInterface_DenseHashSet;
|
77
82
|
using GOOGLE_NAMESPACE::HashtableInterface_DenseHashtable;
|
78
|
-
namespace
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
83
|
+
namespace sparsehash_internal = GOOGLE_NAMESPACE::sparsehash_internal;
|
84
|
+
|
85
|
+
typedef unsigned char uint8;
|
86
|
+
|
87
|
+
#ifdef _MSC_VER
|
88
|
+
// Below, we purposefully test having a very small allocator size.
|
89
|
+
// This causes some "type conversion too small" errors when using this
|
90
|
+
// allocator with sparsetable buckets. We're testing to make sure we
|
91
|
+
// handle that situation ok, so we don't need the compiler warnings.
|
92
|
+
#pragma warning(disable:4244)
|
93
|
+
#endif
|
84
94
|
|
85
95
|
namespace {
|
86
96
|
|
87
97
|
#ifndef _MSC_VER // windows defines its own version
|
98
|
+
# ifdef __MINGW32__ // mingw has trouble writing to /tmp
|
99
|
+
static string TmpFile(const char* basename) {
|
100
|
+
return string("./#") + basename;
|
101
|
+
}
|
102
|
+
# else
|
88
103
|
static string TmpFile(const char* basename) {
|
89
|
-
|
104
|
+
string kTmpdir = "/tmp";
|
105
|
+
return kTmpdir + "/" + basename;
|
90
106
|
}
|
107
|
+
# endif
|
91
108
|
#endif
|
92
109
|
|
93
|
-
typedef unsigned char uint8;
|
94
|
-
|
95
110
|
// Used as a value in some of the hashtable tests. It's just some
|
96
111
|
// arbitrary user-defined type with non-trivial memory management.
|
97
112
|
struct ValueType {
|
@@ -161,6 +176,10 @@ struct Hasher {
|
|
161
176
|
hash = 33 * hash + a[i];
|
162
177
|
return hash;
|
163
178
|
}
|
179
|
+
size_t operator()(const int* a) const {
|
180
|
+
num_hashes_++;
|
181
|
+
return static_cast<size_t>(reinterpret_cast<uintptr_t>(a));
|
182
|
+
}
|
164
183
|
bool operator()(int a, int b) const {
|
165
184
|
num_compares_++;
|
166
185
|
return a == b;
|
@@ -257,11 +276,13 @@ struct Alloc {
|
|
257
276
|
// be their own inverse: f(f(x)) == x.
|
258
277
|
template<class Value>
|
259
278
|
struct Negation {
|
279
|
+
typedef Value result_type;
|
260
280
|
Value operator()(Value& v) { return -v; }
|
261
281
|
const Value operator()(const Value& v) const { return -v; }
|
262
282
|
};
|
263
283
|
|
264
284
|
struct Capital {
|
285
|
+
typedef string result_type;
|
265
286
|
string operator()(string& s) {
|
266
287
|
return string(1, s[0] ^ 32) + s.substr(1);
|
267
288
|
}
|
@@ -271,6 +292,7 @@ struct Capital {
|
|
271
292
|
};
|
272
293
|
|
273
294
|
struct Identity { // lame, I know, but an important case to test.
|
295
|
+
typedef const char* result_type;
|
274
296
|
const char* operator()(const char* s) const {
|
275
297
|
return s;
|
276
298
|
}
|
@@ -328,8 +350,67 @@ template<> pair<const char* const,ValueType> UniqueObjectHelper(int index) {
|
|
328
350
|
UniqueObjectHelper<char*>(index), UniqueObjectHelper<ValueType>(index+1));
|
329
351
|
}
|
330
352
|
|
353
|
+
class ValueSerializer {
|
354
|
+
public:
|
355
|
+
bool operator()(FILE* fp, const int& value) {
|
356
|
+
return fwrite(&value, sizeof(value), 1, fp) == 1;
|
357
|
+
}
|
358
|
+
bool operator()(FILE* fp, int* value) {
|
359
|
+
return fread(value, sizeof(*value), 1, fp) == 1;
|
360
|
+
}
|
361
|
+
bool operator()(FILE* fp, const string& value) {
|
362
|
+
const int size = value.size();
|
363
|
+
return (*this)(fp, size) && fwrite(value.c_str(), size, 1, fp) == 1;
|
364
|
+
}
|
365
|
+
bool operator()(FILE* fp, string* value) {
|
366
|
+
int size;
|
367
|
+
if (!(*this)(fp, &size)) return false;
|
368
|
+
char* buf = new char[size];
|
369
|
+
if (fread(buf, size, 1, fp) != 1) {
|
370
|
+
delete[] buf;
|
371
|
+
return false;
|
372
|
+
}
|
373
|
+
new(value) string(buf, size);
|
374
|
+
delete[] buf;
|
375
|
+
return true;
|
376
|
+
}
|
377
|
+
template <typename OUTPUT>
|
378
|
+
bool operator()(OUTPUT* fp, const ValueType& v) {
|
379
|
+
return (*this)(fp, string(v.s()));
|
380
|
+
}
|
381
|
+
template <typename INPUT>
|
382
|
+
bool operator()(INPUT* fp, ValueType* v) {
|
383
|
+
string data;
|
384
|
+
if (!(*this)(fp, &data)) return false;
|
385
|
+
new(v) ValueType(data.c_str());
|
386
|
+
return true;
|
387
|
+
}
|
388
|
+
template <typename OUTPUT>
|
389
|
+
bool operator()(OUTPUT* fp, const char* const& value) {
|
390
|
+
// Just store the index.
|
391
|
+
return (*this)(fp, atoi(value));
|
392
|
+
}
|
393
|
+
template <typename INPUT>
|
394
|
+
bool operator()(INPUT* fp, const char** value) {
|
395
|
+
// Look up via index.
|
396
|
+
int index;
|
397
|
+
if (!(*this)(fp, &index)) return false;
|
398
|
+
*value = UniqueObjectHelper<char*>(index);
|
399
|
+
return true;
|
400
|
+
}
|
401
|
+
template <typename OUTPUT, typename First, typename Second>
|
402
|
+
bool operator()(OUTPUT* fp, std::pair<const First, Second>* value) {
|
403
|
+
return (*this)(fp, const_cast<First*>(&value->first))
|
404
|
+
&& (*this)(fp, &value->second);
|
405
|
+
}
|
406
|
+
template <typename INPUT, typename First, typename Second>
|
407
|
+
bool operator()(INPUT* fp, const std::pair<const First, Second>& value) {
|
408
|
+
return (*this)(fp, value.first) && (*this)(fp, value.second);
|
409
|
+
}
|
410
|
+
};
|
411
|
+
|
331
412
|
template <typename HashtableType>
|
332
|
-
class HashtableTest {
|
413
|
+
class HashtableTest : public ::testing::Test {
|
333
414
|
public:
|
334
415
|
HashtableTest() : ht_() { }
|
335
416
|
// Give syntactically-prettier access to UniqueObjectHelper.
|
@@ -419,27 +500,58 @@ namespace {
|
|
419
500
|
// We need to define the same class 4 times due to limitations in the
|
420
501
|
// testing framework. Basically, we associate each class below with
|
421
502
|
// the set of types we want to run tests on it with.
|
422
|
-
typedef testing::TypeList6<INT_HASHTABLES> IntHashtables;
|
423
503
|
template <typename HashtableType> class HashtableIntTest
|
424
504
|
: public HashtableTest<HashtableType> { };
|
425
|
-
TYPED_TEST_CASE_6(HashtableIntTest, IntHashtables);
|
426
|
-
|
427
|
-
typedef testing::TypeList6<STRING_HASHTABLES> StringHashtables;
|
428
505
|
template <typename HashtableType> class HashtableStringTest
|
429
506
|
: public HashtableTest<HashtableType> { };
|
430
|
-
TYPED_TEST_CASE_6(HashtableStringTest, StringHashtables);
|
431
|
-
|
432
|
-
typedef testing::TypeList6<CHARSTAR_HASHTABLES> CharStarHashtables;
|
433
507
|
template <typename HashtableType> class HashtableCharStarTest
|
434
508
|
: public HashtableTest<HashtableType> { };
|
435
|
-
|
509
|
+
template <typename HashtableType> class HashtableAllTest
|
510
|
+
: public HashtableTest<HashtableType> { };
|
436
511
|
|
512
|
+
typedef testing::TypeList6<INT_HASHTABLES> IntHashtables;
|
513
|
+
typedef testing::TypeList6<STRING_HASHTABLES> StringHashtables;
|
514
|
+
typedef testing::TypeList6<CHARSTAR_HASHTABLES> CharStarHashtables;
|
437
515
|
typedef testing::TypeList18<INT_HASHTABLES, STRING_HASHTABLES,
|
438
516
|
CHARSTAR_HASHTABLES> AllHashtables;
|
439
|
-
|
440
|
-
|
517
|
+
|
518
|
+
TYPED_TEST_CASE_6(HashtableIntTest, IntHashtables);
|
519
|
+
TYPED_TEST_CASE_6(HashtableStringTest, StringHashtables);
|
520
|
+
TYPED_TEST_CASE_6(HashtableCharStarTest, CharStarHashtables);
|
441
521
|
TYPED_TEST_CASE_18(HashtableAllTest, AllHashtables);
|
442
522
|
|
523
|
+
// ------------------------------------------------------------------------
|
524
|
+
// First, some testing of the underlying infrastructure.
|
525
|
+
|
526
|
+
TEST(HashtableCommonTest, HashMunging) {
|
527
|
+
const Hasher hasher;
|
528
|
+
|
529
|
+
// We don't munge the hash value on non-pointer template types.
|
530
|
+
{
|
531
|
+
const sparsehash_internal::sh_hashtable_settings<int, Hasher, size_t, 1>
|
532
|
+
settings(hasher, 0.0, 0.0);
|
533
|
+
const int v = 1000;
|
534
|
+
EXPECT_EQ(hasher(v), settings.hash(v));
|
535
|
+
}
|
536
|
+
|
537
|
+
{
|
538
|
+
// We do munge the hash value on pointer template types.
|
539
|
+
const sparsehash_internal::sh_hashtable_settings<int*, Hasher, size_t, 1>
|
540
|
+
settings(hasher, 0.0, 0.0);
|
541
|
+
int* v = NULL;
|
542
|
+
v += 0x10000; // get a non-trivial pointer value
|
543
|
+
EXPECT_NE(hasher(v), settings.hash(v));
|
544
|
+
}
|
545
|
+
{
|
546
|
+
const sparsehash_internal::sh_hashtable_settings<const int*, Hasher,
|
547
|
+
size_t, 1>
|
548
|
+
settings(hasher, 0.0, 0.0);
|
549
|
+
const int* v = NULL;
|
550
|
+
v += 0x10000; // get a non-trivial pointer value
|
551
|
+
EXPECT_NE(hasher(v), settings.hash(v));
|
552
|
+
}
|
553
|
+
}
|
554
|
+
|
443
555
|
// ------------------------------------------------------------------------
|
444
556
|
// If the first arg to TYPED_TEST is HashtableIntTest, it will run
|
445
557
|
// this test on all the hashtable types, with key=int and value=int.
|
@@ -624,18 +736,20 @@ TYPED_TEST(HashtableIntTest, Constructors) {
|
|
624
736
|
EXPECT_LE(1, alloc_count);
|
625
737
|
int old_alloc_count = alloc_count;
|
626
738
|
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
TypeParam
|
635
|
-
TypeParam
|
636
|
-
TypeParam
|
637
|
-
TypeParam
|
638
|
-
|
739
|
+
const typename TypeParam::value_type input[] = {
|
740
|
+
this->UniqueObject(1),
|
741
|
+
this->UniqueObject(2),
|
742
|
+
this->UniqueObject(4),
|
743
|
+
this->UniqueObject(8)
|
744
|
+
};
|
745
|
+
const int num_inputs = sizeof(input) / sizeof(input[0]);
|
746
|
+
const typename TypeParam::value_type *begin = &input[0];
|
747
|
+
const typename TypeParam::value_type *end = begin + num_inputs;
|
748
|
+
TypeParam ht_iter_noarg(begin, end);
|
749
|
+
TypeParam ht_iter_onearg(begin, end, 100);
|
750
|
+
TypeParam ht_iter_twoarg(begin, end, 100, hasher);
|
751
|
+
TypeParam ht_iter_threearg(begin, end, 100, hasher, hasher);
|
752
|
+
TypeParam ht_iter_fourarg(begin, end, 100, hasher, hasher, alloc);
|
639
753
|
// Now the allocator should have been called more.
|
640
754
|
EXPECT_GT(alloc_count, old_alloc_count);
|
641
755
|
old_alloc_count = alloc_count;
|
@@ -781,7 +895,7 @@ TYPED_TEST(HashtableAllTest, Swap) {
|
|
781
895
|
|
782
896
|
// We purposefully don't swap allocs -- they're not necessarily swappable.
|
783
897
|
|
784
|
-
// Now swap back, using the free-function swap
|
898
|
+
// Now swap back, using the free-function swap
|
785
899
|
// NOTE: MSVC seems to have trouble with this free swap, not quite
|
786
900
|
// sure why. I've given up trying to fix it though.
|
787
901
|
#ifdef _MSC_VER
|
@@ -798,6 +912,20 @@ TYPED_TEST(HashtableAllTest, Swap) {
|
|
798
912
|
EXPECT_EQ(1u, other_ht.size());
|
799
913
|
EXPECT_EQ(1u, this->ht_.count(this->UniqueKey(111)));
|
800
914
|
EXPECT_EQ(0u, other_ht.count(this->UniqueKey(111)));
|
915
|
+
|
916
|
+
// A user reported a crash with this code using swap to clear.
|
917
|
+
// We've since fixed the bug; this prevents a regression.
|
918
|
+
TypeParam swap_to_clear_ht;
|
919
|
+
swap_to_clear_ht.set_deleted_key(this->UniqueKey(1));
|
920
|
+
for (int i = 2; i < 10000; ++i) {
|
921
|
+
swap_to_clear_ht.insert(this->UniqueObject(i));
|
922
|
+
}
|
923
|
+
TypeParam empty_ht;
|
924
|
+
empty_ht.swap(swap_to_clear_ht);
|
925
|
+
swap_to_clear_ht.set_deleted_key(this->UniqueKey(1));
|
926
|
+
for (int i = 2; i < 10000; ++i) {
|
927
|
+
swap_to_clear_ht.insert(this->UniqueObject(i));
|
928
|
+
}
|
801
929
|
}
|
802
930
|
|
803
931
|
TYPED_TEST(HashtableAllTest, Size) {
|
@@ -1073,6 +1201,7 @@ TYPED_TEST(HashtableAllTest, BracketInsert) {
|
|
1073
1201
|
EXPECT_EQ(2, ht.hash_funct().num_hashes());
|
1074
1202
|
}
|
1075
1203
|
|
1204
|
+
|
1076
1205
|
TYPED_TEST(HashtableAllTest, InsertValue) {
|
1077
1206
|
// First, try some straightforward insertions.
|
1078
1207
|
EXPECT_TRUE(this->ht_.empty());
|
@@ -1111,13 +1240,13 @@ TYPED_TEST(HashtableIntTest, InsertRange) {
|
|
1111
1240
|
ht_source.insert(this->UniqueObject(100000));
|
1112
1241
|
ht_source.insert(this->UniqueObject(1000000));
|
1113
1242
|
|
1114
|
-
|
1115
|
-
|
1116
|
-
|
1117
|
-
|
1118
|
-
|
1119
|
-
|
1120
|
-
|
1243
|
+
const typename TypeParam::value_type input[] = {
|
1244
|
+
// This is a copy of the first element in ht_source.
|
1245
|
+
*ht_source.begin(),
|
1246
|
+
this->UniqueObject(2),
|
1247
|
+
this->UniqueObject(4),
|
1248
|
+
this->UniqueObject(8)
|
1249
|
+
};
|
1121
1250
|
|
1122
1251
|
set<typename TypeParam::value_type> set_input;
|
1123
1252
|
set_input.insert(this->UniqueObject(1111111));
|
@@ -1152,7 +1281,7 @@ TYPED_TEST(HashtableIntTest, InsertRange) {
|
|
1152
1281
|
// Insert from input as well, a separate, random-access iterator.
|
1153
1282
|
// The first element of input overlaps with an existing element
|
1154
1283
|
// of ht_, so this should only up the size by 2.
|
1155
|
-
this->ht_.insert(input
|
1284
|
+
this->ht_.insert(&input[0], &input[3]);
|
1156
1285
|
EXPECT_EQ(8u, this->ht_.size());
|
1157
1286
|
}
|
1158
1287
|
|
@@ -1298,10 +1427,9 @@ TYPED_TEST(HashtableAllTest, Equals) {
|
|
1298
1427
|
}
|
1299
1428
|
|
1300
1429
|
TEST(HashtableTest, IntIO) {
|
1301
|
-
// Since
|
1302
|
-
// just
|
1303
|
-
//
|
1304
|
-
// standard reader and writer.
|
1430
|
+
// Since the set case is just a special (easier) case than the map case, I
|
1431
|
+
// just test on sparse_hash_map. This handles the easy case where we can
|
1432
|
+
// use the standard reader and writer.
|
1305
1433
|
sparse_hash_map<int, int> ht_out;
|
1306
1434
|
ht_out.set_deleted_key(0);
|
1307
1435
|
for (int i = 1; i < 1000; i++) {
|
@@ -1310,7 +1438,7 @@ TEST(HashtableTest, IntIO) {
|
|
1310
1438
|
ht_out.erase(563); // just to test having some erased keys when we write.
|
1311
1439
|
ht_out.erase(22);
|
1312
1440
|
|
1313
|
-
string file(TmpFile("
|
1441
|
+
string file(TmpFile("intio"));
|
1314
1442
|
FILE* fp = fopen(file.c_str(), "wb");
|
1315
1443
|
EXPECT_TRUE(fp != NULL);
|
1316
1444
|
EXPECT_TRUE(ht_out.write_metadata(fp));
|
@@ -1333,10 +1461,9 @@ TEST(HashtableTest, IntIO) {
|
|
1333
1461
|
}
|
1334
1462
|
|
1335
1463
|
TEST(HashtableTest, StringIO) {
|
1336
|
-
// Since
|
1337
|
-
// just
|
1338
|
-
//
|
1339
|
-
// to write our own custom reader/writer for the data.
|
1464
|
+
// Since the set case is just a special (easier) case than the map case,
|
1465
|
+
// I just test on sparse_hash_map. This handles the difficult case where
|
1466
|
+
// we have to write our own custom reader/writer for the data.
|
1340
1467
|
sparse_hash_map<string, string, Hasher, Hasher> ht_out;
|
1341
1468
|
ht_out.set_deleted_key(string(""));
|
1342
1469
|
for (int i = 32; i < 128; i++) {
|
@@ -1346,7 +1473,7 @@ TEST(HashtableTest, StringIO) {
|
|
1346
1473
|
ht_out.erase("c"); // just to test having some erased keys when we write.
|
1347
1474
|
ht_out.erase("y");
|
1348
1475
|
|
1349
|
-
string file(TmpFile("
|
1476
|
+
string file(TmpFile("stringio"));
|
1350
1477
|
FILE* fp = fopen(file.c_str(), "wb");
|
1351
1478
|
EXPECT_TRUE(fp != NULL);
|
1352
1479
|
EXPECT_TRUE(ht_out.write_metadata(fp));
|
@@ -1369,14 +1496,14 @@ TEST(HashtableTest, StringIO) {
|
|
1369
1496
|
for (sparse_hash_map<string, string, Hasher, Hasher>::iterator
|
1370
1497
|
it = ht_in.begin(); it != ht_in.end(); ++it) {
|
1371
1498
|
string::size_type first_size;
|
1372
|
-
fread(&first_size, sizeof(first_size), 1, fp);
|
1499
|
+
EXPECT_EQ(1u, fread(&first_size, sizeof(first_size), 1, fp));
|
1373
1500
|
char* first = new char[first_size];
|
1374
|
-
fread(first, first_size, 1, fp);
|
1501
|
+
EXPECT_EQ(1u, fread(first, first_size, 1, fp));
|
1375
1502
|
|
1376
1503
|
string::size_type second_size;
|
1377
|
-
fread(&second_size, sizeof(second_size), 1, fp);
|
1504
|
+
EXPECT_EQ(1u, fread(&second_size, sizeof(second_size), 1, fp));
|
1378
1505
|
char* second = new char[second_size];
|
1379
|
-
fread(second, second_size, 1, fp);
|
1506
|
+
EXPECT_EQ(1u, fread(second, second_size, 1, fp));
|
1380
1507
|
|
1381
1508
|
// it points to garbage, so we have to use placement-new to initialize.
|
1382
1509
|
// We also have to use const-cast since it->first is const.
|
@@ -1393,6 +1520,195 @@ TEST(HashtableTest, StringIO) {
|
|
1393
1520
|
EXPECT_EQ(string(""), ht_in["y"]);
|
1394
1521
|
}
|
1395
1522
|
|
1523
|
+
TYPED_TEST(HashtableAllTest, Serialization) {
|
1524
|
+
if (!this->ht_.supports_serialization()) return;
|
1525
|
+
TypeParam ht_out;
|
1526
|
+
ht_out.set_deleted_key(this->UniqueKey(2000));
|
1527
|
+
for (int i = 1; i < 100; i++) {
|
1528
|
+
ht_out.insert(this->UniqueObject(i));
|
1529
|
+
}
|
1530
|
+
// just to test having some erased keys when we write.
|
1531
|
+
ht_out.erase(this->UniqueKey(56));
|
1532
|
+
ht_out.erase(this->UniqueKey(22));
|
1533
|
+
|
1534
|
+
string file(TmpFile("serialization"));
|
1535
|
+
FILE* fp = fopen(file.c_str(), "wb");
|
1536
|
+
EXPECT_TRUE(fp != NULL);
|
1537
|
+
EXPECT_TRUE(ht_out.serialize(ValueSerializer(), fp));
|
1538
|
+
fclose(fp);
|
1539
|
+
|
1540
|
+
TypeParam ht_in;
|
1541
|
+
fp = fopen(file.c_str(), "rb");
|
1542
|
+
EXPECT_TRUE(fp != NULL);
|
1543
|
+
EXPECT_TRUE(ht_in.unserialize(ValueSerializer(), fp));
|
1544
|
+
fclose(fp);
|
1545
|
+
|
1546
|
+
EXPECT_EQ(this->UniqueObject(1), *ht_in.find(this->UniqueKey(1)));
|
1547
|
+
EXPECT_EQ(this->UniqueObject(99), *ht_in.find(this->UniqueKey(99)));
|
1548
|
+
EXPECT_FALSE(ht_in.count(this->UniqueKey(100)));
|
1549
|
+
EXPECT_EQ(this->UniqueObject(21), *ht_in.find(this->UniqueKey(21)));
|
1550
|
+
// should not have been saved
|
1551
|
+
EXPECT_FALSE(ht_in.count(this->UniqueKey(22)));
|
1552
|
+
EXPECT_FALSE(ht_in.count(this->UniqueKey(56)));
|
1553
|
+
}
|
1554
|
+
|
1555
|
+
TYPED_TEST(HashtableIntTest, NopointerSerialization) {
|
1556
|
+
if (!this->ht_.supports_serialization()) return;
|
1557
|
+
TypeParam ht_out;
|
1558
|
+
ht_out.set_deleted_key(this->UniqueKey(2000));
|
1559
|
+
for (int i = 1; i < 100; i++) {
|
1560
|
+
ht_out.insert(this->UniqueObject(i));
|
1561
|
+
}
|
1562
|
+
// just to test having some erased keys when we write.
|
1563
|
+
ht_out.erase(this->UniqueKey(56));
|
1564
|
+
ht_out.erase(this->UniqueKey(22));
|
1565
|
+
|
1566
|
+
string file(TmpFile("nopointer_serialization"));
|
1567
|
+
FILE* fp = fopen(file.c_str(), "wb");
|
1568
|
+
EXPECT_TRUE(fp != NULL);
|
1569
|
+
EXPECT_TRUE(ht_out.serialize(typename TypeParam::NopointerSerializer(), fp));
|
1570
|
+
fclose(fp);
|
1571
|
+
|
1572
|
+
TypeParam ht_in;
|
1573
|
+
fp = fopen(file.c_str(), "rb");
|
1574
|
+
EXPECT_TRUE(fp != NULL);
|
1575
|
+
EXPECT_TRUE(ht_in.unserialize(typename TypeParam::NopointerSerializer(), fp));
|
1576
|
+
fclose(fp);
|
1577
|
+
|
1578
|
+
EXPECT_EQ(this->UniqueObject(1), *ht_in.find(this->UniqueKey(1)));
|
1579
|
+
EXPECT_EQ(this->UniqueObject(99), *ht_in.find(this->UniqueKey(99)));
|
1580
|
+
EXPECT_FALSE(ht_in.count(this->UniqueKey(100)));
|
1581
|
+
EXPECT_EQ(this->UniqueObject(21), *ht_in.find(this->UniqueKey(21)));
|
1582
|
+
// should not have been saved
|
1583
|
+
EXPECT_FALSE(ht_in.count(this->UniqueKey(22)));
|
1584
|
+
EXPECT_FALSE(ht_in.count(this->UniqueKey(56)));
|
1585
|
+
}
|
1586
|
+
|
1587
|
+
// We don't support serializing to a string by default, but you can do
|
1588
|
+
// it by writing your own custom input/output class.
|
1589
|
+
class StringIO {
|
1590
|
+
public:
|
1591
|
+
explicit StringIO(string* s) : s_(s) {}
|
1592
|
+
size_t Write(const void* buf, size_t len) {
|
1593
|
+
s_->append(reinterpret_cast<const char*>(buf), len);
|
1594
|
+
return len;
|
1595
|
+
}
|
1596
|
+
size_t Read(void* buf, size_t len) {
|
1597
|
+
if (s_->length() < len)
|
1598
|
+
len = s_->length();
|
1599
|
+
memcpy(reinterpret_cast<char*>(buf), s_->data(), len);
|
1600
|
+
s_->erase(0, len);
|
1601
|
+
return len;
|
1602
|
+
}
|
1603
|
+
private:
|
1604
|
+
string* const s_;
|
1605
|
+
};
|
1606
|
+
|
1607
|
+
TYPED_TEST(HashtableIntTest, SerializingToString) {
|
1608
|
+
if (!this->ht_.supports_serialization()) return;
|
1609
|
+
TypeParam ht_out;
|
1610
|
+
ht_out.set_deleted_key(this->UniqueKey(2000));
|
1611
|
+
for (int i = 1; i < 100; i++) {
|
1612
|
+
ht_out.insert(this->UniqueObject(i));
|
1613
|
+
}
|
1614
|
+
// just to test having some erased keys when we write.
|
1615
|
+
ht_out.erase(this->UniqueKey(56));
|
1616
|
+
ht_out.erase(this->UniqueKey(22));
|
1617
|
+
|
1618
|
+
string stringbuf;
|
1619
|
+
StringIO stringio(&stringbuf);
|
1620
|
+
EXPECT_TRUE(ht_out.serialize(typename TypeParam::NopointerSerializer(),
|
1621
|
+
&stringio));
|
1622
|
+
|
1623
|
+
TypeParam ht_in;
|
1624
|
+
EXPECT_TRUE(ht_in.unserialize(typename TypeParam::NopointerSerializer(),
|
1625
|
+
&stringio));
|
1626
|
+
|
1627
|
+
EXPECT_EQ(this->UniqueObject(1), *ht_in.find(this->UniqueKey(1)));
|
1628
|
+
EXPECT_EQ(this->UniqueObject(99), *ht_in.find(this->UniqueKey(99)));
|
1629
|
+
EXPECT_FALSE(ht_in.count(this->UniqueKey(100)));
|
1630
|
+
EXPECT_EQ(this->UniqueObject(21), *ht_in.find(this->UniqueKey(21)));
|
1631
|
+
// should not have been saved
|
1632
|
+
EXPECT_FALSE(ht_in.count(this->UniqueKey(22)));
|
1633
|
+
EXPECT_FALSE(ht_in.count(this->UniqueKey(56)));
|
1634
|
+
}
|
1635
|
+
|
1636
|
+
// An easier way to do the above would be to use the existing stream methods.
|
1637
|
+
TYPED_TEST(HashtableIntTest, SerializingToStringStream) {
|
1638
|
+
if (!this->ht_.supports_serialization()) return;
|
1639
|
+
TypeParam ht_out;
|
1640
|
+
ht_out.set_deleted_key(this->UniqueKey(2000));
|
1641
|
+
for (int i = 1; i < 100; i++) {
|
1642
|
+
ht_out.insert(this->UniqueObject(i));
|
1643
|
+
}
|
1644
|
+
// just to test having some erased keys when we write.
|
1645
|
+
ht_out.erase(this->UniqueKey(56));
|
1646
|
+
ht_out.erase(this->UniqueKey(22));
|
1647
|
+
|
1648
|
+
std::stringstream string_buffer;
|
1649
|
+
EXPECT_TRUE(ht_out.serialize(typename TypeParam::NopointerSerializer(),
|
1650
|
+
&string_buffer));
|
1651
|
+
|
1652
|
+
TypeParam ht_in;
|
1653
|
+
EXPECT_TRUE(ht_in.unserialize(typename TypeParam::NopointerSerializer(),
|
1654
|
+
&string_buffer));
|
1655
|
+
|
1656
|
+
EXPECT_EQ(this->UniqueObject(1), *ht_in.find(this->UniqueKey(1)));
|
1657
|
+
EXPECT_EQ(this->UniqueObject(99), *ht_in.find(this->UniqueKey(99)));
|
1658
|
+
EXPECT_FALSE(ht_in.count(this->UniqueKey(100)));
|
1659
|
+
EXPECT_EQ(this->UniqueObject(21), *ht_in.find(this->UniqueKey(21)));
|
1660
|
+
// should not have been saved
|
1661
|
+
EXPECT_FALSE(ht_in.count(this->UniqueKey(22)));
|
1662
|
+
EXPECT_FALSE(ht_in.count(this->UniqueKey(56)));
|
1663
|
+
}
|
1664
|
+
|
1665
|
+
// Verify that the metadata serialization is endianness and word size
|
1666
|
+
// agnostic.
|
1667
|
+
TYPED_TEST(HashtableAllTest, MetadataSerializationAndEndianness) {
|
1668
|
+
TypeParam ht_out;
|
1669
|
+
string kExpectedDense("\x13W\x86""B\0\0\0\0\0\0\0 \0\0\0\0\0\0\0\0\0\0\0\0",
|
1670
|
+
24);
|
1671
|
+
string kExpectedSparse("$hu1\0\0\0 \0\0\0\0\0\0\0\0\0\0\0\0", 20);
|
1672
|
+
|
1673
|
+
if (ht_out.supports_readwrite()) {
|
1674
|
+
string file(TmpFile("metadata_serialization"));
|
1675
|
+
FILE* fp = fopen(file.c_str(), "wb");
|
1676
|
+
EXPECT_TRUE(fp != NULL);
|
1677
|
+
|
1678
|
+
EXPECT_TRUE(ht_out.write_metadata(fp));
|
1679
|
+
EXPECT_TRUE(ht_out.write_nopointer_data(fp));
|
1680
|
+
|
1681
|
+
const size_t num_bytes = ftell(fp);
|
1682
|
+
fclose(fp);
|
1683
|
+
fp = fopen(file.c_str(), "rb");
|
1684
|
+
EXPECT_LE(num_bytes, static_cast<size_t>(24));
|
1685
|
+
char contents[24];
|
1686
|
+
EXPECT_EQ(num_bytes, fread(contents, 1, num_bytes, fp));
|
1687
|
+
EXPECT_EQ(EOF, fgetc(fp)); // check we're *exactly* the right size
|
1688
|
+
fclose(fp);
|
1689
|
+
// TODO(csilvers): check type of ht_out instead of looking at the 1st byte.
|
1690
|
+
if (contents[0] == kExpectedDense[0]) {
|
1691
|
+
EXPECT_EQ(kExpectedDense, string(contents, num_bytes));
|
1692
|
+
} else {
|
1693
|
+
EXPECT_EQ(kExpectedSparse, string(contents, num_bytes));
|
1694
|
+
}
|
1695
|
+
}
|
1696
|
+
|
1697
|
+
// Do it again with new-style serialization. Here we can use StringIO.
|
1698
|
+
if (ht_out.supports_serialization()) {
|
1699
|
+
string stringbuf;
|
1700
|
+
StringIO stringio(&stringbuf);
|
1701
|
+
EXPECT_TRUE(ht_out.serialize(typename TypeParam::NopointerSerializer(),
|
1702
|
+
&stringio));
|
1703
|
+
if (stringbuf[0] == kExpectedDense[0]) {
|
1704
|
+
EXPECT_EQ(kExpectedDense, stringbuf);
|
1705
|
+
} else {
|
1706
|
+
EXPECT_EQ(kExpectedSparse, stringbuf);
|
1707
|
+
}
|
1708
|
+
}
|
1709
|
+
}
|
1710
|
+
|
1711
|
+
|
1396
1712
|
// ------------------------------------------------------------------------
|
1397
1713
|
// The above tests test the general API for correctness. These tests
|
1398
1714
|
// test a few corner cases that have tripped us up in the past, and
|
@@ -1594,20 +1910,12 @@ TEST(HashtableTest, NestedHashtables) {
|
|
1594
1910
|
|
1595
1911
|
TEST(HashtableDeathTest, ResizeOverflow) {
|
1596
1912
|
dense_hash_map<int, int> ht;
|
1597
|
-
|
1598
|
-
|
1599
|
-
EXPECT_TRUE(false && "dense_hash_map reszie should have failed");
|
1600
|
-
} catch (const STL_NAMESPACE::length_error&) {
|
1601
|
-
// Good, the resize failed.
|
1602
|
-
}
|
1913
|
+
EXPECT_DEATH(ht.resize(static_cast<size_t>(-1)),
|
1914
|
+
"overflows size_type");
|
1603
1915
|
|
1604
1916
|
sparse_hash_map<int, int> ht2;
|
1605
|
-
|
1606
|
-
|
1607
|
-
EXPECT_TRUE(false && "sparse_hash_map reszie should have failed");
|
1608
|
-
} catch (const STL_NAMESPACE::length_error&) {
|
1609
|
-
// Good, the resize failed.
|
1610
|
-
}
|
1917
|
+
EXPECT_DEATH(ht2.resize(static_cast<size_t>(-1)),
|
1918
|
+
"overflows size_type");
|
1611
1919
|
}
|
1612
1920
|
|
1613
1921
|
TEST(HashtableDeathTest, InsertSizeTypeOverflow) {
|
@@ -1626,18 +1934,10 @@ TEST(HashtableDeathTest, InsertSizeTypeOverflow) {
|
|
1626
1934
|
EXPECT_TRUE(dhs.get_allocator().is_custom_alloc());
|
1627
1935
|
|
1628
1936
|
// Test size_type overflow in insert(it, it)
|
1629
|
-
|
1630
|
-
|
1631
|
-
|
1632
|
-
|
1633
|
-
// Good, the operation failed.
|
1634
|
-
}
|
1635
|
-
try {
|
1636
|
-
shs.insert(test_data.begin(), test_data.end());
|
1637
|
-
EXPECT_TRUE(false && "sparse_hash_map::insert(it,it) should have overflown");
|
1638
|
-
} catch (const STL_NAMESPACE::length_error&) {
|
1639
|
-
// Good, the operation failed.
|
1640
|
-
}
|
1937
|
+
EXPECT_DEATH(dhs.insert(test_data.begin(), test_data.end()),
|
1938
|
+
"overflows size_type");
|
1939
|
+
EXPECT_DEATH(shs.insert(test_data.begin(), test_data.end()),
|
1940
|
+
"overflows size_type");
|
1641
1941
|
}
|
1642
1942
|
|
1643
1943
|
TEST(HashtableDeathTest, InsertMaxSizeOverflow) {
|
@@ -1652,18 +1952,10 @@ TEST(HashtableDeathTest, InsertMaxSizeOverflow) {
|
|
1652
1952
|
dhs.set_empty_key(-1);
|
1653
1953
|
|
1654
1954
|
// Test max_size overflow
|
1655
|
-
|
1656
|
-
|
1657
|
-
|
1658
|
-
|
1659
|
-
// Good, the operation failed.
|
1660
|
-
}
|
1661
|
-
try {
|
1662
|
-
shs.insert(test_data.begin(), test_data.begin() + 11);
|
1663
|
-
EXPECT_TRUE(false && "sparse_hash_map max_size check should have failed");
|
1664
|
-
} catch (const STL_NAMESPACE::length_error&) {
|
1665
|
-
// Good, the operation failed.
|
1666
|
-
}
|
1955
|
+
EXPECT_DEATH(dhs.insert(test_data.begin(), test_data.begin() + 11),
|
1956
|
+
"exceed max_size");
|
1957
|
+
EXPECT_DEATH(shs.insert(test_data.begin(), test_data.begin() + 11),
|
1958
|
+
"exceed max_size");
|
1667
1959
|
}
|
1668
1960
|
|
1669
1961
|
TEST(HashtableDeathTest, ResizeSizeTypeOverflow) {
|
@@ -1672,18 +1964,8 @@ TEST(HashtableDeathTest, ResizeSizeTypeOverflow) {
|
|
1672
1964
|
dense_hash_set<int, Hasher, Hasher, Alloc<int, uint8, 10> > dhs;
|
1673
1965
|
dhs.set_empty_key(-1);
|
1674
1966
|
|
1675
|
-
|
1676
|
-
|
1677
|
-
EXPECT_TRUE(false && "dense_hash_map resize should have seen overflow");
|
1678
|
-
} catch (const STL_NAMESPACE::length_error&) {
|
1679
|
-
// Good, the operation failed.
|
1680
|
-
}
|
1681
|
-
try {
|
1682
|
-
shs.resize(250);
|
1683
|
-
EXPECT_TRUE(false && "sparse_hash_map resize should have seen overflow");
|
1684
|
-
} catch (const STL_NAMESPACE::length_error&) {
|
1685
|
-
// Good, the operation failed.
|
1686
|
-
}
|
1967
|
+
EXPECT_DEATH(dhs.resize(250), "overflows size_type"); // 9+250 > 256
|
1968
|
+
EXPECT_DEATH(shs.resize(250), "overflows size_type");
|
1687
1969
|
}
|
1688
1970
|
|
1689
1971
|
TEST(HashtableDeathTest, ResizeDeltaOverflow) {
|
@@ -1700,18 +1982,10 @@ TEST(HashtableDeathTest, ResizeDeltaOverflow) {
|
|
1700
1982
|
dhs.insert(i);
|
1701
1983
|
shs.insert(i);
|
1702
1984
|
}
|
1703
|
-
|
1704
|
-
|
1705
|
-
|
1706
|
-
|
1707
|
-
// Good, the operation failed.
|
1708
|
-
}
|
1709
|
-
try {
|
1710
|
-
shs.insert(test_data.begin(), test_data.begin() + 250);
|
1711
|
-
EXPECT_TRUE(false && "sparse_hash_map big insert should have overflowed");
|
1712
|
-
} catch (const STL_NAMESPACE::length_error&) {
|
1713
|
-
// Good, the operation failed.
|
1714
|
-
}
|
1985
|
+
EXPECT_DEATH(dhs.insert(test_data.begin(), test_data.begin() + 250),
|
1986
|
+
"overflows size_type"); // 9+250 > 256
|
1987
|
+
EXPECT_DEATH(shs.insert(test_data.begin(), test_data.begin() + 250),
|
1988
|
+
"overflows size_type");
|
1715
1989
|
}
|
1716
1990
|
|
1717
1991
|
// ------------------------------------------------------------------------
|
@@ -1719,8 +1993,8 @@ TEST(HashtableDeathTest, ResizeDeltaOverflow) {
|
|
1719
1993
|
// Also, benchmarks.
|
1720
1994
|
|
1721
1995
|
TYPED_TEST(HashtableAllTest, ClassSizes) {
|
1722
|
-
cout << "sizeof(" << typeid(TypeParam).name() << "): "
|
1723
|
-
|
1996
|
+
std::cout << "sizeof(" << typeid(TypeParam).name() << "): "
|
1997
|
+
<< sizeof(this->ht_) << "\n";
|
1724
1998
|
}
|
1725
1999
|
|
1726
2000
|
} // unnamed namespace
|