Buckets
A bucket is a pool of same-size slots inside a shard. Shards give you isolation; buckets give you speed — every slot in a bucket shares one size, one alignment and one free-list, so allocation is a pop and a store.
A bucket is never created on its own. It is declared when you create the shard, as one object_spec_t entry, and you later grab a handle to it with shard.get_bucket(tag, concurrency_model).
#include <frameworkcpp/arena/arena.hpp> // to build the arena + shard in the examplesThe handle itself — arena_bucket_t — lives in <frameworkcpp/arena/bucket.hpp>; include that directly when you receive a bucket without building the arena.
Declaring a bucket
A bucket lives inside a shard's create_shard call. Each object_spec_t entry becomes one bucket:
enum class bucket_tag : std::uint64_t { commands = 0, payloads = 1 };
auto shard = arena.create_shard(
1, // shard tag
{
// { tag, object_size, align, count }
{static_cast<std::uint64_t>(bucket_tag::commands), sizeof(std::uint64_t),
alignof(std::uint64_t), 1024}, // 1024 slots of 8 bytes
{static_cast<std::uint64_t>(bucket_tag::payloads), 256, 64, 64},
// 256 slots of 256 bytes, aligned to 64
});Holding a bucket
arena_bucket_t get_bucket(std::uint64_t tag, concurrency_model model);- Pass the bucket tag you declared, and the concurrency model this bucket will use.
- The first call for a tag fixes the bucket's model. Requesting a different model afterwards aborts the program.
- The handle is empty (falsy) if no bucket with that tag exists in the shard.
Using it
template <typename T>
T* allocate(std::size_t count = 1); // nullptr if the slot is too small
template <typename T>
void deallocate(T* p) noexcept;
void deallocate_bytes(void* p) noexcept;
std::uint64_t tag() const noexcept;
explicit operator bool() const noexcept;A bucket handle only hands out slots from its own pool — it never goes hunting through the shard. Freed slots are reused within the bucket. Allocation fails with nullptr when the request is bigger than the bucket's object_size or more aligned than the bucket allows.
Example
using namespace frameworkcpp::arena;
arena_t arena;
auto shard = arena.create_shard(
1,
{{0, sizeof(std::uint64_t), alignof(std::uint64_t), 1024}}); // one bucket, tag 0
auto bucket = shard.get_bucket(0, concurrency_model::lock_free);
auto* slot = bucket.allocate<std::uint64_t>(); // only ever from bucket 0
if (slot) *slot = 7;
bucket.deallocate(slot);