72 bool append, std::string_view
key, std::uint64_t row, Reader& reader) {
74 std::uint64_t low = 0, high = count;
76 const auto middle = low + (high - low) / 2;
77 if (reader.compare(read_row(slab, region, middle),
key) < 0) low = middle + 1;
80 if (!append && (low == count || read_row(slab, region, low) != row))
81 throw std::logic_error(
"id slab fold missing sorted row");
85 std::uint64_t bucket = 0, start = 0;
86 if (cached_buckets_ && bucket_count_ != 0) {
88 read_bucket(slab, region, bucket, work.bucket);
89 if (low < start + work.bucket.count || bucket + 1 == bucket_count_)
break;
90 start += work.bucket.count;
98 const auto per_copy = work.buffer.size() / width_;
99 for (
auto end = count;
end > low;) {
100 const auto n = std::min<std::uint64_t>(per_copy,
end - low);
101 const auto bytes =
static_cast<std::size_t
>(width_ * n);
102 slab.
read_at(region, rows_at_ + width_ * (
end - n), work.buffer.data(), bytes);
103 slab.
write_at(region, rows_at_ + width_ * (
end - n + 1), work.buffer.data(), bytes);
106 write_offset(slab, region, rows_at_ + width_ * low, row);
110 if (!cached_buckets_) {
111 work.bucket.count = count;
112 fold_bucket(slab, region, 0, work.bucket, reader);
113 root_ = work.bucket.fold;
116 if (bucket_count_ == 0) bucket_count_ = 1;
117 if (work.bucket.count <= bucket_capacity_) {
118 fold_bucket(slab, region, start, work.bucket, reader);
119 write_bucket(slab, region, bucket, work.bucket);
121 const auto total = work.bucket.count;
123 for (
auto at = bucket_count_; at > bucket + 1; --at) {
124 read_bucket(slab, region, at - 1, work.bucket);
125 write_bucket(slab, region, at, work.bucket);
128 work.bucket.count = total / 2;
129 fold_bucket(slab, region, start, work.bucket, reader);
130 write_bucket(slab, region, bucket, work.bucket);
131 start += work.bucket.count;
132 work.bucket.count = total - work.bucket.count;
133 fold_bucket(slab, region, start, work.bucket, reader);
134 write_bucket(slab, region, bucket + 1, work.bucket);
138 for (std::uint64_t at = 0; at < bucket_count_; ++at) {
139 read_bucket(slab, region, at, work.bucket);
140 reader.compose(work.next, work.bucket.fold);