caco3_web/jemalloc/
info.rs

1use std::fmt::Write;
2
3use arrayvec::ArrayString;
4use byte_unit::{Byte, UnitType};
5use serde::ser::Error as _;
6use serde::{Serialize, Serializer};
7
8#[derive(Serialize)]
9pub struct JemallocInfo {
10    pub options: Options,
11    pub stats: Stats,
12}
13
14#[derive(Serialize)]
15pub struct Stats {
16    // these two are the most interested
17    #[serde(serialize_with = "serialize_byte")]
18    pub allocated: Byte,
19    #[serde(serialize_with = "serialize_byte")]
20    pub resident: Byte,
21    // other values
22    #[serde(serialize_with = "serialize_byte")]
23    pub active: Byte,
24    #[serde(serialize_with = "serialize_byte")]
25    pub mapped: Byte,
26    #[serde(serialize_with = "serialize_byte")]
27    pub metadata: Byte,
28    #[serde(serialize_with = "serialize_byte")]
29    pub retained: Byte,
30}
31
32fn serialize_byte<S>(this: &Byte, serializer: S) -> Result<S::Ok, S::Error>
33where
34    S: Serializer,
35{
36    let mut buffer: ArrayString<256> = ArrayString::new();
37    let adjusted_byte = this.get_appropriate_unit(UnitType::Binary);
38    write!(&mut buffer, "{adjusted_byte:.2}")
39        .map_err(|_| S::Error::custom(format!("serialize adjusted byte: {adjusted_byte}")))?;
40    serializer.serialize_str(buffer.as_str())
41}
42
43#[derive(Serialize)]
44pub struct Options {
45    pub background_thread: Option<BackgroundThread>,
46    pub number_of_arenas: u32,
47}
48
49#[doc(hidden)]
50#[derive(Serialize)]
51pub struct BackgroundThread {
52    pub enabled: bool,
53    pub max: usize,
54}
55
56#[doc(hidden)]
57pub struct JemallocRawData {
58    // stats
59    pub active_bytes: usize,
60    pub allocated_bytes: usize,
61    pub mapped_bytes: usize,
62    pub metadata_bytes: usize,
63    pub resident_bytes: usize,
64    pub retained_bytes: usize,
65    // options
66    pub background_thread: Option<BackgroundThread>,
67    pub number_of_arenas: u32,
68}
69
70impl JemallocInfo {
71    pub fn from_raw(raw_data: JemallocRawData) -> Option<Self> {
72        fn byte_from_usize(n: usize) -> Option<Byte> {
73            Some(Byte::from_u64(n.try_into().ok()?))
74        }
75        let jemalloc = {
76            let JemallocRawData {
77                active_bytes,
78                allocated_bytes,
79                background_thread,
80                mapped_bytes,
81                metadata_bytes,
82                number_of_arenas,
83                resident_bytes,
84                retained_bytes,
85            } = raw_data;
86            JemallocInfo {
87                options: Options {
88                    background_thread,
89                    number_of_arenas,
90                },
91                stats: Stats {
92                    active: byte_from_usize(active_bytes)?,
93                    allocated: byte_from_usize(allocated_bytes)?,
94                    mapped: byte_from_usize(mapped_bytes)?,
95                    metadata: byte_from_usize(metadata_bytes)?,
96                    resident: byte_from_usize(resident_bytes)?,
97                    retained: byte_from_usize(retained_bytes)?,
98                },
99            }
100        };
101        Some(jemalloc)
102    }
103}