Skip to content

Commit

Permalink
optimize paged index size (#217)
Browse files Browse the repository at this point in the history
  • Loading branch information
felixguendling authored Apr 27, 2024
1 parent bbf4bb5 commit ebd5eb5
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 17 deletions.
29 changes: 16 additions & 13 deletions include/cista/containers/paged.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,42 +11,45 @@

namespace cista {

template <typename SizeType>
template <typename SizeType, typename PageSizeType>
struct page {
bool valid() const { return capacity_ != 0U; }
SizeType size() const noexcept { return size_; }
PageSizeType size() const noexcept { return size_; }

SizeType size_{0U};
SizeType capacity_{0U};
PageSizeType size_{0U};
PageSizeType capacity_{0U};
SizeType start_{0U};
};

template <typename DataVec, typename SizeType = typename DataVec::size_type,
SizeType MinPageSize =
typename PageSizeType = std::uint16_t,
PageSizeType MinPageSize =
std::max(std::size_t{2U},
next_power_of_two(sizeof(page<SizeType>) /
next_power_of_two(sizeof(page<SizeType, PageSizeType>) /
sizeof(typename DataVec::value_type))),
SizeType MaxPageSize = 65536U>
PageSizeType MaxPageSize = 4096>
struct paged {
using value_type = typename DataVec::value_type;
using iterator = typename DataVec::iterator;
using const_iterator = typename DataVec::const_iterator;
using reference = typename DataVec::reference;
using const_reference = typename DataVec::const_reference;
using size_type = SizeType;
using page_t = page<SizeType>;
using page_size_type = PageSizeType;
using page_t = page<SizeType, PageSizeType>;

static_assert(sizeof(value_type) * MinPageSize >= sizeof(page_t));
static_assert(std::is_trivially_copyable_v<value_type>);

static constexpr size_type free_list_index(size_type const capacity) {
static constexpr std::size_t free_list_index(size_type const capacity) {
return static_cast<size_type>(constexpr_trailing_zeros(capacity) -
constexpr_trailing_zeros(MinPageSize));
}

static constexpr size_type free_list_size = free_list_index(MaxPageSize) + 1U;
static constexpr auto const free_list_size =
free_list_index(MaxPageSize) + 1U;

page_t resize_page(page_t const& p, size_type const size) {
page_t resize_page(page_t const& p, PageSizeType const size) {
if (size <= p.capacity_) {
return {size, p.capacity_, p.start_};
} else {
Expand All @@ -57,12 +60,12 @@ struct paged {
}
}

page_t create_page(size_type const size) {
page_t create_page(PageSizeType const size) {
auto const capacity = next_power_of_two(std::max(MinPageSize, size));
auto const i = free_list_index(capacity);
verify(i < free_list_.size(), "paged::create_page: size > max capacity");
if (!free_list_[i].empty()) {
auto start = free_list_[i].pop(*this);
auto const start = free_list_[i].pop(*this);
return {size, capacity, start};
} else {
auto const start = data_.size();
Expand Down
3 changes: 2 additions & 1 deletion include/cista/containers/paged_vecvec.h
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,8 @@ struct paged_vecvec {
typename = std::enable_if_t<std::is_convertible_v<
decltype(*std::declval<Container>().begin()), data_value_type>>>
void emplace_back(Container&& bucket) {
auto p = paged_.create_page(static_cast<size_type>(bucket.size()));
auto p = paged_.create_page(
static_cast<typename Paged::page_size_type>(bucket.size()));
paged_.copy(p, std::begin(bucket), std::end(bucket));
idx_.emplace_back(p);
}
Expand Down
6 changes: 3 additions & 3 deletions test/vecvec_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ TEST_CASE("paged_vecvec mmap") {

using key = cista::strong<unsigned, struct x_>;
using data_t = cista::paged<cista::mmap_vec<char>>;
using idx_t = cista::mmap_vec<cista::page<data_t::size_type>>;
using idx_t = cista::mmap_vec<data_t::page_t>;

auto idx = idx_t{cista::mmap{std::tmpnam(nullptr)}};
auto data = data_t{cista::mmap_vec<char>{cista::mmap{std::tmpnam(nullptr)}}};
Expand Down Expand Up @@ -194,14 +194,14 @@ TEST_CASE("paged_vecvec mmap") {
TEST_CASE("paged_vecvec vector") {
using key = cista::strong<unsigned, struct x_>;
using data_t = cista::paged<cista::raw::vector<char>>;
using idx_t = cista::mmap_vec<cista::page<data_t::size_type>>;
using idx_t = cista::mmap_vec<data_t::page_t>;

auto idx = idx_t{cista::mmap{std::tmpnam(nullptr)}};
auto data = data_t{};
auto d =
cista::paged_vecvec<idx_t, data_t, key>{std::move(data), std::move(idx)};

d.resize(3);
d.resize(3U);
CHECK_EQ(3, d.size());

d.emplace_back("hello");
Expand Down

0 comments on commit ebd5eb5

Please sign in to comment.