Skip to content
This repository was archived by the owner on Mar 22, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,311 changes: 696 additions & 615 deletions include/libpmemobj++/experimental/radix_tree.hpp

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions tests/common/map_wrapper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ struct test_bytes_view;
template <typename T>
struct test_bytes_view<
T, typename std::enable_if<!std::is_signed<T>::value>::type> {
using type = pmem::detail::bytes_view<T>;
using type = nvobjex::bytes_view<T>;
};

struct test_bytes_view_int {
Expand Down Expand Up @@ -93,7 +93,7 @@ erase(C &m, Args &&... args) -> decltype(m.erase(std::forward<Args>(args)...))
#define MAP_VALUE value()
#define TRANSPARENT_COMPARE heterogeneous_bytes_view
#define TRANSPARENT_COMPARE_NOT_REFERENCEABLE heterogeneous_bytes_view
#define TRANSPARENT_COMPARE_STRING pmem::detail::bytes_view<pmem::obj::string>
#define TRANSPARENT_COMPARE_STRING nvobjex::bytes_view<pmem::obj::string>

#endif

Expand Down
42 changes: 41 additions & 1 deletion tests/radix_tree/radix.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ using container_int =
using container_string =
nvobjex::radix_tree<nvobjex::inline_string, nvobjex::inline_string>;

using container_int_int = nvobjex::radix_tree<unsigned, nvobj::p<unsigned>>;
using container_int_int =
nvobjex::radix_tree<unsigned, nvobj::p<unsigned>,
nvobjex::bytes_view<unsigned>, false>;
using container_int_string =
nvobjex::radix_tree<unsigned, nvobjex::inline_string>;

Expand All @@ -33,6 +35,32 @@ using container_inline_s_u8t =
nvobjex::radix_tree<nvobjex::basic_inline_string<uint8_t>,
nvobjex::basic_inline_string<uint8_t>>;

using container_int_mt =
nvobjex::radix_tree<nvobjex::inline_string, nvobj::p<unsigned>,
nvobjex::bytes_view<nvobjex::inline_string>, true>;
using container_string_mt =
nvobjex::radix_tree<nvobjex::inline_string, nvobjex::inline_string,
nvobjex::bytes_view<nvobjex::inline_string>, true>;

using container_int_int_mt =
nvobjex::radix_tree<unsigned, nvobj::p<unsigned>,
nvobjex::bytes_view<unsigned>, true>;
using container_int_string_mt =
nvobjex::radix_tree<unsigned, nvobjex::inline_string,
nvobjex::bytes_view<unsigned>, true>;

using container_inline_s_wchart_mt = nvobjex::radix_tree<
nvobjex::basic_inline_string<wchar_t>, nvobj::p<unsigned>,
nvobjex::bytes_view<nvobjex::basic_inline_string<wchar_t>>, true>;
using container_inline_s_wchart_wchart_mt = nvobjex::radix_tree<
nvobjex::basic_inline_string<wchar_t>,
nvobjex::basic_inline_string<wchar_t>,
nvobjex::bytes_view<nvobjex::basic_inline_string<wchar_t>>, true>;
using container_inline_s_u8t_mt = nvobjex::radix_tree<
nvobjex::basic_inline_string<uint8_t>,
nvobjex::basic_inline_string<uint8_t>,
nvobjex::bytes_view<nvobjex::basic_inline_string<uint8_t>>, true>;

struct root {
nvobj::persistent_ptr<container_int> radix_int;
nvobj::persistent_ptr<container_string> radix_str;
Expand All @@ -44,6 +72,18 @@ struct root {
nvobj::persistent_ptr<container_inline_s_wchart_wchart>
radix_inline_s_wchart_wchart;
nvobj::persistent_ptr<container_inline_s_u8t> radix_inline_s_u8t;

nvobj::persistent_ptr<container_int_mt> radix_int_mt;
nvobj::persistent_ptr<container_string_mt> radix_str_mt;

nvobj::persistent_ptr<container_int_int_mt> radix_int_int_mt;
nvobj::persistent_ptr<container_int_string_mt> radix_int_str_mt;

nvobj::persistent_ptr<container_inline_s_wchart_mt>
radix_inline_s_wchart_mt;
nvobj::persistent_ptr<container_inline_s_wchart_wchart_mt>
radix_inline_s_wchart_wchart_mt;
nvobj::persistent_ptr<container_inline_s_u8t_mt> radix_inline_s_u8t_mt;
};

template <typename Container,
Expand Down
35 changes: 19 additions & 16 deletions tests/radix_tree/radix_concurrent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ test_write_find(nvobj::pool<root> &pop, nvobj::persistent_ptr<Container> &ptr)
/* this test only works with int as a key type */
static void
test_various_readers(nvobj::pool<root> &pop,
nvobj::persistent_ptr<container_int_int> &ptr)
nvobj::persistent_ptr<container_int_int_mt> &ptr)
{
size_t threads = 16;
if (On_drd)
Expand All @@ -72,19 +72,20 @@ test_various_readers(nvobj::pool<root> &pop,
auto readers = std::vector<std::function<void()>>{
[&]() {
for (size_t i = 0; i < INITIAL_ELEMENTS; ++i) {
auto res = ptr->find(key<container_int_int>(i));
auto res =
ptr->find(key<container_int_int_mt>(i));
UT_ASSERT(res != ptr->end());
UT_ASSERT(res->value() ==
value<container_int_int>(i));
value<container_int_int_mt>(i));
}
},
[&]() {
for (size_t i = 0; i < INITIAL_ELEMENTS; ++i) {
auto res = ptr->lower_bound(
key<container_int_int>(i));
key<container_int_int_mt>(i));
UT_ASSERT(res != ptr->end());
UT_ASSERT(res->value() ==
value<container_int_int>(i));
value<container_int_int_mt>(i));
}
},
[&]() {
Expand All @@ -93,15 +94,16 @@ test_various_readers(nvobj::pool<root> &pop,
key<container_int_int>(i));
UT_ASSERT(res != ptr->end());
UT_ASSERT(res->value() ==
value<container_int_int>(i + 1));
value<container_int_int_mt>(i + 1));
}
},
};

parallel_modify_read(writer, readers, threads);

nvobj::transaction::run(
pop, [&] { nvobj::delete_persistent<container_int_int>(ptr); });
nvobj::transaction::run(pop, [&] {
nvobj::delete_persistent<container_int_int_mt>(ptr);
});

UT_ASSERTeq(num_allocs(pop), 0);
}
Expand All @@ -124,16 +126,17 @@ test(int argc, char *argv[])
UT_FATAL("!pool::create: %s %s", pe.what(), path);
}

test_write_find(pop, pop.root()->radix_int_int);
test_various_readers(pop, pop.root()->radix_int_int);
test_write_find(pop, pop.root()->radix_int_int_mt);
test_various_readers(pop, pop.root()->radix_int_int_mt);

if (!On_drd) {
test_write_find(pop, pop.root()->radix_int);
test_write_find(pop, pop.root()->radix_int_str);
test_write_find(pop, pop.root()->radix_str);
test_write_find(pop, pop.root()->radix_inline_s_wchart_wchart);
test_write_find(pop, pop.root()->radix_inline_s_wchart);
test_write_find(pop, pop.root()->radix_inline_s_u8t);
test_write_find(pop, pop.root()->radix_int_mt);
test_write_find(pop, pop.root()->radix_int_str_mt);
test_write_find(pop, pop.root()->radix_str_mt);
test_write_find(pop,
pop.root()->radix_inline_s_wchart_wchart_mt);
test_write_find(pop, pop.root()->radix_inline_s_wchart_mt);
test_write_find(pop, pop.root()->radix_inline_s_u8t_mt);
}

pop.close();
Expand Down
50 changes: 27 additions & 23 deletions tests/radix_tree/radix_concurrent_erase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ static size_t INITIAL_ELEMENTS = 512;
* erase all elements and read them from the other threads. */
static void
test_erase_find(nvobj::pool<root> &pop,
nvobj::persistent_ptr<container_string> &ptr)
nvobj::persistent_ptr<container_string_mt> &ptr)
{
const size_t value_repeats = 1000;
size_t threads = 4;
Expand All @@ -26,7 +26,7 @@ test_erase_find(nvobj::pool<root> &pop,

auto erase_f = [&] {
for (size_t i = 0; i < INITIAL_ELEMENTS; ++i) {
ptr->erase(key<container_string>(i));
ptr->erase(key<container_string_mt>(i));
ptr->garbage_collect();
}
};
Expand All @@ -38,11 +38,11 @@ test_erase_find(nvobj::pool<root> &pop,
for (size_t i = 0; i < INITIAL_ELEMENTS; ++i) {
w.critical([&] {
auto res = ptr->find(
key<container_string>(i));
key<container_string_mt>(i));
UT_ASSERT(
res == ptr->end() ||
res->value() ==
value<container_string>(
value<container_string_mt>(
i,
value_repeats));
});
Expand All @@ -57,8 +57,9 @@ test_erase_find(nvobj::pool<root> &pop,

ptr->runtime_finalize_mt();

nvobj::transaction::run(
pop, [&] { nvobj::delete_persistent<container_string>(ptr); });
nvobj::transaction::run(pop, [&] {
nvobj::delete_persistent<container_string_mt>(ptr);
});

UT_ASSERTeq(num_allocs(pop), 0);
}
Expand All @@ -67,7 +68,7 @@ test_erase_find(nvobj::pool<root> &pop,
* Concurrently try to read this element from other threads */
static void
test_write_erase_find(nvobj::pool<root> &pop,
nvobj::persistent_ptr<container_string> &ptr)
nvobj::persistent_ptr<container_string_mt> &ptr)
{
const size_t value_repeats = 1000;
size_t threads = 8;
Expand All @@ -79,9 +80,10 @@ test_write_erase_find(nvobj::pool<root> &pop,

auto writer_f = [&] {
for (size_t i = 0; i < INITIAL_ELEMENTS; ++i) {
ptr->emplace(key<container_string>(0),
value<container_string>(0, value_repeats));
ptr->erase(key<container_string>(0));
ptr->emplace(
key<container_string_mt>(0),
value<container_string_mt>(0, value_repeats));
ptr->erase(key<container_string_mt>(0));
ptr->garbage_collect();
}
};
Expand All @@ -93,11 +95,11 @@ test_write_erase_find(nvobj::pool<root> &pop,
for (size_t i = 0; i < INITIAL_ELEMENTS; ++i) {
w.critical([&] {
auto res = ptr->find(
key<container_string>(0));
key<container_string_mt>(0));
UT_ASSERT(
res == ptr->end() ||
res->value() ==
value<container_string>(
value<container_string_mt>(
0,
value_repeats));
});
Expand All @@ -111,8 +113,9 @@ test_write_erase_find(nvobj::pool<root> &pop,

ptr->runtime_finalize_mt();

nvobj::transaction::run(
pop, [&] { nvobj::delete_persistent<container_string>(ptr); });
nvobj::transaction::run(pop, [&] {
nvobj::delete_persistent<container_string_mt>(ptr);
});

UT_ASSERTeq(num_allocs(pop), 0);
}
Expand All @@ -123,7 +126,7 @@ test_write_erase_find(nvobj::pool<root> &pop,
* deleting and reading elements */
static void
test_garbage_collection(nvobj::pool<root> &pop,
nvobj::persistent_ptr<container_string> &ptr)
nvobj::persistent_ptr<container_string_mt> &ptr)
{
const size_t value_repeats = 1000;
size_t threads = 8;
Expand All @@ -139,7 +142,7 @@ test_garbage_collection(nvobj::pool<root> &pop,
if (id == 0) {
/* deleter */
for (size_t i = 0; i < INITIAL_ELEMENTS; ++i) {
ptr->erase(key<container_string>(i));
ptr->erase(key<container_string_mt>(i));

if (i % 50 == 0) {
syncthreads();
Expand All @@ -154,11 +157,11 @@ test_garbage_collection(nvobj::pool<root> &pop,
for (size_t i = 0; i < INITIAL_ELEMENTS; ++i) {
w.critical([&] {
auto res = ptr->find(
key<container_string>(i));
key<container_string_mt>(i));
UT_ASSERT(
res == ptr->end() ||
res->value() ==
value<container_string>(
value<container_string_mt>(
i,
value_repeats));
});
Expand All @@ -177,8 +180,9 @@ test_garbage_collection(nvobj::pool<root> &pop,

ptr->runtime_finalize_mt();

nvobj::transaction::run(
pop, [&] { nvobj::delete_persistent<container_string>(ptr); });
nvobj::transaction::run(pop, [&] {
nvobj::delete_persistent<container_string_mt>(ptr);
});

UT_ASSERTeq(num_allocs(pop), 0);
}
Expand All @@ -201,9 +205,9 @@ test(int argc, char *argv[])
UT_FATAL("!pool::create: %s %s", pe.what(), path);
}

test_erase_find(pop, pop.root()->radix_str);
test_write_erase_find(pop, pop.root()->radix_str);
test_garbage_collection(pop, pop.root()->radix_str);
test_erase_find(pop, pop.root()->radix_str_mt);
test_write_erase_find(pop, pop.root()->radix_str_mt);
test_garbage_collection(pop, pop.root()->radix_str_mt);

pop.close();
}
Expand Down
Loading