11// SPDX-License-Identifier: BSD-3-Clause
22/* Copyright 2020-2021, Intel Corporation */
33
4+ #include < functional>
5+ #include < libpmemobj.h>
6+ #include < random>
7+
48#include " transaction_helpers.hpp"
59#include " unittest.hpp"
610
711#include < libpmemobj++/experimental/inline_string.hpp>
812#include < libpmemobj++/experimental/radix_tree.hpp>
913
10- #include < functional>
11-
12- #include < libpmemobj.h>
14+ static std::mt19937_64 generator;
1315
1416namespace nvobj = pmem::obj;
1517namespace nvobjex = pmem::obj::experimental;
1618
17- using container_int =
19+ using cntr_int =
1820 nvobjex::radix_tree<nvobjex::inline_string, nvobj::p<unsigned >>;
19- using container_string =
21+ using cntr_string =
2022 nvobjex::radix_tree<nvobjex::inline_string, nvobjex::inline_string>;
2123
22- using container_int_int =
23- nvobjex::radix_tree<unsigned , nvobj::p<unsigned >,
24- nvobjex::bytes_view<unsigned >, false >;
25- using container_int_string =
26- nvobjex::radix_tree<unsigned , nvobjex::inline_string>;
24+ using cntr_int_int = nvobjex::radix_tree<unsigned , nvobj::p<unsigned >,
25+ nvobjex::bytes_view<unsigned >, false >;
26+ using cntr_int_string = nvobjex::radix_tree<unsigned , nvobjex::inline_string>;
2727
28- using container_inline_s_wchart =
28+ using cntr_inline_s_wchart =
2929 nvobjex::radix_tree<nvobjex::basic_inline_string<wchar_t >,
3030 nvobj::p<unsigned >>;
31- using container_inline_s_wchart_wchart =
31+ using cntr_inline_s_wchart_wchart =
3232 nvobjex::radix_tree<nvobjex::basic_inline_string<wchar_t >,
3333 nvobjex::basic_inline_string<wchar_t >>;
34- using container_inline_s_u8t =
34+ using cntr_inline_s_u8t =
3535 nvobjex::radix_tree<nvobjex::basic_inline_string<uint8_t >,
3636 nvobjex::basic_inline_string<uint8_t >>;
3737
38- using container_int_mt =
38+ using cntr_int_mt =
3939 nvobjex::radix_tree<nvobjex::inline_string, nvobj::p<unsigned >,
4040 nvobjex::bytes_view<nvobjex::inline_string>, true >;
41- using container_string_mt =
41+ using cntr_string_mt =
4242 nvobjex::radix_tree<nvobjex::inline_string, nvobjex::inline_string,
4343 nvobjex::bytes_view<nvobjex::inline_string>, true >;
4444
45- using container_int_int_mt =
45+ using cntr_int_int_mt =
4646 nvobjex::radix_tree<unsigned , nvobj::p<unsigned >,
4747 nvobjex::bytes_view<unsigned >, true >;
48- using container_int_string_mt =
48+ using cntr_int_string_mt =
4949 nvobjex::radix_tree<unsigned , nvobjex::inline_string,
5050 nvobjex::bytes_view<unsigned >, true >;
5151
52- using container_inline_s_wchart_mt = nvobjex::radix_tree<
52+ using cntr_inline_s_wchart_mt = nvobjex::radix_tree<
5353 nvobjex::basic_inline_string<wchar_t >, nvobj::p<unsigned >,
5454 nvobjex::bytes_view<nvobjex::basic_inline_string<wchar_t >>, true >;
55- using container_inline_s_wchart_wchart_mt = nvobjex::radix_tree<
55+ using cntr_inline_s_wchart_wchart_mt = nvobjex::radix_tree<
5656 nvobjex::basic_inline_string<wchar_t >,
5757 nvobjex::basic_inline_string<wchar_t >,
5858 nvobjex::bytes_view<nvobjex::basic_inline_string<wchar_t >>, true >;
59- using container_inline_s_u8t_mt = nvobjex::radix_tree<
59+ using cntr_inline_s_u8t_mt = nvobjex::radix_tree<
6060 nvobjex::basic_inline_string<uint8_t >,
6161 nvobjex::basic_inline_string<uint8_t >,
6262 nvobjex::bytes_view<nvobjex::basic_inline_string<uint8_t >>, true >;
6363
6464struct root {
65- nvobj::persistent_ptr<container_int > radix_int;
66- nvobj::persistent_ptr<container_string > radix_str;
65+ nvobj::persistent_ptr<cntr_int > radix_int;
66+ nvobj::persistent_ptr<cntr_string > radix_str;
6767
68- nvobj::persistent_ptr<container_int_int > radix_int_int;
69- nvobj::persistent_ptr<container_int_string > radix_int_str;
68+ nvobj::persistent_ptr<cntr_int_int > radix_int_int;
69+ nvobj::persistent_ptr<cntr_int_string > radix_int_str;
7070
71- nvobj::persistent_ptr<container_inline_s_wchart > radix_inline_s_wchart;
72- nvobj::persistent_ptr<container_inline_s_wchart_wchart >
71+ nvobj::persistent_ptr<cntr_inline_s_wchart > radix_inline_s_wchart;
72+ nvobj::persistent_ptr<cntr_inline_s_wchart_wchart >
7373 radix_inline_s_wchart_wchart;
74- nvobj::persistent_ptr<container_inline_s_u8t > radix_inline_s_u8t;
74+ nvobj::persistent_ptr<cntr_inline_s_u8t > radix_inline_s_u8t;
7575
76- nvobj::persistent_ptr<container_int_mt > radix_int_mt;
77- nvobj::persistent_ptr<container_string_mt > radix_str_mt;
76+ nvobj::persistent_ptr<cntr_int_mt > radix_int_mt;
77+ nvobj::persistent_ptr<cntr_string_mt > radix_str_mt;
7878
79- nvobj::persistent_ptr<container_int_int_mt > radix_int_int_mt;
80- nvobj::persistent_ptr<container_int_string_mt > radix_int_str_mt;
79+ nvobj::persistent_ptr<cntr_int_int_mt > radix_int_int_mt;
80+ nvobj::persistent_ptr<cntr_int_string_mt > radix_int_str_mt;
8181
82- nvobj::persistent_ptr<container_inline_s_wchart_mt>
83- radix_inline_s_wchart_mt;
84- nvobj::persistent_ptr<container_inline_s_wchart_wchart_mt>
82+ nvobj::persistent_ptr<cntr_inline_s_wchart_mt> radix_inline_s_wchart_mt;
83+ nvobj::persistent_ptr<cntr_inline_s_wchart_wchart_mt>
8584 radix_inline_s_wchart_wchart_mt;
86- nvobj::persistent_ptr<container_inline_s_u8t_mt > radix_inline_s_u8t_mt;
85+ nvobj::persistent_ptr<cntr_inline_s_u8t_mt > radix_inline_s_u8t_mt;
8786};
8887
88+ /* Helper functions to access key/value of different types */
8989template <typename Container,
9090 typename Enable = typename std::enable_if<
9191 std::is_same<typename Container::mapped_type,
@@ -108,9 +108,9 @@ value(unsigned v, int repeats = 1)
108108{
109109 using CharT = typename Container::mapped_type::value_type;
110110
111+ auto str = std::to_string (v);
111112 auto s = std::basic_string<CharT>{};
112113 for (int i = 0 ; i < repeats; i++) {
113- auto str = std::to_string (v);
114114 s += std::basic_string<CharT>(str.begin (), str.end ());
115115 }
116116
@@ -178,6 +178,7 @@ operator!=(pmem::obj::experimental::basic_inline_string<CharT, Traits> &lhs,
178178 .compare (rhs) != 0 ;
179179}
180180
181+ /* verify all elements in container, using lower_/upper_bound and find */
181182template <typename Container, typename K, typename F>
182183void
183184verify_elements (nvobj::persistent_ptr<Container> ptr, unsigned count, K &&key_f,
@@ -216,6 +217,8 @@ verify_elements(nvobj::persistent_ptr<Container> ptr, unsigned count, K &&key_f,
216217 }
217218}
218219
220+ /* run 1 thread with modifications (erase/write/etc.) and multiple threads with
221+ * reads */
219222template <typename ModifyF, typename ReadF>
220223static void
221224parallel_modify_read (ModifyF modifier, std::vector<ReadF> &readers,
@@ -230,16 +233,30 @@ parallel_modify_read(ModifyF modifier, std::vector<ReadF> &readers,
230233 });
231234}
232235
236+ /* each test suite should initialize generator at the beginning */
237+ void
238+ init_random ()
239+ {
240+ std::random_device rd;
241+ auto seed = rd ();
242+ std::cout << " rand seed: " << seed << std::endl;
243+ generator = std::mt19937_64 (seed);
244+ }
245+
233246template <typename Container>
234247static void
235248init_container (nvobj::pool<root> &pop, nvobj::persistent_ptr<Container> &ptr,
236- const size_t initial_elements, const size_t value_repeats = 1 )
249+ const size_t initial_elements, const size_t value_repeats = 1 ,
250+ bool rand_keys = false )
237251{
238252 nvobj::transaction::run (
239253 pop, [&] { ptr = nvobj::make_persistent<Container>(); });
240254
241255 for (size_t i = 0 ; i < initial_elements; ++i) {
242- ptr->emplace (key<Container>(i),
243- value<Container>(i, value_repeats));
256+ auto k = key<Container>(i);
257+ if (rand_keys) {
258+ k = key<Container>(static_cast <unsigned >(generator ()));
259+ }
260+ ptr->emplace (k, value<Container>(i, value_repeats));
244261 }
245262}
0 commit comments