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.
Files changed (99) hide show
  1. data/README +61 -27
  2. data/Rakefile +4 -1
  3. data/TODO +5 -0
  4. data/VERSION +1 -1
  5. data/changelog +3 -0
  6. data/ext/extconf.rb +10 -5
  7. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/AUTHORS +0 -0
  8. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/COPYING +0 -0
  9. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/ChangeLog +47 -0
  10. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/INSTALL +0 -0
  11. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/Makefile.am +29 -14
  12. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/Makefile.in +77 -42
  13. data/ext/sparsehash-1.8.1/NEWS +71 -0
  14. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/README +0 -0
  15. data/ext/{sparsehash-1.5.2/README.windows → sparsehash-1.8.1/README_windows.txt} +25 -25
  16. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/TODO +0 -0
  17. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/aclocal.m4 +0 -0
  18. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/compile +0 -0
  19. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/config.guess +0 -0
  20. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/config.sub +0 -0
  21. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/configure +3690 -4560
  22. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/configure.ac +1 -1
  23. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/depcomp +0 -0
  24. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/doc/dense_hash_map.html +65 -5
  25. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/doc/dense_hash_set.html +65 -5
  26. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/doc/designstyle.css +0 -0
  27. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/doc/implementation.html +11 -5
  28. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/doc/index.html +0 -0
  29. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/doc/performance.html +0 -0
  30. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/doc/sparse_hash_map.html +65 -5
  31. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/doc/sparse_hash_set.html +65 -5
  32. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/doc/sparsetable.html +0 -0
  33. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/experimental/Makefile +0 -0
  34. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/experimental/README +0 -0
  35. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/experimental/example.c +0 -0
  36. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/experimental/libchash.c +0 -0
  37. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/experimental/libchash.h +0 -0
  38. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/google-sparsehash.sln +17 -1
  39. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/install-sh +0 -0
  40. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/m4/acx_pthread.m4 +0 -0
  41. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/m4/google_namespace.m4 +0 -0
  42. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/m4/namespaces.m4 +0 -0
  43. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/m4/stl_hash.m4 +0 -0
  44. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/m4/stl_hash_fun.m4 +0 -0
  45. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/m4/stl_namespace.m4 +0 -0
  46. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/missing +0 -0
  47. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/mkinstalldirs +0 -0
  48. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/packages/deb.sh +0 -0
  49. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/packages/deb/README +0 -0
  50. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/packages/deb/changelog +24 -0
  51. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/packages/deb/compat +0 -0
  52. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/packages/deb/control +1 -1
  53. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/packages/deb/copyright +0 -0
  54. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/packages/deb/docs +0 -0
  55. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/packages/deb/rules +0 -0
  56. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/packages/deb/sparsehash.dirs +0 -0
  57. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/packages/deb/sparsehash.install +0 -0
  58. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/packages/rpm.sh +0 -0
  59. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/packages/rpm/rpm.spec +1 -1
  60. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/config.h.in +3 -0
  61. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/config.h.include +0 -0
  62. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/google/dense_hash_map +43 -27
  63. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/google/dense_hash_set +40 -19
  64. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/google/sparse_hash_map +32 -23
  65. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/google/sparse_hash_set +31 -21
  66. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/google/sparsehash/densehashtable.h +481 -298
  67. data/ext/sparsehash-1.8.1/src/google/sparsehash/hashtable-common.h +178 -0
  68. data/ext/sparsehash-1.8.1/src/google/sparsehash/libc_allocator_with_realloc.h +121 -0
  69. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/google/sparsehash/sparsehashtable.h +404 -233
  70. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/google/sparsetable +173 -83
  71. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/google/type_traits.h +3 -29
  72. data/ext/sparsehash-1.8.1/src/hash_test_interface.h +1011 -0
  73. data/ext/sparsehash-1.8.1/src/hashtable_test.cc +1733 -0
  74. data/ext/sparsehash-1.8.1/src/libc_allocator_with_realloc_test.cc +129 -0
  75. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/simple_test.cc +1 -1
  76. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/sparsetable_unittest.cc +202 -6
  77. data/ext/sparsehash-1.8.1/src/testutil.h +251 -0
  78. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/time_hash_map.cc +128 -54
  79. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/type_traits_unittest.cc +30 -20
  80. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/windows/config.h +0 -0
  81. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/windows/google/sparsehash/sparseconfig.h +0 -0
  82. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/windows/port.cc +0 -0
  83. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/src/windows/port.h +0 -0
  84. data/ext/sparsehash-1.8.1/vsprojects/hashtable_test/hashtable_test.vcproj +197 -0
  85. data/ext/{sparsehash-1.5.2/vsprojects/hashtable_unittest/hashtable_unittest.vcproj → sparsehash-1.8.1/vsprojects/simple_test/simple_test.vcproj} +9 -8
  86. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/vsprojects/sparsetable_unittest/sparsetable_unittest.vcproj +0 -2
  87. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/vsprojects/time_hash_map/time_hash_map.vcproj +3 -2
  88. data/ext/{sparsehash-1.5.2 → sparsehash-1.8.1}/vsprojects/type_traits_unittest/type_traits_unittest.vcproj +0 -2
  89. data/ext/template/google_hash.cpp.erb +2 -1
  90. data/ext/template/main.cpp.erb +1 -1
  91. data/results.txt +6 -22
  92. data/spec/benchmark.rb +57 -0
  93. data/spec/spec.google_hash.rb +1 -8
  94. metadata +140 -130
  95. data/ext/benchmark.rb +0 -47
  96. data/ext/sparsehash-1.5.2/NEWS +0 -0
  97. data/ext/sparsehash-1.5.2/src/hashtable_unittest.cc +0 -1375
  98. data/ext/sparsehash-1.5.2/src/words +0 -8944
  99. 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
+ }
@@ -55,7 +55,7 @@
55
55
  } \
56
56
  } while (0)
57
57
 
58
- int main(int argc, char** argv) {
58
+ int main(int argc, char**) {
59
59
  // Run with an argument to get verbose output
60
60
  const bool verbose = argc > 1;
61
61
 
@@ -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/#sparsetable.test";
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 = "#sparsetable.test";
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
- // The expected output from all of the above: TestInt() and TestString()
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, char **argv) { // though we ignore the args
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 || // output not the same size
688
- memcmp(outbuf, g_expected, r) ) { // or bytes differed
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_