use std::sync::Arc;
use sqry_core::graph::unified::concurrent::GraphSnapshot;
pub mod diff;
pub use diff::{ChangeType, DiffOptions, DiffOutput, DiffSummary, NodeChange, NodeLocation};
pub struct ComparativeQueryDb {
old: Arc<GraphSnapshot>,
new: Arc<GraphSnapshot>,
}
impl ComparativeQueryDb {
#[must_use]
pub fn new(old: Arc<GraphSnapshot>, new: Arc<GraphSnapshot>) -> Self {
Self { old, new }
}
#[inline]
#[must_use]
pub fn old(&self) -> &GraphSnapshot {
&self.old
}
#[inline]
#[must_use]
pub fn new_snapshot(&self) -> &GraphSnapshot {
&self.new
}
#[inline]
#[must_use]
pub fn old_arc(&self) -> Arc<GraphSnapshot> {
Arc::clone(&self.old)
}
#[inline]
#[must_use]
pub fn new_arc(&self) -> Arc<GraphSnapshot> {
Arc::clone(&self.new)
}
#[must_use]
pub fn diff(&self, opts: &DiffOptions) -> DiffOutput {
if Arc::ptr_eq(&self.old, &self.new) {
return DiffOutput::default();
}
diff::compute_diff(&self.old, &self.new, opts)
}
#[must_use]
pub fn diff_default(&self) -> DiffOutput {
self.diff(&DiffOptions::default())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn comparative_query_db_is_send_sync() {
fn assert_send_sync<T: Send + Sync>() {}
assert_send_sync::<ComparativeQueryDb>();
}
#[test]
fn diff_short_circuits_when_both_sides_share_arc() {
use sqry_core::graph::unified::concurrent::CodeGraph;
let graph = CodeGraph::new();
let snap = Arc::new(graph.snapshot());
let cmp = ComparativeQueryDb::new(Arc::clone(&snap), Arc::clone(&snap));
let out = cmp.diff(&DiffOptions::default());
assert!(out.changes.is_empty(), "expected empty diff on shared Arc");
assert_eq!(out.summary, DiffSummary::default());
}
}