diff --git a/test/boost/chunked_managed_vector_test.cc b/test/boost/chunked_managed_vector_test.cc index 22415c1632..f774b67faa 100644 --- a/test/boost/chunked_managed_vector_test.cc +++ b/test/boost/chunked_managed_vector_test.cc @@ -12,6 +12,8 @@ #include #include #include "utils/lsa/chunked_managed_vector.hh" +#include "utils/managed_ref.hh" +#include "test/lib/log.hh" #include #include @@ -203,3 +205,64 @@ SEASTAR_TEST_CASE(tests_reserve_partial) { }); return make_ready_future<>(); } + +SEASTAR_TEST_CASE(test_clear_and_release) { + region region; + allocating_section as; + + with_allocator(region.allocator(), [&] { + lsa::chunked_managed_vector> v; + + for (uint64_t i = 1; i < 4000; ++i) { + as(region, [&] { + v.emplace_back(make_managed(i)); + }); + } + + v.clear_and_release(); + }); + + return make_ready_future<>(); +} + +SEASTAR_TEST_CASE(test_chunk_reserve) { + region region; + allocating_section as; + + for (auto conf : + { // std::make_pair(reserve size, push count) + std::make_pair(0, 4000), + std::make_pair(100, 4000), + std::make_pair(200, 4000), + std::make_pair(1000, 4000), + std::make_pair(2000, 4000), + std::make_pair(3000, 4000), + std::make_pair(5000, 4000), + std::make_pair(500, 8000), + std::make_pair(1000, 8000), + std::make_pair(2000, 8000), + std::make_pair(8000, 500), + }) + { + with_allocator(region.allocator(), [&] { + auto [reserve_size, push_count] = conf; + testlog.info("Testing reserve({}), {}x emplace_back()", reserve_size, push_count); + lsa::chunked_managed_vector> v; + v.reserve(reserve_size); + uint64_t seed = rand(); + for (uint64_t i = 0; i < push_count; ++i) { + as(region, [&] { + v.emplace_back(make_managed(seed + i)); + BOOST_REQUIRE(**v.begin() == seed); + }); + } + auto v_it = v.begin(); + for (uint64_t i = 0; i < push_count; ++i) { + BOOST_REQUIRE(**v_it++ == seed + i); + } + v.clear_and_release(); + }); + } + + return make_ready_future<>(); +} diff --git a/utils/lsa/chunked_managed_vector.hh b/utils/lsa/chunked_managed_vector.hh index e7a6291659..cbf83eef79 100644 --- a/utils/lsa/chunked_managed_vector.hh +++ b/utils/lsa/chunked_managed_vector.hh @@ -60,6 +60,9 @@ private: throw std::out_of_range("chunked_managed_vector out of range access"); } } + chunk_ptr& back_chunk() { + return _chunks[_size / max_chunk_capacity()]; + } static void migrate(T* begin, T* end, managed_vector& result); public: using value_type = T; @@ -106,24 +109,24 @@ public: void push_back(const T& x) { reserve_for_push_back(); - _chunks.back().emplace_back(x); + back_chunk().emplace_back(x); ++_size; } void push_back(T&& x) { reserve_for_push_back(); - _chunks.back().emplace_back(std::move(x)); + back_chunk().emplace_back(std::move(x)); ++_size; } template T& emplace_back(Args&&... args) { reserve_for_push_back(); - auto& ret = _chunks.back().emplace_back(std::forward(args)...); + auto& ret = back_chunk().emplace_back(std::forward(args)...); ++_size; return ret; } void pop_back() { --_size; - _chunks.back().pop_back(); + back_chunk().pop_back(); } const T& back() const { return *addr(_size - 1);