Rename ArenaAllocator -> Arena

This commit is contained in:
2025-09-05 17:57:04 -04:00
parent 46fe51c0bb
commit f56ed2bfbe
22 changed files with 267 additions and 279 deletions

View File

@@ -25,7 +25,7 @@
#include <immintrin.h>
#include <simdutf.h>
#include "arena_allocator.hpp"
#include "arena.hpp"
#include "format.hpp"
// WeaselDB Metrics System Design:
@@ -79,18 +79,18 @@ namespace metric {
// - Content: Thread-specific metric instance state
//
// 3. TEMPORARY ARENAS:
// a) Caller-Provided Arenas (ArenaAllocator& parameters):
// a) Caller-Provided Arenas (Arena& parameters):
// - Lifetime: Controlled by caller (function parameter)
// - Purpose: Output formatting where caller controls result lifetime
// - Owner: Caller owns arena and controls string lifetime
// - Example: render(ArenaAllocator& arena) - caller manages arena
// - Example: render(Arena& arena) - caller manages arena
// lifecycle
//
// b) Stack-Owned Temporary Arenas:
// - Lifetime: Function/scope lifetime (automatic destruction)
// - Purpose: Internal temporary allocations for lookups and processing
// - Owner: Function owns arena on stack, destroyed at scope exit
// - Example: intern_labels() creates ArenaAllocator lookup_arena(1024)
// - Example: intern_labels() creates Arena lookup_arena(1024)
//
// CRITICAL OWNERSHIP RULES:
//
@@ -124,8 +124,7 @@ static void validate_or_abort(bool condition, const char *message,
}
// Helper to copy a string into arena memory
static std::string_view arena_copy_string(std::string_view str,
ArenaAllocator &arena) {
static std::string_view arena_copy_string(std::string_view str, Arena &arena) {
if (str.empty()) {
return std::string_view{};
}
@@ -142,7 +141,7 @@ struct LabelsKey {
// Arena-owning constructor (copies strings into arena and formats as
// Prometheus text)
LabelsKey(std::span<const std::pair<std::string_view, std::string_view>> l,
ArenaAllocator &arena) {
Arena &arena) {
// Copy and validate all label keys and values, sort by key
ArenaVector<std::pair<std::string_view, std::string_view>> labels(&arena);
for (const auto &[key, value] : l) {
@@ -251,7 +250,7 @@ template <> struct Family<Counter>::State {
ArenaStlAllocator<std::pair<const LabelsKey, Counter::State *>>>
instances;
explicit PerThreadState(ArenaAllocator &arena)
explicit PerThreadState(Arena &arena)
: instances(
ArenaStlAllocator<std::pair<const LabelsKey, Counter::State *>>(
&arena)) {}
@@ -271,7 +270,7 @@ template <> struct Family<Counter>::State {
ArenaStlAllocator<std::pair<const LabelsKey, MetricCallback<Counter>>>>
callbacks;
State(ArenaAllocator &arena)
State(Arena &arena)
: global_accumulated_values(
ArenaStlAllocator<std::pair<const LabelsKey, Counter::State *>>(
&arena)),
@@ -293,7 +292,7 @@ template <> struct Family<Gauge>::State {
ArenaStlAllocator<std::pair<const LabelsKey, MetricCallback<Gauge>>>>
callbacks;
State(ArenaAllocator &arena)
State(Arena &arena)
: instances(ArenaStlAllocator<std::pair<const LabelsKey, Gauge::State *>>(
&arena)),
callbacks(ArenaStlAllocator<
@@ -312,7 +311,7 @@ template <> struct Family<Histogram>::State {
ArenaStlAllocator<std::pair<const LabelsKey, Histogram::State *>>>
instances;
explicit PerThreadState(ArenaAllocator &arena)
explicit PerThreadState(Arena &arena)
: instances(
ArenaStlAllocator<std::pair<const LabelsKey, Histogram::State *>>(
&arena)) {}
@@ -326,7 +325,7 @@ template <> struct Family<Histogram>::State {
ArenaStlAllocator<std::pair<const LabelsKey, Histogram::State *>>>
global_accumulated_values;
State(ArenaAllocator &arena)
State(Arena &arena)
: buckets(&arena),
global_accumulated_values(
ArenaStlAllocator<std::pair<const LabelsKey, Histogram::State *>>(
@@ -371,54 +370,47 @@ struct Metric {
static std::mutex mutex;
// Global arena allocator for metric families and persistent global state
static ArenaAllocator &get_global_arena() {
static auto *global_arena =
new ArenaAllocator(64 * 1024); // 64KB initial size
static Arena &get_global_arena() {
static auto *global_arena = new Arena(64 * 1024); // 64KB initial size
return *global_arena;
}
// Function-local statics to avoid static initialization order fiasco
static auto &get_counter_families() {
using FamilyMap =
std::map<std::string_view, ArenaAllocator::Ptr<Family<Counter>::State>,
std::less<std::string_view>,
ArenaStlAllocator<
std::pair<const std::string_view,
ArenaAllocator::Ptr<Family<Counter>::State>>>>;
static FamilyMap *counterFamilies =
new FamilyMap(ArenaStlAllocator<
std::pair<const std::string_view,
ArenaAllocator::Ptr<Family<Counter>::State>>>(
using FamilyMap = std::map<
std::string_view, Arena::Ptr<Family<Counter>::State>,
std::less<std::string_view>,
ArenaStlAllocator<std::pair<const std::string_view,
Arena::Ptr<Family<Counter>::State>>>>;
static FamilyMap *counterFamilies = new FamilyMap(
ArenaStlAllocator<std::pair<const std::string_view,
Arena::Ptr<Family<Counter>::State>>>(
&get_global_arena()));
return *counterFamilies;
}
static auto &get_gauge_families() {
using FamilyMap =
std::map<std::string_view, ArenaAllocator::Ptr<Family<Gauge>::State>,
std::less<std::string_view>,
ArenaStlAllocator<
std::pair<const std::string_view,
ArenaAllocator::Ptr<Family<Gauge>::State>>>>;
using FamilyMap = std::map<
std::string_view, Arena::Ptr<Family<Gauge>::State>,
std::less<std::string_view>,
ArenaStlAllocator<std::pair<const std::string_view,
Arena::Ptr<Family<Gauge>::State>>>>;
static FamilyMap *gaugeFamilies = new FamilyMap(
ArenaStlAllocator<std::pair<const std::string_view,
ArenaAllocator::Ptr<Family<Gauge>::State>>>(
Arena::Ptr<Family<Gauge>::State>>>(
&get_global_arena()));
return *gaugeFamilies;
}
static auto &get_histogram_families() {
using FamilyMap =
std::map<std::string_view,
ArenaAllocator::Ptr<Family<Histogram>::State>,
std::less<std::string_view>,
ArenaStlAllocator<
std::pair<const std::string_view,
ArenaAllocator::Ptr<Family<Histogram>::State>>>>;
static FamilyMap *histogramFamilies =
new FamilyMap(ArenaStlAllocator<
std::pair<const std::string_view,
ArenaAllocator::Ptr<Family<Histogram>::State>>>(
using FamilyMap = std::map<
std::string_view, Arena::Ptr<Family<Histogram>::State>,
std::less<std::string_view>,
ArenaStlAllocator<std::pair<const std::string_view,
Arena::Ptr<Family<Histogram>::State>>>>;
static FamilyMap *histogramFamilies = new FamilyMap(
ArenaStlAllocator<std::pair<const std::string_view,
Arena::Ptr<Family<Histogram>::State>>>(
&get_global_arena()));
return *histogramFamilies;
}
@@ -446,8 +438,7 @@ struct Metric {
// Registry of all thread arenas for memory tracking
static auto &get_thread_arenas() {
using ThreadArenaMap =
std::unordered_map<std::thread::id, ArenaAllocator *>;
using ThreadArenaMap = std::unordered_map<std::thread::id, Arena *>;
static ThreadArenaMap *threadArenas = new ThreadArenaMap();
return *threadArenas;
}
@@ -460,7 +451,7 @@ struct Metric {
// Thread cleanup for per-family thread-local storage
struct ThreadInit {
ArenaAllocator arena;
Arena arena;
ThreadInit() {
// Register this thread's arena for memory tracking
std::unique_lock<std::mutex> _{mutex};
@@ -536,7 +527,7 @@ struct Metric {
static thread_local ThreadInit thread_init;
// Thread-local arena allocator for metric instances
static ArenaAllocator &get_thread_local_arena() { return thread_init.arena; }
static Arena &get_thread_local_arena() { return thread_init.arena; }
// Thread cleanup now handled by ThreadInit RAII
@@ -561,7 +552,7 @@ struct Metric {
// lifetime)
// Create temporary lookup key using stack-allocated arena
ArenaAllocator lookup_arena(1024); // Small arena for lookups only
Arena lookup_arena(1024); // Small arena for lookups only
LabelsKey lookup_key{labels, lookup_arena};
// Use standard hash set lookup - lookup_key memory used transiently only
@@ -736,7 +727,7 @@ struct Metric {
ArenaVector<Counter::State *> thread_states; // Pre-resolved pointers
Counter::State *global_state; // Pre-resolved global state pointer
CounterLabelData(const LabelsKey &key, ArenaAllocator &arena)
CounterLabelData(const LabelsKey &key, Arena &arena)
: labels_key(key), thread_states(&arena), global_state(nullptr) {}
};
@@ -754,7 +745,7 @@ struct Metric {
Histogram::State *global_state; // Pre-resolved global state pointer
size_t bucket_count; // Cache bucket count from family
HistogramLabelData(const LabelsKey &key, ArenaAllocator &arena)
HistogramLabelData(const LabelsKey &key, Arena &arena)
: labels_key(key), thread_states(&arena), global_state(nullptr),
bucket_count(0) {}
};
@@ -764,7 +755,7 @@ struct Metric {
ArenaVector<ArenaVector<CounterLabelData>> counter_data;
ArenaVector<ArenaVector<GaugeLabelData>> gauge_data;
ArenaVector<ArenaVector<HistogramLabelData>> histogram_data;
explicit LabelSets(ArenaAllocator &arena)
explicit LabelSets(Arena &arena)
: counter_data(&arena), gauge_data(&arena), histogram_data(&arena) {}
};
@@ -846,7 +837,7 @@ struct Metric {
// Three-phase rendering system
struct RenderPlan {
ArenaAllocator arena;
Arena arena;
ArenaVector<std::string_view> static_text{&arena};
ArenaVector<RenderInstruction> instructions{&arena};
uint64_t registration_version;
@@ -865,7 +856,7 @@ struct Metric {
// Use temporary arena for formatting static text (will be interned to
// global arena)
ArenaAllocator temp_arena(8192); // 8KB for temporary formatting
Arena temp_arena(8192); // 8KB for temporary formatting
// Helper function to append an additional label to existing Prometheus
// format
@@ -1091,7 +1082,7 @@ struct Metric {
// Phase 2: Execute phase - run instructions and generate dynamic text
static ArenaVector<std::string_view>
execute_render_plan(ArenaAllocator &arena,
execute_render_plan(Arena &arena,
const ArenaVector<RenderInstruction> &instructions) {
ArenaVector<std::string_view> dynamic_text(&arena);
@@ -1191,7 +1182,7 @@ struct Metric {
// Phase 3: Present phase - interleave static and dynamic text
static ArenaVector<std::string_view>
present_render_output(ArenaAllocator &arena,
present_render_output(Arena &arena,
const ArenaVector<std::string_view> &static_text,
const ArenaVector<std::string_view> &dynamic_text) {
ArenaVector<std::string_view> output(&arena);
@@ -1213,7 +1204,7 @@ struct Metric {
}
// Build label sets once for reuse in both phases
static LabelSets build_label_sets(ArenaAllocator &arena) {
static LabelSets build_label_sets(Arena &arena) {
LabelSets label_sets{arena};
// Build counter data with pre-resolved pointers
@@ -1495,7 +1486,7 @@ Family<Gauge> create_gauge(std::string_view name, std::string_view help) {
auto name_view = arena_copy_string(name, global_arena);
auto &familyPtr = Metric::get_gauge_families()[name_view];
if (!familyPtr) {
// Family<T>::State instances use ArenaAllocator::Ptr for automatic cleanup
// Family<T>::State instances use Arena::Ptr for automatic cleanup
familyPtr = global_arena.construct<Family<Gauge>::State>(global_arena);
familyPtr->name = name_view;
familyPtr->help = arena_copy_string(help, global_arena);
@@ -1519,7 +1510,7 @@ Family<Histogram> create_histogram(std::string_view name, std::string_view help,
auto name_view = arena_copy_string(name, global_arena);
auto &family_ptr = Metric::get_histogram_families()[name_view];
if (!family_ptr) {
// Family<T>::State instances use ArenaAllocator::Ptr for automatic cleanup
// Family<T>::State instances use Arena::Ptr for automatic cleanup
family_ptr = global_arena.construct<Family<Histogram>::State>(global_arena);
family_ptr->name = name_view;
family_ptr->help = arena_copy_string(help, global_arena);
@@ -1688,7 +1679,7 @@ static double calculate_metrics_memory_usage() {
}
// New three-phase render implementation
std::span<std::string_view> render(ArenaAllocator &arena) {
std::span<std::string_view> render(Arena &arena) {
// Initialize self-monitoring metrics (before taking global lock)
static auto memory_gauge = []() {
auto gauge = create_gauge("weaseldb_metrics_memory_bytes",