use std::collections::{BTreeMap, BTreeSet};
use uqa_core::{Edge, EdgeId, Vertex, VertexId};
use crate::posting_list::GraphPostingListError;
use crate::types::Direction;
#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
pub enum GraphStoreError {
#[error("graph {0:?} does not exist")]
UnknownGraph(String),
#[error("graph id space exhausted: {0}")]
IdExhausted(String),
#[error("invalid graph mutation: {0}")]
InvalidMutation(String),
#[error("invalid graph query: {0}")]
InvalidQuery(String),
#[error("corrupt graph state: {0}")]
CorruptGraph(String),
#[error(transparent)]
InvalidPostingList(#[from] GraphPostingListError),
}
pub type GraphStoreResult<T> = Result<T, GraphStoreError>;
pub trait GraphStore {
fn create_graph(&mut self, name: &str);
fn drop_graph(&mut self, name: &str);
fn graph_names(&self) -> Vec<String>;
fn has_graph(&self, name: &str) -> bool;
fn union_graphs(&mut self, g1: &str, g2: &str, target: &str) -> GraphStoreResult<()>;
fn intersect_graphs(&mut self, g1: &str, g2: &str, target: &str) -> GraphStoreResult<()>;
fn difference_graphs(&mut self, g1: &str, g2: &str, target: &str) -> GraphStoreResult<()>;
fn copy_graph(&mut self, source: &str, target: &str) -> GraphStoreResult<()>;
fn add_vertex(&mut self, vertex: Vertex, graph: &str) -> GraphStoreResult<()>;
fn add_edge(&mut self, edge: Edge, graph: &str) -> GraphStoreResult<()>;
fn remove_vertex(&mut self, vertex_id: VertexId, graph: &str) -> GraphStoreResult<()>;
fn remove_edge(&mut self, edge_id: EdgeId, graph: &str) -> GraphStoreResult<()>;
fn neighbors(
&self,
vertex_id: VertexId,
label: Option<&str>,
direction: Direction,
graph: &str,
) -> GraphStoreResult<Vec<VertexId>>;
fn vertices_by_label(&self, label: &str, graph: &str) -> GraphStoreResult<Vec<Vertex>>;
fn vertex_ids_by_label(&self, label: &str, graph: &str) -> GraphStoreResult<Vec<VertexId>> {
Ok(self
.vertices_by_label(label, graph)?
.into_iter()
.map(|vertex| vertex.vertex_id)
.collect())
}
fn vertices_in_graph(&self, graph: &str) -> GraphStoreResult<Vec<Vertex>>;
fn edges_in_graph(&self, graph: &str) -> GraphStoreResult<Vec<Edge>>;
fn vertex_graphs(&self, vertex_id: VertexId) -> BTreeSet<String>;
fn out_edge_ids(&self, vertex_id: VertexId, graph: &str) -> GraphStoreResult<BTreeSet<EdgeId>>;
fn in_edge_ids(&self, vertex_id: VertexId, graph: &str) -> GraphStoreResult<BTreeSet<EdgeId>>;
fn edge_ids_by_label(&self, label: &str, graph: &str) -> GraphStoreResult<BTreeSet<EdgeId>>;
fn vertex_ids_in_graph(&self, graph: &str) -> GraphStoreResult<BTreeSet<VertexId>>;
fn require_vertex_in_graph(&self, vertex_id: VertexId, graph: &str) -> GraphStoreResult<()> {
if !self.vertex_ids_in_graph(graph)?.contains(&vertex_id) {
return Err(GraphStoreError::InvalidQuery(format!(
"vertex {vertex_id} is not a member of graph {graph:?}"
)));
}
if self.get_vertex(vertex_id).is_none() {
return Err(GraphStoreError::CorruptGraph(format!(
"graph {graph:?} references missing vertex {vertex_id}"
)));
}
Ok(())
}
fn degree_distribution(&self, graph: &str) -> GraphStoreResult<BTreeMap<VertexId, u64>>;
fn label_degree(&self, label: &str, graph: &str) -> GraphStoreResult<f64>;
fn vertex_label_counts(&self, graph: &str) -> GraphStoreResult<BTreeMap<String, u64>>;
fn get_vertex(&self, vertex_id: VertexId) -> Option<&Vertex>;
fn get_edge(&self, edge_id: EdgeId) -> Option<&Edge>;
fn next_vertex_id(&mut self) -> GraphStoreResult<VertexId>;
fn next_edge_id(&mut self) -> GraphStoreResult<EdgeId>;
fn allocate_vertex_id(&mut self, _label: &str, _graph: &str) -> GraphStoreResult<VertexId> {
self.next_vertex_id()
}
fn allocate_edge_id(&mut self, _label: &str, _graph: &str) -> GraphStoreResult<EdgeId> {
self.next_edge_id()
}
fn clear(&mut self);
fn vertices(&self) -> BTreeMap<VertexId, Vertex>;
fn edges(&self) -> BTreeMap<EdgeId, Edge>;
}