use crate::core::graph::{Edge, Node};
use crate::core::version::{EdgeVersion, NodeVersion};
use crate::storage::wal::LSN;
use std::sync::Arc;
#[derive(Debug, Clone)]
pub struct CurrentStorageSnapshot {
lsn: LSN,
nodes: Arc<Vec<Node>>,
edges: Arc<Vec<Edge>>,
}
impl CurrentStorageSnapshot {
pub fn new(lsn: LSN, nodes: Arc<Vec<Node>>, edges: Arc<Vec<Edge>>) -> Self {
Self { lsn, nodes, edges }
}
#[cfg(test)]
pub fn nodes(&self) -> &[Node] {
&self.nodes
}
#[cfg(test)]
pub fn edges(&self) -> &[Edge] {
&self.edges
}
pub fn lsn(&self) -> LSN {
self.lsn
}
pub fn node_count(&self) -> usize {
self.nodes.len()
}
pub fn edge_count(&self) -> usize {
self.edges.len()
}
pub fn iter_nodes(&self) -> CurrentNodeIterator {
CurrentNodeIterator {
nodes: self.nodes.clone(),
index: 0,
}
}
pub fn iter_edges(&self) -> CurrentEdgeIterator {
CurrentEdgeIterator {
edges: self.edges.clone(),
index: 0,
}
}
}
pub struct CurrentNodeIterator {
nodes: Arc<Vec<Node>>,
index: usize,
}
impl Iterator for CurrentNodeIterator {
type Item = Node;
fn next(&mut self) -> Option<Self::Item> {
if self.index < self.nodes.len() {
let node = self.nodes[self.index].clone();
self.index += 1;
Some(node)
} else {
None
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let remaining = self.nodes.len() - self.index;
(remaining, Some(remaining))
}
}
impl ExactSizeIterator for CurrentNodeIterator {
fn len(&self) -> usize {
self.nodes.len() - self.index
}
}
pub struct CurrentEdgeIterator {
edges: Arc<Vec<Edge>>,
index: usize,
}
impl Iterator for CurrentEdgeIterator {
type Item = Edge;
fn next(&mut self) -> Option<Self::Item> {
if self.index < self.edges.len() {
let edge = self.edges[self.index].clone();
self.index += 1;
Some(edge)
} else {
None
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let remaining = self.edges.len() - self.index;
(remaining, Some(remaining))
}
}
impl ExactSizeIterator for CurrentEdgeIterator {
fn len(&self) -> usize {
self.edges.len() - self.index
}
}
#[derive(Debug, Clone)]
pub struct HistoricalStorageSnapshot {
lsn: LSN,
node_versions: Vec<Arc<NodeVersion>>,
edge_versions: Vec<Arc<EdgeVersion>>,
}
impl HistoricalStorageSnapshot {
pub fn new(
lsn: LSN,
node_versions: Vec<Arc<NodeVersion>>,
edge_versions: Vec<Arc<EdgeVersion>>,
) -> Self {
Self {
lsn,
node_versions,
edge_versions,
}
}
pub fn lsn(&self) -> LSN {
self.lsn
}
pub fn node_version_count(&self) -> usize {
self.node_versions.len()
}
pub fn edge_version_count(&self) -> usize {
self.edge_versions.len()
}
pub fn iter_node_versions(&self) -> HistoricalNodeVersionIterator {
HistoricalNodeVersionIterator {
versions: self.node_versions.clone(),
index: 0,
}
}
pub fn iter_edge_versions(&self) -> HistoricalEdgeVersionIterator {
HistoricalEdgeVersionIterator {
versions: self.edge_versions.clone(),
index: 0,
}
}
}
pub struct HistoricalNodeVersionIterator {
versions: Vec<Arc<NodeVersion>>,
index: usize,
}
impl Iterator for HistoricalNodeVersionIterator {
type Item = Arc<NodeVersion>;
fn next(&mut self) -> Option<Self::Item> {
if self.index < self.versions.len() {
let version = self.versions[self.index].clone();
self.index += 1;
Some(version)
} else {
None
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let remaining = self.versions.len() - self.index;
(remaining, Some(remaining))
}
}
impl ExactSizeIterator for HistoricalNodeVersionIterator {
fn len(&self) -> usize {
self.versions.len() - self.index
}
}
pub struct HistoricalEdgeVersionIterator {
versions: Vec<Arc<EdgeVersion>>,
index: usize,
}
impl Iterator for HistoricalEdgeVersionIterator {
type Item = Arc<EdgeVersion>;
fn next(&mut self) -> Option<Self::Item> {
if self.index < self.versions.len() {
let version = self.versions[self.index].clone();
self.index += 1;
Some(version)
} else {
None
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let remaining = self.versions.len() - self.index;
(remaining, Some(remaining))
}
}
impl ExactSizeIterator for HistoricalEdgeVersionIterator {
fn len(&self) -> usize {
self.versions.len() - self.index
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::core::id::{NodeId, VersionId};
use crate::core::interning::InternedString;
use crate::core::property::PropertyMap;
#[test]
fn test_current_snapshot_creation() {
let lsn = LSN(42);
let nodes = Arc::new(vec![Node::new(
NodeId::new(1).unwrap(),
InternedString::from_raw(1),
PropertyMap::new(),
VersionId::new(1).unwrap(),
)]);
let edges = Arc::new(vec![]);
let snapshot = CurrentStorageSnapshot::new(lsn, nodes, edges);
assert_eq!(snapshot.lsn(), LSN(42));
assert_eq!(snapshot.node_count(), 1);
assert_eq!(snapshot.edge_count(), 0);
}
#[test]
fn test_current_snapshot_iteration() {
let lsn = LSN(10);
let nodes = Arc::new(vec![
Node::new(
NodeId::new(1).unwrap(),
InternedString::from_raw(1),
PropertyMap::new(),
VersionId::new(1).unwrap(),
),
Node::new(
NodeId::new(2).unwrap(),
InternedString::from_raw(1),
PropertyMap::new(),
VersionId::new(2).unwrap(),
),
]);
let snapshot = CurrentStorageSnapshot::new(lsn, nodes, Arc::new(vec![]));
let collected: Vec<Node> = snapshot.iter_nodes().collect();
assert_eq!(collected.len(), 2);
assert_eq!(collected[0].id, NodeId::new(1).unwrap());
assert_eq!(collected[1].id, NodeId::new(2).unwrap());
}
#[test]
fn test_iterator_exact_size() {
let lsn = LSN(10);
let nodes = Arc::new(vec![
Node::new(
NodeId::new(1).unwrap(),
InternedString::from_raw(1),
PropertyMap::new(),
VersionId::new(1).unwrap(),
),
Node::new(
NodeId::new(2).unwrap(),
InternedString::from_raw(1),
PropertyMap::new(),
VersionId::new(2).unwrap(),
),
]);
let snapshot = CurrentStorageSnapshot::new(lsn, nodes, Arc::new(vec![]));
let mut iter = snapshot.iter_nodes();
assert_eq!(iter.len(), 2);
iter.next();
assert_eq!(iter.len(), 1);
iter.next();
assert_eq!(iter.len(), 0);
}
}