Rename ArenaAllocator -> Arena
This commit is contained in:
109
src/metric.cpp
109
src/metric.cpp
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user