use crate::types::memory_estimation::MemoryEstimatable;
use crate::value::Value;
impl MemoryEstimatable for Value {
fn estimate_memory(&self) -> usize {
let base_size = std::mem::size_of::<Value>();
match self {
Value::Empty
| Value::Null(_)
| Value::Bool(_)
| Value::SmallInt(_)
| Value::Int(_)
| Value::BigInt(_)
| Value::Float(_)
| Value::Double(_) => base_size,
Value::String(s) => base_size + s.len(),
Value::FixedString(data) => base_size + data.len(),
Value::Blob(b) => base_size + b.len(),
Value::Decimal128(d) => base_size + std::mem::size_of_val(d),
Value::Date(_) | Value::Time(_) | Value::DateTime(_) => base_size,
Value::Vertex(v) => base_size + std::mem::size_of_val(v.as_ref()),
Value::Edge(e) => base_size + std::mem::size_of_val(e.as_ref()),
Value::EdgeHeader(h) => base_size + std::mem::size_of_val(h.as_ref()),
Value::Path(p) => base_size + std::mem::size_of_val(p.as_ref()),
Value::List(list) => {
base_size + list.iter().map(|v| v.estimate_memory()).sum::<usize>()
}
Value::Map(map) => {
base_size
+ map.capacity() * 8
+ map
.iter()
.map(|(k, v)| k.estimate_memory() + v.estimate_memory())
.sum::<usize>()
}
Value::Set(set) => {
base_size
+ set.capacity() * 8
+ set.iter().map(|v| v.estimate_memory()).sum::<usize>()
}
Value::Geography(g) => base_size + std::mem::size_of_val(g),
Value::Vector(v) => base_size + v.estimated_size(),
Value::DataSet(ds) => base_size + ds.as_ref().estimated_size(),
Value::Json(j) => base_size + j.estimated_size(),
Value::JsonB(j) => base_size + j.estimated_size(),
Value::Uuid(_) => base_size,
Value::Interval(_) => base_size,
Value::VertexId(_) | Value::EdgeId(_) => base_size,
Value::Struct(s) => {
base_size
+ s.fields
.iter()
.map(|(k, v)| k.len() + v.estimate_memory())
.sum::<usize>()
}
Value::Array(a) => {
base_size + a.values.iter().map(|v| v.estimate_memory()).sum::<usize>()
}
}
}
}
pub fn estimate_values_memory(values: &[Value]) -> usize {
values.iter().map(|v| v.estimate_memory()).sum()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_fixed_size_value() {
let v = Value::Int(42);
assert_eq!(v.estimate_memory(), std::mem::size_of::<Value>());
}
#[test]
fn test_string_value() {
let s = compact_str::CompactString::new("hello");
let v = Value::String(s);
assert_eq!(v.estimate_memory(), std::mem::size_of::<Value>() + 5);
}
#[test]
fn test_list_value() {
use crate::value::list::List;
let list = vec![
Value::Int(1),
Value::Int(2),
Value::String(compact_str::CompactString::new("hello")),
];
let v = Value::List(Box::new(List::from(list)));
let expected = std::mem::size_of::<Value>()
+ std::mem::size_of::<Value>() * 2
+ (std::mem::size_of::<Value>() + 5);
assert!(v.estimate_memory() >= expected);
}
}