use std::sync::Arc;
use crate::analysis::index::admitted_counts;
use crate::analysis::{GraphAnalysisError, GraphAnalysisLimits, GraphEdgeSelection};
use crate::graph::CodeGraph;
use super::analysis::{CachedGraphAnalysis, DerivedState};
use super::limits::GraphCacheLimits;
use super::state::CacheCounters;
use super::stats::GraphCacheStats;
pub(crate) struct CachedGraphState {
graph: Arc<CodeGraph>,
derived: DerivedState,
}
impl CachedGraphState {
pub(crate) fn new(
graph: CodeGraph,
limits: GraphCacheLimits,
counters: Arc<CacheCounters>,
) -> Self {
Self {
graph: Arc::new(graph),
derived: DerivedState::new(limits, counters),
}
}
pub(crate) fn graph(&self) -> &CodeGraph {
&self.graph
}
pub(crate) fn derived(&self) -> &DerivedState {
&self.derived
}
pub(crate) fn stats(&self) -> GraphCacheStats {
self.derived.counters().snapshot()
}
}
#[derive(Clone)]
pub struct CachedCodeGraph {
state: Arc<CachedGraphState>,
}
impl CachedCodeGraph {
pub(crate) fn new(state: Arc<CachedGraphState>) -> Self {
Self { state }
}
pub fn graph(&self) -> &CodeGraph {
self.state.graph()
}
pub fn stats(&self) -> GraphCacheStats {
self.state.stats()
}
pub fn analyze(
&self,
selection: GraphEdgeSelection,
limits: GraphAnalysisLimits,
) -> Result<CachedGraphAnalysis, GraphAnalysisError> {
let admitted = admitted_counts(self.graph(), selection, limits)?;
let shared = self
.state
.derived()
.indexed(self.graph(), selection, admitted)?;
Ok(CachedGraphAnalysis::new(
Arc::clone(&self.state),
selection,
limits,
shared,
))
}
pub fn clear_analysis_cache(&self) {
self.state.derived().clear();
}
}