use super::manager::StatisticsManager;
use super::{EdgeTypeStatistics, TagStatistics};
#[derive(Debug)]
pub struct StatsView<'a> {
manager: &'a StatisticsManager,
space: Option<&'a str>,
}
impl<'a> StatsView<'a> {
pub fn new(manager: &'a StatisticsManager, space: Option<&'a str>) -> Self {
Self { manager, space }
}
pub fn space(&self) -> Option<&'a str> {
self.space
}
pub fn vertex_count(&self, tag_name: &str) -> u64 {
match self.space {
Some(space) => self.manager.get_vertex_count(space, tag_name),
None => 0,
}
}
pub fn edge_count(&self, edge_type: &str) -> u64 {
match self.space {
Some(space) => self.manager.get_edge_count(space, edge_type),
None => 0,
}
}
pub fn tag_stats(&self, tag_name: &str) -> Option<TagStatistics> {
match self.space {
Some(space) => self.manager.get_tag_stats(space, tag_name),
None => None,
}
}
pub fn edge_stats(&self, edge_type: &str) -> Option<EdgeTypeStatistics> {
match self.space {
Some(space) => self.manager.get_edge_stats(space, edge_type),
None => None,
}
}
pub fn property_stats(
&self,
tag_name: Option<&str>,
property: &str,
) -> Option<crate::optimizer::stats::PropertyStatistics> {
match self.space {
Some(space) => self.manager.get_property_stats(space, tag_name, property),
None => None,
}
}
pub fn property_ndv(&self, tag_name: Option<&str>, property: &str) -> Option<u64> {
self.property_stats(tag_name, property)
.map(|s| s.distinct_values)
.filter(|&n| n > 0)
}
pub fn combined_cardinality(
&self,
tag_name: Option<&str>,
properties: &[String],
) -> Option<u64> {
match self.space {
Some(space) => self
.manager
.get_combined_cardinality(space, tag_name, properties),
None => None,
}
}
pub fn manager(&self) -> &StatisticsManager {
self.manager
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::optimizer::stats::TagStatistics;
#[test]
fn test_view_without_space_returns_no_stats() {
let manager = StatisticsManager::new();
let view = StatsView::new(&manager, None);
assert_eq!(view.space(), None);
assert_eq!(view.vertex_count("person"), 0);
assert_eq!(view.edge_count("follows"), 0);
assert!(view.tag_stats("person").is_none());
assert!(view.edge_stats("follows").is_none());
}
#[test]
fn test_view_with_space_reads_scoped_stats() {
let manager = StatisticsManager::new();
let mut tag = TagStatistics::new("person".to_string());
tag.vertex_count = 1000;
manager.update_tag_stats("basketball", tag);
let view = StatsView::new(&manager, Some("basketball"));
assert_eq!(view.vertex_count("person"), 1000);
assert_eq!(view.edge_count("follows"), 0);
assert_eq!(view.tag_stats("person").map(|s| s.vertex_count), Some(1000));
let other = StatsView::new(&manager, Some("tennis"));
assert_eq!(other.vertex_count("person"), 0);
}
}