summaryrefslogtreecommitdiff
path: root/xdelta3/cpp-btree/btree_test.h
diff options
context:
space:
mode:
authorJosh MacDonald <josh.macdonald@gmail.com>2014-11-01 00:13:18 -0700
committerJosh MacDonald <josh.macdonald@gmail.com>2014-11-01 00:13:18 -0700
commit336445673c60b7c05b015114077f49493f18e7f4 (patch)
tree844bb336d19e65c517109987e2daa39d038f3224 /xdelta3/cpp-btree/btree_test.h
parent9d4f55040311a16b32973b284e9cdfdf843ddf66 (diff)
Checksum test under development
Diffstat (limited to 'xdelta3/cpp-btree/btree_test.h')
-rw-r--r--xdelta3/cpp-btree/btree_test.h940
1 files changed, 940 insertions, 0 deletions
diff --git a/xdelta3/cpp-btree/btree_test.h b/xdelta3/cpp-btree/btree_test.h
new file mode 100644
index 0000000..413dc3c
--- /dev/null
+++ b/xdelta3/cpp-btree/btree_test.h
@@ -0,0 +1,940 @@
1// Copyright 2013 Google Inc. All Rights Reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#ifndef UTIL_BTREE_BTREE_TEST_H__
16#define UTIL_BTREE_BTREE_TEST_H__
17
18#include <stdio.h>
19#include <algorithm>
20#include <functional>
21#include <type_traits>
22#include <iosfwd>
23#include <map>
24#include <set>
25#include <sstream>
26#include <string>
27#include <utility>
28#include <vector>
29
30#include "gtest/gtest.h"
31#include "gflags/gflags.h"
32#include "btree_container.h"
33
34DECLARE_int32(test_values);
35DECLARE_int32(benchmark_values);
36
37namespace std {
38
39// Provide operator<< support for std::pair<T, U>.
40template <typename T, typename U>
41ostream& operator<<(ostream &os, const std::pair<T, U> &p) {
42 os << "(" << p.first << "," << p.second << ")";
43 return os;
44}
45
46// Provide pair equality testing that works as long as x.first is comparable to
47// y.first and x.second is comparable to y.second. Needed in the test for
48// comparing std::pair<T, U> to std::pair<const T, U>.
49template <typename T, typename U, typename V, typename W>
50bool operator==(const std::pair<T, U> &x, const std::pair<V, W> &y) {
51 return x.first == y.first && x.second == y.second;
52}
53
54// Partial specialization of remove_const that propagates the removal through
55// std::pair.
56template <typename T, typename U>
57struct remove_const<pair<T, U> > {
58 typedef pair<typename remove_const<T>::type,
59 typename remove_const<U>::type> type;
60};
61
62} // namespace std
63
64namespace btree {
65
66// Select the first member of a pair.
67template <class _Pair>
68struct select1st : public std::unary_function<_Pair, typename _Pair::first_type> {
69 const typename _Pair::first_type& operator()(const _Pair& __x) const {
70 return __x.first;
71 }
72};
73
74// Utility class to provide an accessor for a key given a value. The default
75// behavior is to treat the value as a pair and return the first element.
76template <typename K, typename V>
77struct KeyOfValue {
78 typedef select1st<V> type;
79};
80
81template <typename T>
82struct identity {
83 inline const T& operator()(const T& t) const { return t; }
84};
85
86// Partial specialization of KeyOfValue class for when the key and value are
87// the same type such as in set<> and btree_set<>.
88template <typename K>
89struct KeyOfValue<K, K> {
90 typedef identity<K> type;
91};
92
93// Counts the number of occurances of "c" in a buffer.
94inline ptrdiff_t strcount(const char* buf_begin, const char* buf_end, char c) {
95 if (buf_begin == NULL)
96 return 0;
97 if (buf_end <= buf_begin)
98 return 0;
99 ptrdiff_t num = 0;
100 for (const char* bp = buf_begin; bp != buf_end; bp++) {
101 if (*bp == c)
102 num++;
103 }
104 return num;
105}
106
107// for when the string is not null-terminated.
108inline ptrdiff_t strcount(const char* buf, size_t len, char c) {
109 return strcount(buf, buf + len, c);
110}
111
112inline ptrdiff_t strcount(const std::string& buf, char c) {
113 return strcount(buf.c_str(), buf.size(), c);
114}
115
116// The base class for a sorted associative container checker. TreeType is the
117// container type to check and CheckerType is the container type to check
118// against. TreeType is expected to be btree_{set,map,multiset,multimap} and
119// CheckerType is expected to be {set,map,multiset,multimap}.
120template <typename TreeType, typename CheckerType>
121class base_checker {
122 typedef base_checker<TreeType, CheckerType> self_type;
123
124 public:
125 typedef typename TreeType::key_type key_type;
126 typedef typename TreeType::value_type value_type;
127 typedef typename TreeType::key_compare key_compare;
128 typedef typename TreeType::pointer pointer;
129 typedef typename TreeType::const_pointer const_pointer;
130 typedef typename TreeType::reference reference;
131 typedef typename TreeType::const_reference const_reference;
132 typedef typename TreeType::size_type size_type;
133 typedef typename TreeType::difference_type difference_type;
134 typedef typename TreeType::iterator iterator;
135 typedef typename TreeType::const_iterator const_iterator;
136 typedef typename TreeType::reverse_iterator reverse_iterator;
137 typedef typename TreeType::const_reverse_iterator const_reverse_iterator;
138
139 public:
140 // Default constructor.
141 base_checker()
142 : const_tree_(tree_) {
143 }
144 // Copy constructor.
145 base_checker(const self_type &x)
146 : tree_(x.tree_),
147 const_tree_(tree_),
148 checker_(x.checker_) {
149 }
150 // Range constructor.
151 template <typename InputIterator>
152 base_checker(InputIterator b, InputIterator e)
153 : tree_(b, e),
154 const_tree_(tree_),
155 checker_(b, e) {
156 }
157
158 // Iterator routines.
159 iterator begin() { return tree_.begin(); }
160 const_iterator begin() const { return tree_.begin(); }
161 iterator end() { return tree_.end(); }
162 const_iterator end() const { return tree_.end(); }
163 reverse_iterator rbegin() { return tree_.rbegin(); }
164 const_reverse_iterator rbegin() const { return tree_.rbegin(); }
165 reverse_iterator rend() { return tree_.rend(); }
166 const_reverse_iterator rend() const { return tree_.rend(); }
167
168 // Helper routines.
169 template <typename IterType, typename CheckerIterType>
170 IterType iter_check(
171 IterType tree_iter, CheckerIterType checker_iter) const {
172 if (tree_iter == tree_.end()) {
173 EXPECT_EQ(checker_iter, checker_.end());
174 } else {
175 EXPECT_EQ(*tree_iter, *checker_iter);
176 }
177 return tree_iter;
178 }
179 template <typename IterType, typename CheckerIterType>
180 IterType riter_check(
181 IterType tree_iter, CheckerIterType checker_iter) const {
182 if (tree_iter == tree_.rend()) {
183 EXPECT_EQ(checker_iter, checker_.rend());
184 } else {
185 EXPECT_EQ(*tree_iter, *checker_iter);
186 }
187 return tree_iter;
188 }
189 void value_check(const value_type &x) {
190 typename KeyOfValue<typename TreeType::key_type,
191 typename TreeType::value_type>::type key_of_value;
192 const key_type &key = key_of_value(x);
193 EXPECT_EQ(*find(key), x);
194 lower_bound(key);
195 upper_bound(key);
196 equal_range(key);
197 count(key);
198 }
199 void erase_check(const key_type &key) {
200 EXPECT_TRUE(tree_.find(key) == const_tree_.end());
201 EXPECT_TRUE(const_tree_.find(key) == tree_.end());
202 EXPECT_TRUE(tree_.equal_range(key).first ==
203 const_tree_.equal_range(key).second);
204 }
205
206 // Lookup routines.
207 iterator lower_bound(const key_type &key) {
208 return iter_check(tree_.lower_bound(key), checker_.lower_bound(key));
209 }
210 const_iterator lower_bound(const key_type &key) const {
211 return iter_check(tree_.lower_bound(key), checker_.lower_bound(key));
212 }
213 iterator upper_bound(const key_type &key) {
214 return iter_check(tree_.upper_bound(key), checker_.upper_bound(key));
215 }
216 const_iterator upper_bound(const key_type &key) const {
217 return iter_check(tree_.upper_bound(key), checker_.upper_bound(key));
218 }
219 std::pair<iterator,iterator> equal_range(const key_type &key) {
220 std::pair<typename CheckerType::iterator,
221 typename CheckerType::iterator> checker_res =
222 checker_.equal_range(key);
223 std::pair<iterator, iterator> tree_res = tree_.equal_range(key);
224 iter_check(tree_res.first, checker_res.first);
225 iter_check(tree_res.second, checker_res.second);
226 return tree_res;
227 }
228 std::pair<const_iterator,const_iterator> equal_range(const key_type &key) const {
229 std::pair<typename CheckerType::const_iterator,
230 typename CheckerType::const_iterator> checker_res =
231 checker_.equal_range(key);
232 std::pair<const_iterator, const_iterator> tree_res = tree_.equal_range(key);
233 iter_check(tree_res.first, checker_res.first);
234 iter_check(tree_res.second, checker_res.second);
235 return tree_res;
236 }
237 iterator find(const key_type &key) {
238 return iter_check(tree_.find(key), checker_.find(key));
239 }
240 const_iterator find(const key_type &key) const {
241 return iter_check(tree_.find(key), checker_.find(key));
242 }
243 size_type count(const key_type &key) const {
244 size_type res = checker_.count(key);
245 EXPECT_EQ(res, tree_.count(key));
246 return res;
247 }
248
249 // Assignment operator.
250 self_type& operator=(const self_type &x) {
251 tree_ = x.tree_;
252 checker_ = x.checker_;
253 return *this;
254 }
255
256 // Deletion routines.
257 int erase(const key_type &key) {
258 int size = tree_.size();
259 int res = checker_.erase(key);
260 EXPECT_EQ(res, tree_.count(key));
261 EXPECT_EQ(res, tree_.erase(key));
262 EXPECT_EQ(tree_.count(key), 0);
263 EXPECT_EQ(tree_.size(), size - res);
264 erase_check(key);
265 return res;
266 }
267 iterator erase(iterator iter) {
268 key_type key = iter.key();
269 int size = tree_.size();
270 int count = tree_.count(key);
271 typename CheckerType::iterator checker_iter = checker_.find(key);
272 for (iterator tmp(tree_.find(key)); tmp != iter; ++tmp) {
273 ++checker_iter;
274 }
275 typename CheckerType::iterator checker_next = checker_iter;
276 ++checker_next;
277 checker_.erase(checker_iter);
278 iter = tree_.erase(iter);
279 EXPECT_EQ(tree_.size(), checker_.size());
280 EXPECT_EQ(tree_.size(), size - 1);
281 EXPECT_EQ(tree_.count(key), count - 1);
282 if (count == 1) {
283 erase_check(key);
284 }
285 return iter_check(iter, checker_next);
286 }
287
288 void erase(iterator begin, iterator end) {
289 int size = tree_.size();
290 int count = distance(begin, end);
291 typename CheckerType::iterator checker_begin = checker_.find(begin.key());
292 for (iterator tmp(tree_.find(begin.key())); tmp != begin; ++tmp) {
293 ++checker_begin;
294 }
295 typename CheckerType::iterator checker_end =
296 end == tree_.end() ? checker_.end() : checker_.find(end.key());
297 if (end != tree_.end()) {
298 for (iterator tmp(tree_.find(end.key())); tmp != end; ++tmp) {
299 ++checker_end;
300 }
301 }
302 checker_.erase(checker_begin, checker_end);
303 tree_.erase(begin, end);
304 EXPECT_EQ(tree_.size(), checker_.size());
305 EXPECT_EQ(tree_.size(), size - count);
306 }
307
308 // Utility routines.
309 void clear() {
310 tree_.clear();
311 checker_.clear();
312 }
313 void swap(self_type &x) {
314 tree_.swap(x.tree_);
315 checker_.swap(x.checker_);
316 }
317
318 void verify() const {
319 tree_.verify();
320 EXPECT_EQ(tree_.size(), checker_.size());
321
322 // Move through the forward iterators using increment.
323 typename CheckerType::const_iterator
324 checker_iter(checker_.begin());
325 const_iterator tree_iter(tree_.begin());
326 for (; tree_iter != tree_.end();
327 ++tree_iter, ++checker_iter) {
328 EXPECT_EQ(*tree_iter, *checker_iter);
329 }
330
331 // Move through the forward iterators using decrement.
332 for (int n = tree_.size() - 1; n >= 0; --n) {
333 iter_check(tree_iter, checker_iter);
334 --tree_iter;
335 --checker_iter;
336 }
337 EXPECT_TRUE(tree_iter == tree_.begin());
338 EXPECT_TRUE(checker_iter == checker_.begin());
339
340 // Move through the reverse iterators using increment.
341 typename CheckerType::const_reverse_iterator
342 checker_riter(checker_.rbegin());
343 const_reverse_iterator tree_riter(tree_.rbegin());
344 for (; tree_riter != tree_.rend();
345 ++tree_riter, ++checker_riter) {
346 EXPECT_EQ(*tree_riter, *checker_riter);
347 }
348
349 // Move through the reverse iterators using decrement.
350 for (int n = tree_.size() - 1; n >= 0; --n) {
351 riter_check(tree_riter, checker_riter);
352 --tree_riter;
353 --checker_riter;
354 }
355 EXPECT_EQ(tree_riter, tree_.rbegin());
356 EXPECT_EQ(checker_riter, checker_.rbegin());
357 }
358
359 // Access to the underlying btree.
360 const TreeType& tree() const { return tree_; }
361
362 // Size routines.
363 size_type size() const {
364 EXPECT_EQ(tree_.size(), checker_.size());
365 return tree_.size();
366 }
367 size_type max_size() const { return tree_.max_size(); }
368 bool empty() const {
369 EXPECT_EQ(tree_.empty(), checker_.empty());
370 return tree_.empty();
371 }
372 size_type height() const { return tree_.height(); }
373 size_type internal_nodes() const { return tree_.internal_nodes(); }
374 size_type leaf_nodes() const { return tree_.leaf_nodes(); }
375 size_type nodes() const { return tree_.nodes(); }
376 size_type bytes_used() const { return tree_.bytes_used(); }
377 double fullness() const { return tree_.fullness(); }
378 double overhead() const { return tree_.overhead(); }
379
380 protected:
381 TreeType tree_;
382 const TreeType &const_tree_;
383 CheckerType checker_;
384};
385
386// A checker for unique sorted associative containers. TreeType is expected to
387// be btree_{set,map} and CheckerType is expected to be {set,map}.
388template <typename TreeType, typename CheckerType>
389class unique_checker : public base_checker<TreeType, CheckerType> {
390 typedef base_checker<TreeType, CheckerType> super_type;
391 typedef unique_checker<TreeType, CheckerType> self_type;
392
393 public:
394 typedef typename super_type::iterator iterator;
395 typedef typename super_type::value_type value_type;
396
397 public:
398 // Default constructor.
399 unique_checker()
400 : super_type() {
401 }
402 // Copy constructor.
403 unique_checker(const self_type &x)
404 : super_type(x) {
405 }
406 // Range constructor.
407 template <class InputIterator>
408 unique_checker(InputIterator b, InputIterator e)
409 : super_type(b, e) {
410 }
411
412 // Insertion routines.
413 std::pair<iterator,bool> insert(const value_type &x) {
414 int size = this->tree_.size();
415 std::pair<typename CheckerType::iterator,bool> checker_res =
416 this->checker_.insert(x);
417 std::pair<iterator,bool> tree_res = this->tree_.insert(x);
418 EXPECT_EQ(*tree_res.first, *checker_res.first);
419 EXPECT_EQ(tree_res.second, checker_res.second);
420 EXPECT_EQ(this->tree_.size(), this->checker_.size());
421 EXPECT_EQ(this->tree_.size(), size + tree_res.second);
422 return tree_res;
423 }
424 iterator insert(iterator position, const value_type &x) {
425 int size = this->tree_.size();
426 std::pair<typename CheckerType::iterator,bool> checker_res =
427 this->checker_.insert(x);
428 iterator tree_res = this->tree_.insert(position, x);
429 EXPECT_EQ(*tree_res, *checker_res.first);
430 EXPECT_EQ(this->tree_.size(), this->checker_.size());
431 EXPECT_EQ(this->tree_.size(), size + checker_res.second);
432 return tree_res;
433 }
434 template <typename InputIterator>
435 void insert(InputIterator b, InputIterator e) {
436 for (; b != e; ++b) {
437 insert(*b);
438 }
439 }
440};
441
442// A checker for multiple sorted associative containers. TreeType is expected
443// to be btree_{multiset,multimap} and CheckerType is expected to be
444// {multiset,multimap}.
445template <typename TreeType, typename CheckerType>
446class multi_checker : public base_checker<TreeType, CheckerType> {
447 typedef base_checker<TreeType, CheckerType> super_type;
448 typedef multi_checker<TreeType, CheckerType> self_type;
449
450 public:
451 typedef typename super_type::iterator iterator;
452 typedef typename super_type::value_type value_type;
453
454 public:
455 // Default constructor.
456 multi_checker()
457 : super_type() {
458 }
459 // Copy constructor.
460 multi_checker(const self_type &x)
461 : super_type(x) {
462 }
463 // Range constructor.
464 template <class InputIterator>
465 multi_checker(InputIterator b, InputIterator e)
466 : super_type(b, e) {
467 }
468
469 // Insertion routines.
470 iterator insert(const value_type &x) {
471 int size = this->tree_.size();
472 typename CheckerType::iterator checker_res = this->checker_.insert(x);
473 iterator tree_res = this->tree_.insert(x);
474 EXPECT_EQ(*tree_res, *checker_res);
475 EXPECT_EQ(this->tree_.size(), this->checker_.size());
476 EXPECT_EQ(this->tree_.size(), size + 1);
477 return tree_res;
478 }
479 iterator insert(iterator position, const value_type &x) {
480 int size = this->tree_.size();
481 typename CheckerType::iterator checker_res = this->checker_.insert(x);
482 iterator tree_res = this->tree_.insert(position, x);
483 EXPECT_EQ(*tree_res, *checker_res);
484 EXPECT_EQ(this->tree_.size(), this->checker_.size());
485 EXPECT_EQ(this->tree_.size(), size + 1);
486 return tree_res;
487 }
488 template <typename InputIterator>
489 void insert(InputIterator b, InputIterator e) {
490 for (; b != e; ++b) {
491 insert(*b);
492 }
493 }
494};
495
496char* GenerateDigits(char buf[16], int val, int maxval) {
497 EXPECT_LE(val, maxval);
498 int p = 15;
499 buf[p--] = 0;
500 while (maxval > 0) {
501 buf[p--] = '0' + (val % 10);
502 val /= 10;
503 maxval /= 10;
504 }
505 return buf + p + 1;
506}
507
508template <typename K>
509struct Generator {
510 int maxval;
511 Generator(int m)
512 : maxval(m) {
513 }
514 K operator()(int i) const {
515 EXPECT_LE(i, maxval);
516 return i;
517 }
518};
519
520template <>
521struct Generator<std::string> {
522 int maxval;
523 Generator(int m)
524 : maxval(m) {
525 }
526 std::string operator()(int i) const {
527 char buf[16];
528 return GenerateDigits(buf, i, maxval);
529 }
530};
531
532template <typename T, typename U>
533struct Generator<std::pair<T, U> > {
534 Generator<typename std::remove_const<T>::type> tgen;
535 Generator<typename std::remove_const<U>::type> ugen;
536
537 Generator(int m)
538 : tgen(m),
539 ugen(m) {
540 }
541 std::pair<T, U> operator()(int i) const {
542 return std::make_pair(tgen(i), ugen(i));
543 }
544};
545
546// Generate values for our tests and benchmarks. Value range is [0, maxval].
547const std::vector<int>& GenerateNumbers(int n, int maxval) {
548 static std::vector<int> values;
549 static std::set<int> unique_values;
550
551 if (values.size() < n) {
552
553 for (int i = values.size(); i < n; i++) {
554 int value;
555 do {
556 value = rand() % (maxval + 1);
557 } while (unique_values.find(value) != unique_values.end());
558
559 values.push_back(value);
560 unique_values.insert(value);
561 }
562 }
563
564 return values;
565}
566
567// Generates values in the range
568// [0, 4 * min(FLAGS_benchmark_values, FLAGS_test_values)]
569template <typename V>
570std::vector<V> GenerateValues(int n) {
571 int two_times_max = 2 * std::max(FLAGS_benchmark_values, FLAGS_test_values);
572 int four_times_max = 2 * two_times_max;
573 EXPECT_LE(n, two_times_max);
574 const std::vector<int> &nums = GenerateNumbers(n, four_times_max);
575 Generator<V> gen(four_times_max);
576 std::vector<V> vec;
577
578 for (int i = 0; i < n; i++) {
579 vec.push_back(gen(nums[i]));
580 }
581
582 return vec;
583}
584
585template <typename T, typename V>
586void DoTest(const char *name, T *b, const std::vector<V> &values) {
587 typename KeyOfValue<typename T::key_type, V>::type key_of_value;
588
589 T &mutable_b = *b;
590 const T &const_b = *b;
591
592 // Test insert.
593 for (int i = 0; i < values.size(); ++i) {
594 mutable_b.insert(values[i]);
595 mutable_b.value_check(values[i]);
596 }
597 assert(mutable_b.size() == values.size());
598
599 const_b.verify();
600 printf(" %s fullness=%0.2f overhead=%0.2f bytes-per-value=%0.2f\n",
601 name, const_b.fullness(), const_b.overhead(),
602 double(const_b.bytes_used()) / const_b.size());
603
604 // Test copy constructor.
605 T b_copy(const_b);
606 EXPECT_EQ(b_copy.size(), const_b.size());
607 EXPECT_LE(b_copy.height(), const_b.height());
608 EXPECT_LE(b_copy.internal_nodes(), const_b.internal_nodes());
609 EXPECT_LE(b_copy.leaf_nodes(), const_b.leaf_nodes());
610 for (int i = 0; i < values.size(); ++i) {
611 EXPECT_EQ(*b_copy.find(key_of_value(values[i])), values[i]);
612 }
613
614 // Test range constructor.
615 T b_range(const_b.begin(), const_b.end());
616 EXPECT_EQ(b_range.size(), const_b.size());
617 EXPECT_LE(b_range.height(), const_b.height());
618 EXPECT_LE(b_range.internal_nodes(), const_b.internal_nodes());
619 EXPECT_LE(b_range.leaf_nodes(), const_b.leaf_nodes());
620 for (int i = 0; i < values.size(); ++i) {
621 EXPECT_EQ(*b_range.find(key_of_value(values[i])), values[i]);
622 }
623
624 // Test range insertion for values that already exist.
625 b_range.insert(b_copy.begin(), b_copy.end());
626 b_range.verify();
627
628 // Test range insertion for new values.
629 b_range.clear();
630 b_range.insert(b_copy.begin(), b_copy.end());
631 EXPECT_EQ(b_range.size(), b_copy.size());
632 EXPECT_EQ(b_range.height(), b_copy.height());
633 EXPECT_EQ(b_range.internal_nodes(), b_copy.internal_nodes());
634 EXPECT_EQ(b_range.leaf_nodes(), b_copy.leaf_nodes());
635 for (int i = 0; i < values.size(); ++i) {
636 EXPECT_EQ(*b_range.find(key_of_value(values[i])), values[i]);
637 }
638
639 // Test assignment to self. Nothing should change.
640 b_range.operator=(b_range);
641 EXPECT_EQ(b_range.size(), b_copy.size());
642 EXPECT_EQ(b_range.height(), b_copy.height());
643 EXPECT_EQ(b_range.internal_nodes(), b_copy.internal_nodes());
644 EXPECT_EQ(b_range.leaf_nodes(), b_copy.leaf_nodes());
645
646 // Test assignment of new values.
647 b_range.clear();
648 b_range = b_copy;
649 EXPECT_EQ(b_range.size(), b_copy.size());
650 EXPECT_EQ(b_range.height(), b_copy.height());
651 EXPECT_EQ(b_range.internal_nodes(), b_copy.internal_nodes());
652 EXPECT_EQ(b_range.leaf_nodes(), b_copy.leaf_nodes());
653
654 // Test swap.
655 b_range.clear();
656 b_range.swap(b_copy);
657 EXPECT_EQ(b_copy.size(), 0);
658 EXPECT_EQ(b_range.size(), const_b.size());
659 for (int i = 0; i < values.size(); ++i) {
660 EXPECT_EQ(*b_range.find(key_of_value(values[i])), values[i]);
661 }
662 b_range.swap(b_copy);
663
664 // Test erase via values.
665 for (int i = 0; i < values.size(); ++i) {
666 mutable_b.erase(key_of_value(values[i]));
667 // Erasing a non-existent key should have no effect.
668 EXPECT_EQ(mutable_b.erase(key_of_value(values[i])), 0);
669 }
670
671 const_b.verify();
672 EXPECT_EQ(const_b.internal_nodes(), 0);
673 EXPECT_EQ(const_b.leaf_nodes(), 0);
674 EXPECT_EQ(const_b.size(), 0);
675
676 // Test erase via iterators.
677 mutable_b = b_copy;
678 for (int i = 0; i < values.size(); ++i) {
679 mutable_b.erase(mutable_b.find(key_of_value(values[i])));
680 }
681
682 const_b.verify();
683 EXPECT_EQ(const_b.internal_nodes(), 0);
684 EXPECT_EQ(const_b.leaf_nodes(), 0);
685 EXPECT_EQ(const_b.size(), 0);
686
687 // Test insert with hint.
688 for (int i = 0; i < values.size(); i++) {
689 mutable_b.insert(mutable_b.upper_bound(key_of_value(values[i])), values[i]);
690 }
691
692 const_b.verify();
693
694 // Test dumping of the btree to an ostream. There should be 1 line for each
695 // value.
696 std::stringstream strm;
697 strm << mutable_b.tree();
698 EXPECT_EQ(mutable_b.size(), strcount(strm.str(), '\n'));
699
700 // Test range erase.
701 mutable_b.erase(mutable_b.begin(), mutable_b.end());
702 EXPECT_EQ(mutable_b.size(), 0);
703 const_b.verify();
704
705 // First half.
706 mutable_b = b_copy;
707 typename T::iterator mutable_iter_end = mutable_b.begin();
708 for (int i = 0; i < values.size() / 2; ++i) ++mutable_iter_end;
709 mutable_b.erase(mutable_b.begin(), mutable_iter_end);
710 EXPECT_EQ(mutable_b.size(), values.size() - values.size() / 2);
711 const_b.verify();
712
713 // Second half.
714 mutable_b = b_copy;
715 typename T::iterator mutable_iter_begin = mutable_b.begin();
716 for (int i = 0; i < values.size() / 2; ++i) ++mutable_iter_begin;
717 mutable_b.erase(mutable_iter_begin, mutable_b.end());
718 EXPECT_EQ(mutable_b.size(), values.size() / 2);
719 const_b.verify();
720
721 // Second quarter.
722 mutable_b = b_copy;
723 mutable_iter_begin = mutable_b.begin();
724 for (int i = 0; i < values.size() / 4; ++i) ++mutable_iter_begin;
725 mutable_iter_end = mutable_iter_begin;
726 for (int i = 0; i < values.size() / 4; ++i) ++mutable_iter_end;
727 mutable_b.erase(mutable_iter_begin, mutable_iter_end);
728 EXPECT_EQ(mutable_b.size(), values.size() - values.size() / 4);
729 const_b.verify();
730
731 mutable_b.clear();
732}
733
734template <typename T>
735void ConstTest() {
736 typedef typename T::value_type value_type;
737 typename KeyOfValue<typename T::key_type, value_type>::type key_of_value;
738
739 T mutable_b;
740 const T &const_b = mutable_b;
741
742 // Insert a single value into the container and test looking it up.
743 value_type value = Generator<value_type>(2)(2);
744 mutable_b.insert(value);
745 EXPECT_TRUE(mutable_b.find(key_of_value(value)) != const_b.end());
746 EXPECT_TRUE(const_b.find(key_of_value(value)) != mutable_b.end());
747 EXPECT_EQ(*const_b.lower_bound(key_of_value(value)), value);
748 EXPECT_TRUE(const_b.upper_bound(key_of_value(value)) == const_b.end());
749 EXPECT_EQ(*const_b.equal_range(key_of_value(value)).first, value);
750
751 // We can only create a non-const iterator from a non-const container.
752 typename T::iterator mutable_iter(mutable_b.begin());
753 EXPECT_TRUE(mutable_iter == const_b.begin());
754 EXPECT_TRUE(mutable_iter != const_b.end());
755 EXPECT_TRUE(const_b.begin() == mutable_iter);
756 EXPECT_TRUE(const_b.end() != mutable_iter);
757 typename T::reverse_iterator mutable_riter(mutable_b.rbegin());
758 EXPECT_TRUE(mutable_riter == const_b.rbegin());
759 EXPECT_TRUE(mutable_riter != const_b.rend());
760 EXPECT_TRUE(const_b.rbegin() == mutable_riter);
761 EXPECT_TRUE(const_b.rend() != mutable_riter);
762
763 // We can create a const iterator from a non-const iterator.
764 typename T::const_iterator const_iter(mutable_iter);
765 EXPECT_TRUE(const_iter == mutable_b.begin());
766 EXPECT_TRUE(const_iter != mutable_b.end());
767 EXPECT_TRUE(mutable_b.begin() == const_iter);
768 EXPECT_TRUE(mutable_b.end() != const_iter);
769 typename T::const_reverse_iterator const_riter(mutable_riter);
770 EXPECT_EQ(const_riter, mutable_b.rbegin());
771 EXPECT_TRUE(const_riter != mutable_b.rend());
772 EXPECT_EQ(mutable_b.rbegin(), const_riter);
773 EXPECT_TRUE(mutable_b.rend() != const_riter);
774
775 // Make sure various methods can be invoked on a const container.
776 const_b.verify();
777 EXPECT_FALSE(const_b.empty());
778 EXPECT_EQ(const_b.size(), 1);
779 EXPECT_GT(const_b.max_size(), 0);
780 EXPECT_EQ(const_b.height(), 1);
781 EXPECT_EQ(const_b.count(key_of_value(value)), 1);
782 EXPECT_EQ(const_b.internal_nodes(), 0);
783 EXPECT_EQ(const_b.leaf_nodes(), 1);
784 EXPECT_EQ(const_b.nodes(), 1);
785 EXPECT_GT(const_b.bytes_used(), 0);
786 EXPECT_GT(const_b.fullness(), 0);
787 EXPECT_GT(const_b.overhead(), 0);
788}
789
790template <typename T, typename C>
791void BtreeTest() {
792 ConstTest<T>();
793
794 typedef typename std::remove_const<typename T::value_type>::type V;
795 std::vector<V> random_values = GenerateValues<V>(FLAGS_test_values);
796
797 unique_checker<T, C> container;
798
799 // Test key insertion/deletion in sorted order.
800 std::vector<V> sorted_values(random_values);
801 sort(sorted_values.begin(), sorted_values.end());
802 DoTest("sorted: ", &container, sorted_values);
803
804 // Test key insertion/deletion in reverse sorted order.
805 reverse(sorted_values.begin(), sorted_values.end());
806 DoTest("rsorted: ", &container, sorted_values);
807
808 // Test key insertion/deletion in random order.
809 DoTest("random: ", &container, random_values);
810}
811
812template <typename T, typename C>
813void BtreeMultiTest() {
814 ConstTest<T>();
815
816 typedef typename std::remove_const<typename T::value_type>::type V;
817 const std::vector<V>& random_values = GenerateValues<V>(FLAGS_test_values);
818
819 multi_checker<T, C> container;
820
821 // Test keys in sorted order.
822 std::vector<V> sorted_values(random_values);
823 sort(sorted_values.begin(), sorted_values.end());
824 DoTest("sorted: ", &container, sorted_values);
825
826 // Test keys in reverse sorted order.
827 reverse(sorted_values.begin(), sorted_values.end());
828 DoTest("rsorted: ", &container, sorted_values);
829
830 // Test keys in random order.
831 DoTest("random: ", &container, random_values);
832
833 // Test keys in random order w/ duplicates.
834 std::vector<V> duplicate_values(random_values);
835 duplicate_values.insert(
836 duplicate_values.end(), random_values.begin(), random_values.end());
837 DoTest("duplicates:", &container, duplicate_values);
838
839 // Test all identical keys.
840 std::vector<V> identical_values(100);
841 fill(identical_values.begin(), identical_values.end(), Generator<V>(2)(2));
842 DoTest("identical: ", &container, identical_values);
843}
844
845template <typename T, typename Alloc = std::allocator<T> >
846class TestAllocator : public Alloc {
847 public:
848 typedef typename Alloc::pointer pointer;
849 typedef typename Alloc::size_type size_type;
850
851 TestAllocator() : bytes_used_(NULL) { }
852 TestAllocator(int64_t *bytes_used) : bytes_used_(bytes_used) { }
853
854 // Constructor used for rebinding
855 template <class U>
856 TestAllocator(const TestAllocator<U>& x)
857 : Alloc(x),
858 bytes_used_(x.bytes_used()) {
859 }
860
861 pointer allocate(size_type n, std::allocator<void>::const_pointer hint = 0) {
862 EXPECT_TRUE(bytes_used_ != NULL);
863 *bytes_used_ += n * sizeof(T);
864 return Alloc::allocate(n, hint);
865 }
866
867 void deallocate(pointer p, size_type n) {
868 Alloc::deallocate(p, n);
869 EXPECT_TRUE(bytes_used_ != NULL);
870 *bytes_used_ -= n * sizeof(T);
871 }
872
873 // Rebind allows an allocator<T> to be used for a different type
874 template <class U> struct rebind {
875 typedef TestAllocator<U, typename Alloc::template rebind<U>::other> other;
876 };
877
878 int64_t* bytes_used() const { return bytes_used_; }
879
880 private:
881 int64_t *bytes_used_;
882};
883
884template <typename T>
885void BtreeAllocatorTest() {
886 typedef typename T::value_type value_type;
887
888 int64_t alloc1 = 0;
889 int64_t alloc2 = 0;
890 T b1(typename T::key_compare(), &alloc1);
891 T b2(typename T::key_compare(), &alloc2);
892
893 // This should swap the allocators!
894 swap(b1, b2);
895
896 for (int i = 0; i < 1000; i++) {
897 b1.insert(Generator<value_type>(1000)(i));
898 }
899
900 // We should have allocated out of alloc2!
901 EXPECT_LE(b1.bytes_used(), alloc2 + sizeof(b1));
902 EXPECT_GT(alloc2, alloc1);
903}
904
905template <typename T>
906void BtreeMapTest() {
907 typedef typename T::value_type value_type;
908 typedef typename T::mapped_type mapped_type;
909
910 mapped_type m = Generator<mapped_type>(0)(0);
911 (void) m;
912
913 T b;
914
915 // Verify we can insert using operator[].
916 for (int i = 0; i < 1000; i++) {
917 value_type v = Generator<value_type>(1000)(i);
918 b[v.first] = v.second;
919 }
920 EXPECT_EQ(b.size(), 1000);
921
922 // Test whether we can use the "->" operator on iterators and
923 // reverse_iterators. This stresses the btree_map_params::pair_pointer
924 // mechanism.
925 EXPECT_EQ(b.begin()->first, Generator<value_type>(1000)(0).first);
926 EXPECT_EQ(b.begin()->second, Generator<value_type>(1000)(0).second);
927 EXPECT_EQ(b.rbegin()->first, Generator<value_type>(1000)(999).first);
928 EXPECT_EQ(b.rbegin()->second, Generator<value_type>(1000)(999).second);
929}
930
931template <typename T>
932void BtreeMultiMapTest() {
933 typedef typename T::mapped_type mapped_type;
934 mapped_type m = Generator<mapped_type>(0)(0);
935 (void) m;
936}
937
938} // namespace btree
939
940#endif // UTIL_BTREE_BTREE_TEST_H__