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.
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_