google_hash 0.6.2 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README +61 -27
- data/Rakefile +4 -1
- data/TODO +5 -0
- data/VERSION +1 -1
- data/changelog +3 -0
- data/ext/extconf.rb +10 -5
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/AUTHORS +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/COPYING +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/ChangeLog +47 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/INSTALL +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/Makefile.am +29 -14
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/Makefile.in +77 -42
- data/ext/sparsehash-1.8.1/NEWS +71 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/README +0 -0
- data/ext/{sparsehash-1.5.2/README.windows → sparsehash-1.8.1/README_windows.txt} +25 -25
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/TODO +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/aclocal.m4 +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/compile +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/config.guess +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/config.sub +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/configure +3690 -4560
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/configure.ac +1 -1
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/depcomp +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/doc/dense_hash_map.html +65 -5
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/doc/dense_hash_set.html +65 -5
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/doc/designstyle.css +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/doc/implementation.html +11 -5
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/doc/index.html +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/doc/performance.html +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/doc/sparse_hash_map.html +65 -5
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/doc/sparse_hash_set.html +65 -5
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/doc/sparsetable.html +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/experimental/Makefile +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/experimental/README +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/experimental/example.c +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/experimental/libchash.c +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/experimental/libchash.h +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/google-sparsehash.sln +17 -1
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/install-sh +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/m4/acx_pthread.m4 +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/m4/google_namespace.m4 +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/m4/namespaces.m4 +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/m4/stl_hash.m4 +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/m4/stl_hash_fun.m4 +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/m4/stl_namespace.m4 +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/missing +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/mkinstalldirs +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/packages/deb.sh +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/packages/deb/README +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/packages/deb/changelog +24 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/packages/deb/compat +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/packages/deb/control +1 -1
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/packages/deb/copyright +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/packages/deb/docs +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/packages/deb/rules +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/packages/deb/sparsehash.dirs +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/packages/deb/sparsehash.install +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/packages/rpm.sh +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/packages/rpm/rpm.spec +1 -1
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/config.h.in +3 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/config.h.include +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/google/dense_hash_map +43 -27
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/google/dense_hash_set +40 -19
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/google/sparse_hash_map +32 -23
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/google/sparse_hash_set +31 -21
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/google/sparsehash/densehashtable.h +481 -298
- data/ext/sparsehash-1.8.1/src/google/sparsehash/hashtable-common.h +178 -0
- data/ext/sparsehash-1.8.1/src/google/sparsehash/libc_allocator_with_realloc.h +121 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/google/sparsehash/sparsehashtable.h +404 -233
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/google/sparsetable +173 -83
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/google/type_traits.h +3 -29
- data/ext/sparsehash-1.8.1/src/hash_test_interface.h +1011 -0
- data/ext/sparsehash-1.8.1/src/hashtable_test.cc +1733 -0
- data/ext/sparsehash-1.8.1/src/libc_allocator_with_realloc_test.cc +129 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/simple_test.cc +1 -1
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/sparsetable_unittest.cc +202 -6
- data/ext/sparsehash-1.8.1/src/testutil.h +251 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/time_hash_map.cc +128 -54
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/type_traits_unittest.cc +30 -20
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/windows/config.h +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/windows/google/sparsehash/sparseconfig.h +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/windows/port.cc +0 -0
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/windows/port.h +0 -0
- data/ext/sparsehash-1.8.1/vsprojects/hashtable_test/hashtable_test.vcproj +197 -0
- data/ext/{sparsehash-1.5.2/vsprojects/hashtable_unittest/hashtable_unittest.vcproj → sparsehash-1.8.1/vsprojects/simple_test/simple_test.vcproj} +9 -8
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/vsprojects/sparsetable_unittest/sparsetable_unittest.vcproj +0 -2
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/vsprojects/time_hash_map/time_hash_map.vcproj +3 -2
- data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/vsprojects/type_traits_unittest/type_traits_unittest.vcproj +0 -2
- data/ext/template/google_hash.cpp.erb +2 -1
- data/ext/template/main.cpp.erb +1 -1
- data/results.txt +6 -22
- data/spec/benchmark.rb +57 -0
- data/spec/spec.google_hash.rb +1 -8
- metadata +140 -130
- data/ext/benchmark.rb +0 -47
- data/ext/sparsehash-1.5.2/NEWS +0 -0
- data/ext/sparsehash-1.5.2/src/hashtable_unittest.cc +0 -1375
- data/ext/sparsehash-1.5.2/src/words +0 -8944
- data/types.txt +0 -18
@@ -0,0 +1,129 @@
|
|
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: Guilin Chen
|
32
|
+
|
33
|
+
#include "config.h"
|
34
|
+
#include <google/sparsehash/libc_allocator_with_realloc.h>
|
35
|
+
#include <stdlib.h>
|
36
|
+
#include <iostream>
|
37
|
+
#include <string>
|
38
|
+
#include <vector>
|
39
|
+
|
40
|
+
using std::cerr;
|
41
|
+
using std::string;
|
42
|
+
using std::basic_string;
|
43
|
+
using std::char_traits;
|
44
|
+
using std::vector;
|
45
|
+
using GOOGLE_NAMESPACE::libc_allocator_with_realloc;
|
46
|
+
|
47
|
+
#define arraysize(a) ( sizeof(a) / sizeof(*(a)) )
|
48
|
+
|
49
|
+
#define EXPECT_EQ(a, b) do { \
|
50
|
+
if ((a) != (b)) { \
|
51
|
+
cerr << "Check failed: EXPECTED: " << #a << " == " << #b << ", " \
|
52
|
+
<< "ACTUAL: " << a << " != " << b << "\n"; \
|
53
|
+
exit(1); \
|
54
|
+
} \
|
55
|
+
} while (0)
|
56
|
+
|
57
|
+
namespace {
|
58
|
+
|
59
|
+
typedef libc_allocator_with_realloc<int> int_alloc;
|
60
|
+
typedef int_alloc::rebind<int*>::other intp_alloc;
|
61
|
+
|
62
|
+
// cstring allocates from libc_allocator_with_realloc.
|
63
|
+
typedef basic_string<char, char_traits<char>,
|
64
|
+
libc_allocator_with_realloc<char> > cstring;
|
65
|
+
typedef vector<cstring, libc_allocator_with_realloc<cstring> > cstring_vector;
|
66
|
+
|
67
|
+
|
68
|
+
void TestAllocate() {
|
69
|
+
int_alloc alloc;
|
70
|
+
intp_alloc palloc;
|
71
|
+
|
72
|
+
int** parray = palloc.allocate(1024);
|
73
|
+
for (int i = 0; i < 16; ++i) {
|
74
|
+
parray[i] = alloc.allocate(i * 1024 + 1);
|
75
|
+
}
|
76
|
+
for (int i = 0; i < 16; ++i) {
|
77
|
+
alloc.deallocate(parray[i], i * 1024 + 1);
|
78
|
+
}
|
79
|
+
palloc.deallocate(parray, 1024);
|
80
|
+
|
81
|
+
int* p = alloc.allocate(4096);
|
82
|
+
p[0] = 1;
|
83
|
+
p[1023] = 2;
|
84
|
+
p[4095] = 3;
|
85
|
+
p = alloc.reallocate(p, 8192);
|
86
|
+
EXPECT_EQ(1, p[0]);
|
87
|
+
EXPECT_EQ(2, p[1023]);
|
88
|
+
EXPECT_EQ(3, p[4095]);
|
89
|
+
p = alloc.reallocate(p, 1024);
|
90
|
+
EXPECT_EQ(1, p[0]);
|
91
|
+
EXPECT_EQ(2, p[1023]);
|
92
|
+
alloc.deallocate(p, 1024);
|
93
|
+
}
|
94
|
+
|
95
|
+
void TestSTL() {
|
96
|
+
// Test strings copied from base/arena_unittest.cc
|
97
|
+
static const char* test_strings[] = {
|
98
|
+
"aback", "abaft", "abandon", "abandoned", "abandoning",
|
99
|
+
"abandonment", "abandons", "abase", "abased", "abasement",
|
100
|
+
"abasements", "abases", "abash", "abashed", "abashes", "abashing",
|
101
|
+
"abasing", "abate", "abated", "abatement", "abatements", "abater",
|
102
|
+
"abates", "abating", "abbe", "abbey", "abbeys", "abbot", "abbots",
|
103
|
+
"abbreviate", "abbreviated", "abbreviates", "abbreviating",
|
104
|
+
"abbreviation", "abbreviations", "abdomen", "abdomens", "abdominal",
|
105
|
+
"abduct", "abducted", "abduction", "abductions", "abductor", "abductors",
|
106
|
+
"abducts", "Abe", "abed", "Abel", "Abelian", "Abelson", "Aberdeen",
|
107
|
+
"Abernathy", "aberrant", "aberration", "aberrations", "abet", "abets",
|
108
|
+
"abetted", "abetter", "abetting", "abeyance", "abhor", "abhorred",
|
109
|
+
"abhorrent", "abhorrer", "abhorring", "abhors", "abide", "abided",
|
110
|
+
"abides", "abiding"};
|
111
|
+
cstring_vector v;
|
112
|
+
for (size_t i = 0; i < arraysize(test_strings); ++i) {
|
113
|
+
v.push_back(test_strings[i]);
|
114
|
+
}
|
115
|
+
for (size_t i = arraysize(test_strings); i > 0; --i) {
|
116
|
+
EXPECT_EQ(cstring(test_strings[i-1]), v.back());
|
117
|
+
v.pop_back();
|
118
|
+
}
|
119
|
+
}
|
120
|
+
|
121
|
+
} // namespace
|
122
|
+
|
123
|
+
int main() {
|
124
|
+
TestAllocate();
|
125
|
+
TestSTL();
|
126
|
+
|
127
|
+
cerr << "PASS\n";
|
128
|
+
return 0;
|
129
|
+
}
|
@@ -45,11 +45,14 @@
|
|
45
45
|
#include <unistd.h> // for unlink()
|
46
46
|
#include <sys/types.h> // for size_t
|
47
47
|
#include <string>
|
48
|
+
#include <memory> // for allocator
|
48
49
|
#endif
|
49
50
|
#include <google/sparsetable>
|
50
51
|
|
51
52
|
using STL_NAMESPACE::string;
|
53
|
+
using STL_NAMESPACE::allocator;
|
52
54
|
using GOOGLE_NAMESPACE::sparsetable;
|
55
|
+
using GOOGLE_NAMESPACE::DEFAULT_SPARSEGROUP_SIZE;
|
53
56
|
|
54
57
|
// Many sparsetable operations return a size_t. Rather than have to
|
55
58
|
// use PRIuS everywhere, we'll just cast to a "big enough" value.
|
@@ -320,12 +323,12 @@ void TestInt() {
|
|
320
323
|
|
321
324
|
// ----------------------------------------------------------------------
|
322
325
|
// Test I/O
|
323
|
-
string filestr = "/tmp
|
326
|
+
string filestr = "/tmp/.sparsetable.test";
|
324
327
|
const char *file = filestr.c_str();
|
325
328
|
FILE *fp = fopen(file, "wb");
|
326
329
|
if ( fp == NULL ) {
|
327
330
|
// maybe we can't write to /tmp/. Try the current directory
|
328
|
-
file = "
|
331
|
+
file = ".sparsetable.test";
|
329
332
|
fp = fopen(file, "wb");
|
330
333
|
}
|
331
334
|
if ( fp == NULL ) {
|
@@ -443,7 +446,182 @@ void TestString() {
|
|
443
446
|
out += snprintf(out, LEFT, "y[??] = %s\n", (*--it).c_str());
|
444
447
|
}
|
445
448
|
|
446
|
-
//
|
449
|
+
// An instrumented allocator that keeps track of all calls to
|
450
|
+
// allocate/deallocate/construct/destroy. It stores the number of times
|
451
|
+
// they were called and the values they were called with. Such information is
|
452
|
+
// stored in the following global variables.
|
453
|
+
|
454
|
+
static size_t sum_allocate_bytes;
|
455
|
+
static size_t sum_deallocate_bytes;
|
456
|
+
|
457
|
+
void ResetAllocatorCounters() {
|
458
|
+
sum_allocate_bytes = 0;
|
459
|
+
sum_deallocate_bytes = 0;
|
460
|
+
}
|
461
|
+
|
462
|
+
template <class T> class instrumented_allocator {
|
463
|
+
public:
|
464
|
+
typedef T value_type;
|
465
|
+
typedef u_int16_t size_type;
|
466
|
+
typedef ptrdiff_t difference_type;
|
467
|
+
|
468
|
+
typedef T* pointer;
|
469
|
+
typedef const T* const_pointer;
|
470
|
+
typedef T& reference;
|
471
|
+
typedef const T& const_reference;
|
472
|
+
|
473
|
+
instrumented_allocator() {}
|
474
|
+
instrumented_allocator(const instrumented_allocator&) {}
|
475
|
+
~instrumented_allocator() {}
|
476
|
+
|
477
|
+
pointer address(reference r) const { return &r; }
|
478
|
+
const_pointer address(const_reference r) const { return &r; }
|
479
|
+
|
480
|
+
pointer allocate(size_type n, const_pointer = 0) {
|
481
|
+
sum_allocate_bytes += n * sizeof(value_type);
|
482
|
+
return static_cast<pointer>(malloc(n * sizeof(value_type)));
|
483
|
+
}
|
484
|
+
void deallocate(pointer p, size_type n) {
|
485
|
+
sum_deallocate_bytes += n * sizeof(value_type);
|
486
|
+
free(p);
|
487
|
+
}
|
488
|
+
|
489
|
+
size_type max_size() const {
|
490
|
+
return static_cast<size_type>(-1) / sizeof(value_type);
|
491
|
+
}
|
492
|
+
|
493
|
+
void construct(pointer p, const value_type& val) {
|
494
|
+
new(p) value_type(val);
|
495
|
+
}
|
496
|
+
void destroy(pointer p) {
|
497
|
+
p->~value_type();
|
498
|
+
}
|
499
|
+
|
500
|
+
template <class U>
|
501
|
+
explicit instrumented_allocator(const instrumented_allocator<U>&) {}
|
502
|
+
|
503
|
+
template<class U>
|
504
|
+
struct rebind {
|
505
|
+
typedef instrumented_allocator<U> other;
|
506
|
+
};
|
507
|
+
|
508
|
+
private:
|
509
|
+
void operator=(const instrumented_allocator&);
|
510
|
+
};
|
511
|
+
|
512
|
+
template<class T>
|
513
|
+
inline bool operator==(const instrumented_allocator<T>&,
|
514
|
+
const instrumented_allocator<T>&) {
|
515
|
+
return true;
|
516
|
+
}
|
517
|
+
|
518
|
+
template<class T>
|
519
|
+
inline bool operator!=(const instrumented_allocator<T>&,
|
520
|
+
const instrumented_allocator<T>&) {
|
521
|
+
return false;
|
522
|
+
}
|
523
|
+
|
524
|
+
// Test sparsetable with instrumented_allocator.
|
525
|
+
void TestAllocator() {
|
526
|
+
out += snprintf(out, LEFT, "allocator test\n");
|
527
|
+
|
528
|
+
ResetAllocatorCounters();
|
529
|
+
|
530
|
+
// POD (int32) with instrumented_allocator.
|
531
|
+
typedef sparsetable<int, DEFAULT_SPARSEGROUP_SIZE,
|
532
|
+
instrumented_allocator<int> > IntSparseTable;
|
533
|
+
|
534
|
+
IntSparseTable* s1 = new IntSparseTable(10000);
|
535
|
+
TEST(sum_allocate_bytes > 0);
|
536
|
+
for (int i = 0; i < 10000; ++i) {
|
537
|
+
s1->set(i, 0);
|
538
|
+
}
|
539
|
+
TEST(sum_allocate_bytes >= 10000 * sizeof(int));
|
540
|
+
ResetAllocatorCounters();
|
541
|
+
delete s1;
|
542
|
+
TEST(sum_deallocate_bytes >= 10000 * sizeof(int));
|
543
|
+
|
544
|
+
IntSparseTable* s2 = new IntSparseTable(1000);
|
545
|
+
IntSparseTable* s3 = new IntSparseTable(1000);
|
546
|
+
|
547
|
+
for (int i = 0; i < 1000; ++i) {
|
548
|
+
s2->set(i, 0);
|
549
|
+
s3->set(i, 0);
|
550
|
+
}
|
551
|
+
TEST(sum_allocate_bytes >= 2000 * sizeof(int));
|
552
|
+
|
553
|
+
ResetAllocatorCounters();
|
554
|
+
s3->clear();
|
555
|
+
TEST(sum_deallocate_bytes >= 1000 * sizeof(int));
|
556
|
+
|
557
|
+
ResetAllocatorCounters();
|
558
|
+
s2->swap(*s3); // s2 is empty after the swap
|
559
|
+
s2->clear();
|
560
|
+
TEST(sum_deallocate_bytes < 1000 * sizeof(int));
|
561
|
+
for (int i = 0; i < s3->size(); ++i) {
|
562
|
+
s3->erase(i);
|
563
|
+
}
|
564
|
+
TEST(sum_deallocate_bytes >= 1000 * sizeof(int));
|
565
|
+
delete s2;
|
566
|
+
delete s3;
|
567
|
+
|
568
|
+
// POD (int) with default allocator.
|
569
|
+
sparsetable<int> x, y;
|
570
|
+
for (int s = 1000; s <= 40000; s += 1000) {
|
571
|
+
x.resize(s);
|
572
|
+
for (int i = 0; i < s; ++i) {
|
573
|
+
x.set(i, i + 1);
|
574
|
+
}
|
575
|
+
y = x;
|
576
|
+
for (int i = 0; i < s; ++i) {
|
577
|
+
y.erase(i);
|
578
|
+
}
|
579
|
+
y.swap(x);
|
580
|
+
}
|
581
|
+
TEST(x.num_nonempty() == 0);
|
582
|
+
out += snprintf(out, LEFT, "y[0]: %d\n", int(y[0]));
|
583
|
+
out += snprintf(out, LEFT, "y[39999]: %d\n", int(y[39999]));
|
584
|
+
y.clear();
|
585
|
+
|
586
|
+
// POD (int) with std allocator.
|
587
|
+
sparsetable<int, DEFAULT_SPARSEGROUP_SIZE, allocator<int> > u, v;
|
588
|
+
for (int s = 1000; s <= 40000; s += 1000) {
|
589
|
+
u.resize(s);
|
590
|
+
for (int i = 0; i < s; ++i) {
|
591
|
+
u.set(i, i + 1);
|
592
|
+
}
|
593
|
+
v = u;
|
594
|
+
for (int i = 0; i < s; ++i) {
|
595
|
+
v.erase(i);
|
596
|
+
}
|
597
|
+
v.swap(u);
|
598
|
+
}
|
599
|
+
TEST(u.num_nonempty() == 0);
|
600
|
+
out += snprintf(out, LEFT, "v[0]: %d\n", int(v[0]));
|
601
|
+
out += snprintf(out, LEFT, "v[39999]: %d\n", int(v[39999]));
|
602
|
+
v.clear();
|
603
|
+
|
604
|
+
// Non-POD (string) with default allocator.
|
605
|
+
sparsetable<string> a, b;
|
606
|
+
for (int s = 1000; s <= 40000; s += 1000) {
|
607
|
+
a.resize(s);
|
608
|
+
for (int i = 0; i < s; ++i) {
|
609
|
+
a.set(i, "aa");
|
610
|
+
}
|
611
|
+
b = a;
|
612
|
+
for (int i = 0; i < s; ++i) {
|
613
|
+
b.erase(i);
|
614
|
+
}
|
615
|
+
b.swap(a);
|
616
|
+
}
|
617
|
+
TEST(a.num_nonempty() == 0);
|
618
|
+
out += snprintf(out, LEFT, "b[0]: %s\n", b.get(0).c_str());
|
619
|
+
out += snprintf(out, LEFT, "b[39999]: %s\n", b.get(39999).c_str());
|
620
|
+
b.clear();
|
621
|
+
}
|
622
|
+
|
623
|
+
// The expected output from all of the above: TestInt(), TestString() and
|
624
|
+
// TestAllocator().
|
447
625
|
static const char g_expected[] = (
|
448
626
|
"int test\n"
|
449
627
|
"x[0]: 0\n"
|
@@ -675,17 +853,35 @@ static const char g_expected[] = (
|
|
675
853
|
"y[??] = -13\n"
|
676
854
|
"y[??] = -11\n"
|
677
855
|
"y[??] = -10\n"
|
856
|
+
"allocator test\n"
|
857
|
+
"sum_allocate_bytes > 0? yes\n"
|
858
|
+
"sum_allocate_bytes >= 10000 * sizeof(int)? yes\n"
|
859
|
+
"sum_deallocate_bytes >= 10000 * sizeof(int)? yes\n"
|
860
|
+
"sum_allocate_bytes >= 2000 * sizeof(int)? yes\n"
|
861
|
+
"sum_deallocate_bytes >= 1000 * sizeof(int)? yes\n"
|
862
|
+
"sum_deallocate_bytes < 1000 * sizeof(int)? yes\n"
|
863
|
+
"sum_deallocate_bytes >= 1000 * sizeof(int)? yes\n"
|
864
|
+
"x.num_nonempty() == 0? yes\n"
|
865
|
+
"y[0]: 1\n"
|
866
|
+
"y[39999]: 40000\n"
|
867
|
+
"u.num_nonempty() == 0? yes\n"
|
868
|
+
"v[0]: 1\n"
|
869
|
+
"v[39999]: 40000\n"
|
870
|
+
"a.num_nonempty() == 0? yes\n"
|
871
|
+
"b[0]: aa\n"
|
872
|
+
"b[39999]: aa\n"
|
678
873
|
);
|
679
874
|
|
680
875
|
// defined at bottom of file for ease of maintainence
|
681
|
-
int main(int argc
|
876
|
+
int main(int /*argc*/, char ** /*argv*/) {
|
682
877
|
TestInt();
|
683
878
|
TestString();
|
879
|
+
TestAllocator();
|
684
880
|
|
685
881
|
// Finally, check to see if our output (in out) is what it's supposed to be.
|
686
882
|
const size_t r = sizeof(g_expected) - 1;
|
687
|
-
if ( r != out - outbuf ||
|
688
|
-
memcmp(outbuf, g_expected, r) ) {
|
883
|
+
if ( r != static_cast<size_t>(out - outbuf) || // output not the same size
|
884
|
+
memcmp(outbuf, g_expected, r) ) { // or bytes differed
|
689
885
|
fprintf(stderr, "TESTS FAILED\n\nEXPECTED:\n\n%s\n\nACTUAL:\n\n%s\n\n",
|
690
886
|
g_expected, outbuf);
|
691
887
|
return 1;
|
@@ -0,0 +1,251 @@
|
|
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 macro mimics a unittest framework, but is a bit less flexible
|
34
|
+
// than most. It requires a superclass to derive from, and does all
|
35
|
+
// work in global constructors. The tricky part is implementing
|
36
|
+
// TYPED_TEST.
|
37
|
+
|
38
|
+
#ifndef SPARSEHASH_TEST_UTIL_H_
|
39
|
+
#define SPARSEHASH_TEST_UTIL_H_
|
40
|
+
|
41
|
+
#include "config.h"
|
42
|
+
#include <stdio.h>
|
43
|
+
|
44
|
+
_START_GOOGLE_NAMESPACE_
|
45
|
+
|
46
|
+
namespace testing {
|
47
|
+
|
48
|
+
#define EXPECT_TRUE(cond) do { \
|
49
|
+
if (!(cond)) { \
|
50
|
+
::fputs("Test failed: " #cond "\n", stderr); \
|
51
|
+
::exit(1); \
|
52
|
+
} \
|
53
|
+
} while (0)
|
54
|
+
|
55
|
+
#define EXPECT_FALSE(a) EXPECT_TRUE(!(a))
|
56
|
+
#define EXPECT_EQ(a, b) EXPECT_TRUE((a) == (b))
|
57
|
+
#define EXPECT_LT(a, b) EXPECT_TRUE((a) < (b))
|
58
|
+
#define EXPECT_GT(a, b) EXPECT_TRUE((a) > (b))
|
59
|
+
#define EXPECT_LE(a, b) EXPECT_TRUE((a) <= (b))
|
60
|
+
#define EXPECT_GE(a, b) EXPECT_TRUE((a) >= (b))
|
61
|
+
|
62
|
+
#define TEST(suitename, testname) \
|
63
|
+
class TEST_##suitename##_##testname { \
|
64
|
+
public: \
|
65
|
+
TEST_##suitename##_##testname() { \
|
66
|
+
::fputs("Running " #suitename "." #testname "\n", stderr); \
|
67
|
+
Run(); \
|
68
|
+
} \
|
69
|
+
void Run(); \
|
70
|
+
}; \
|
71
|
+
static TEST_##suitename##_##testname \
|
72
|
+
test_instance_##suitename##_##testname; \
|
73
|
+
void TEST_##suitename##_##testname::Run()
|
74
|
+
|
75
|
+
|
76
|
+
template<typename C1, typename C2, typename C3, typename C4, typename C5,
|
77
|
+
typename C6> struct TypeList6 {
|
78
|
+
typedef C1 type1;
|
79
|
+
typedef C2 type2;
|
80
|
+
typedef C3 type3;
|
81
|
+
typedef C4 type4;
|
82
|
+
typedef C5 type5;
|
83
|
+
typedef C6 type6;
|
84
|
+
};
|
85
|
+
|
86
|
+
// I need to list 18 types here, for code below to compile, though
|
87
|
+
// only the first 6 are ever used.
|
88
|
+
#define TYPED_TEST_CASE_6(classname, typelist) \
|
89
|
+
typedef typelist::type1 classname##_type1; \
|
90
|
+
typedef typelist::type2 classname##_type2; \
|
91
|
+
typedef typelist::type3 classname##_type3; \
|
92
|
+
typedef typelist::type4 classname##_type4; \
|
93
|
+
typedef typelist::type5 classname##_type5; \
|
94
|
+
typedef typelist::type6 classname##_type6; \
|
95
|
+
static const int classname##_numtypes = 6; \
|
96
|
+
typedef typelist::type1 classname##_type7; \
|
97
|
+
typedef typelist::type1 classname##_type8; \
|
98
|
+
typedef typelist::type1 classname##_type9; \
|
99
|
+
typedef typelist::type1 classname##_type10; \
|
100
|
+
typedef typelist::type1 classname##_type11; \
|
101
|
+
typedef typelist::type1 classname##_type12; \
|
102
|
+
typedef typelist::type1 classname##_type13; \
|
103
|
+
typedef typelist::type1 classname##_type14; \
|
104
|
+
typedef typelist::type1 classname##_type15; \
|
105
|
+
typedef typelist::type1 classname##_type16; \
|
106
|
+
typedef typelist::type1 classname##_type17; \
|
107
|
+
typedef typelist::type1 classname##_type18;
|
108
|
+
|
109
|
+
template<typename C1, typename C2, typename C3, typename C4, typename C5,
|
110
|
+
typename C6, typename C7, typename C8, typename C9, typename C10,
|
111
|
+
typename C11, typename C12, typename C13, typename C14, typename C15,
|
112
|
+
typename C16, typename C17, typename C18> struct TypeList18 {
|
113
|
+
typedef C1 type1;
|
114
|
+
typedef C2 type2;
|
115
|
+
typedef C3 type3;
|
116
|
+
typedef C4 type4;
|
117
|
+
typedef C5 type5;
|
118
|
+
typedef C6 type6;
|
119
|
+
typedef C7 type7;
|
120
|
+
typedef C8 type8;
|
121
|
+
typedef C9 type9;
|
122
|
+
typedef C10 type10;
|
123
|
+
typedef C11 type11;
|
124
|
+
typedef C12 type12;
|
125
|
+
typedef C13 type13;
|
126
|
+
typedef C14 type14;
|
127
|
+
typedef C15 type15;
|
128
|
+
typedef C16 type16;
|
129
|
+
typedef C17 type17;
|
130
|
+
typedef C18 type18;
|
131
|
+
};
|
132
|
+
|
133
|
+
#define TYPED_TEST_CASE_18(classname, typelist) \
|
134
|
+
typedef typelist::type1 classname##_type1; \
|
135
|
+
typedef typelist::type2 classname##_type2; \
|
136
|
+
typedef typelist::type3 classname##_type3; \
|
137
|
+
typedef typelist::type4 classname##_type4; \
|
138
|
+
typedef typelist::type5 classname##_type5; \
|
139
|
+
typedef typelist::type6 classname##_type6; \
|
140
|
+
typedef typelist::type7 classname##_type7; \
|
141
|
+
typedef typelist::type8 classname##_type8; \
|
142
|
+
typedef typelist::type9 classname##_type9; \
|
143
|
+
typedef typelist::type10 classname##_type10; \
|
144
|
+
typedef typelist::type11 classname##_type11; \
|
145
|
+
typedef typelist::type12 classname##_type12; \
|
146
|
+
typedef typelist::type13 classname##_type13; \
|
147
|
+
typedef typelist::type14 classname##_type14; \
|
148
|
+
typedef typelist::type15 classname##_type15; \
|
149
|
+
typedef typelist::type16 classname##_type16; \
|
150
|
+
typedef typelist::type17 classname##_type17; \
|
151
|
+
typedef typelist::type18 classname##_type18; \
|
152
|
+
static const int classname##_numtypes = 18;
|
153
|
+
|
154
|
+
#define TYPED_TEST(superclass, testname) \
|
155
|
+
template<typename TypeParam> \
|
156
|
+
class TEST_onetype_##superclass##_##testname : \
|
157
|
+
public superclass<TypeParam> { \
|
158
|
+
public: \
|
159
|
+
TEST_onetype_##superclass##_##testname() { \
|
160
|
+
Run(); \
|
161
|
+
} \
|
162
|
+
private: \
|
163
|
+
void Run(); \
|
164
|
+
}; \
|
165
|
+
class TEST_typed_##superclass##_##testname { \
|
166
|
+
public: \
|
167
|
+
explicit TEST_typed_##superclass##_##testname() { \
|
168
|
+
if (superclass##_numtypes >= 1) { \
|
169
|
+
::fputs("Running " #superclass "." #testname ".1\n", stderr); \
|
170
|
+
TEST_onetype_##superclass##_##testname<superclass##_type1> t; \
|
171
|
+
} \
|
172
|
+
if (superclass##_numtypes >= 2) { \
|
173
|
+
::fputs("Running " #superclass "." #testname ".2\n", stderr); \
|
174
|
+
TEST_onetype_##superclass##_##testname<superclass##_type2> t; \
|
175
|
+
} \
|
176
|
+
if (superclass##_numtypes >= 3) { \
|
177
|
+
::fputs("Running " #superclass "." #testname ".3\n", stderr); \
|
178
|
+
TEST_onetype_##superclass##_##testname<superclass##_type3> t; \
|
179
|
+
} \
|
180
|
+
if (superclass##_numtypes >= 4) { \
|
181
|
+
::fputs("Running " #superclass "." #testname ".4\n", stderr); \
|
182
|
+
TEST_onetype_##superclass##_##testname<superclass##_type4> t; \
|
183
|
+
} \
|
184
|
+
if (superclass##_numtypes >= 5) { \
|
185
|
+
::fputs("Running " #superclass "." #testname ".5\n", stderr); \
|
186
|
+
TEST_onetype_##superclass##_##testname<superclass##_type5> t; \
|
187
|
+
} \
|
188
|
+
if (superclass##_numtypes >= 6) { \
|
189
|
+
::fputs("Running " #superclass "." #testname ".6\n", stderr); \
|
190
|
+
TEST_onetype_##superclass##_##testname<superclass##_type6> t; \
|
191
|
+
} \
|
192
|
+
if (superclass##_numtypes >= 7) { \
|
193
|
+
::fputs("Running " #superclass "." #testname ".7\n", stderr); \
|
194
|
+
TEST_onetype_##superclass##_##testname<superclass##_type7> t; \
|
195
|
+
} \
|
196
|
+
if (superclass##_numtypes >= 8) { \
|
197
|
+
::fputs("Running " #superclass "." #testname ".8\n", stderr); \
|
198
|
+
TEST_onetype_##superclass##_##testname<superclass##_type8> t; \
|
199
|
+
} \
|
200
|
+
if (superclass##_numtypes >= 9) { \
|
201
|
+
::fputs("Running " #superclass "." #testname ".9\n", stderr); \
|
202
|
+
TEST_onetype_##superclass##_##testname<superclass##_type9> t; \
|
203
|
+
} \
|
204
|
+
if (superclass##_numtypes >= 10) { \
|
205
|
+
::fputs("Running " #superclass "." #testname ".10\n", stderr); \
|
206
|
+
TEST_onetype_##superclass##_##testname<superclass##_type10> t; \
|
207
|
+
} \
|
208
|
+
if (superclass##_numtypes >= 11) { \
|
209
|
+
::fputs("Running " #superclass "." #testname ".11\n", stderr); \
|
210
|
+
TEST_onetype_##superclass##_##testname<superclass##_type11> t; \
|
211
|
+
} \
|
212
|
+
if (superclass##_numtypes >= 12) { \
|
213
|
+
::fputs("Running " #superclass "." #testname ".12\n", stderr); \
|
214
|
+
TEST_onetype_##superclass##_##testname<superclass##_type12> t; \
|
215
|
+
} \
|
216
|
+
if (superclass##_numtypes >= 13) { \
|
217
|
+
::fputs("Running " #superclass "." #testname ".13\n", stderr); \
|
218
|
+
TEST_onetype_##superclass##_##testname<superclass##_type13> t; \
|
219
|
+
} \
|
220
|
+
if (superclass##_numtypes >= 14) { \
|
221
|
+
::fputs("Running " #superclass "." #testname ".14\n", stderr); \
|
222
|
+
TEST_onetype_##superclass##_##testname<superclass##_type14> t; \
|
223
|
+
} \
|
224
|
+
if (superclass##_numtypes >= 15) { \
|
225
|
+
::fputs("Running " #superclass "." #testname ".15\n", stderr); \
|
226
|
+
TEST_onetype_##superclass##_##testname<superclass##_type15> t; \
|
227
|
+
} \
|
228
|
+
if (superclass##_numtypes >= 16) { \
|
229
|
+
::fputs("Running " #superclass "." #testname ".16\n", stderr); \
|
230
|
+
TEST_onetype_##superclass##_##testname<superclass##_type16> t; \
|
231
|
+
} \
|
232
|
+
if (superclass##_numtypes >= 17) { \
|
233
|
+
::fputs("Running " #superclass "." #testname ".17\n", stderr); \
|
234
|
+
TEST_onetype_##superclass##_##testname<superclass##_type17> t; \
|
235
|
+
} \
|
236
|
+
if (superclass##_numtypes >= 18) { \
|
237
|
+
::fputs("Running " #superclass "." #testname ".18\n", stderr); \
|
238
|
+
TEST_onetype_##superclass##_##testname<superclass##_type18> t; \
|
239
|
+
} \
|
240
|
+
} \
|
241
|
+
}; \
|
242
|
+
static TEST_typed_##superclass##_##testname \
|
243
|
+
test_instance_typed_##superclass##_##testname; \
|
244
|
+
template<class TypeParam> \
|
245
|
+
void TEST_onetype_##superclass##_##testname<TypeParam>::Run()
|
246
|
+
|
247
|
+
} // namespace testing
|
248
|
+
|
249
|
+
_END_GOOGLE_NAMESPACE_
|
250
|
+
|
251
|
+
#endif // SPARSEHASH_TEST_UTIL_H_
|