pub use grafeo_common::memory::usage::{
IndexMemory, MvccMemory, NamedMemory, StoreMemory, StringPoolMemory,
};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct MemoryUsage {
pub total_bytes: usize,
pub store: StoreMemory,
pub indexes: IndexMemory,
pub mvcc: MvccMemory,
pub caches: CacheMemory,
pub string_pool: StringPoolMemory,
pub buffer_manager: BufferManagerMemory,
}
impl MemoryUsage {
pub fn compute_total(&mut self) {
self.total_bytes = self.store.total_bytes
+ self.indexes.total_bytes
+ self.mvcc.total_bytes
+ self.caches.total_bytes
+ self.string_pool.total_bytes
+ self.buffer_manager.allocated_bytes;
}
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct CacheMemory {
pub total_bytes: usize,
pub parsed_plan_cache_bytes: usize,
pub optimized_plan_cache_bytes: usize,
pub cached_plan_count: usize,
}
impl CacheMemory {
pub fn compute_total(&mut self) {
self.total_bytes = self.parsed_plan_cache_bytes + self.optimized_plan_cache_bytes;
}
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct BufferManagerMemory {
pub budget_bytes: usize,
pub allocated_bytes: usize,
pub graph_storage_bytes: usize,
pub index_buffers_bytes: usize,
pub execution_buffers_bytes: usize,
pub spill_staging_bytes: usize,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn default_memory_usage_is_zero() {
let usage = MemoryUsage::default();
assert_eq!(usage.total_bytes, 0);
assert_eq!(usage.store.total_bytes, 0);
assert_eq!(usage.indexes.total_bytes, 0);
assert_eq!(usage.mvcc.total_bytes, 0);
assert_eq!(usage.caches.total_bytes, 0);
assert_eq!(usage.string_pool.total_bytes, 0);
assert_eq!(usage.buffer_manager.allocated_bytes, 0);
}
#[test]
fn compute_total_sums_children() {
let mut usage = MemoryUsage {
store: StoreMemory {
total_bytes: 100,
..Default::default()
},
indexes: IndexMemory {
total_bytes: 200,
..Default::default()
},
mvcc: MvccMemory {
total_bytes: 50,
..Default::default()
},
caches: CacheMemory {
total_bytes: 30,
..Default::default()
},
string_pool: StringPoolMemory {
total_bytes: 10,
..Default::default()
},
buffer_manager: BufferManagerMemory {
allocated_bytes: 20,
..Default::default()
},
..Default::default()
};
usage.compute_total();
assert_eq!(usage.total_bytes, 410);
}
#[test]
fn serde_roundtrip() {
let mut usage = MemoryUsage::default();
usage.store.nodes_bytes = 1024;
usage.indexes.vector_indexes.push(NamedMemory {
name: "vec_idx".to_string(),
bytes: 512,
item_count: 100,
});
usage.mvcc.average_chain_depth = 1.5;
let json = serde_json::to_string(&usage).unwrap();
let deserialized: MemoryUsage = serde_json::from_str(&json).unwrap();
assert_eq!(deserialized.store.nodes_bytes, 1024);
assert_eq!(deserialized.indexes.vector_indexes.len(), 1);
assert_eq!(deserialized.indexes.vector_indexes[0].name, "vec_idx");
assert!((deserialized.mvcc.average_chain_depth - 1.5).abs() < f64::EPSILON);
}
}