use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CsrShard {
pub shard_id: usize,
pub source_start: u32,
pub source_end: u32,
pub edges: Vec<CsrEdge>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct CsrEdge {
pub src: u32,
pub dst: u32,
pub weight: f32,
pub flags: u32,
}
impl CsrShard {
pub fn new(shard_id: usize, source_start: u32, source_end: u32) -> Self {
Self {
shard_id,
source_start,
source_end,
edges: Vec::new(),
}
}
pub fn add_edge(&mut self, edge: CsrEdge) {
assert!(
edge.src >= self.source_start && edge.src < self.source_end,
"Edge src {} outside shard range [{}, {})",
edge.src,
self.source_start,
self.source_end
);
self.edges.push(edge);
}
pub fn sort_edges(&mut self) {
self.edges
.sort_by(|a, b| a.src.cmp(&b.src).then_with(|| a.dst.cmp(&b.dst)));
}
pub fn edge_count(&self) -> usize {
self.edges.len()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_shard_creation() {
let shard = CsrShard::new(0, 1000, 2000);
assert_eq!(shard.shard_id, 0);
assert_eq!(shard.source_start, 1000);
assert_eq!(shard.source_end, 2000);
assert_eq!(shard.edge_count(), 0);
}
#[test]
fn test_add_edge() {
let mut shard = CsrShard::new(0, 1000, 2000);
let edge = CsrEdge {
src: 1500,
dst: 2500,
weight: 0.5,
flags: 0,
};
shard.add_edge(edge.clone());
assert_eq!(shard.edge_count(), 1);
assert_eq!(shard.edges[0], edge);
}
#[test]
#[should_panic]
fn test_add_edge_outside_range_panics() {
let mut shard = CsrShard::new(0, 1000, 2000);
let edge = CsrEdge {
src: 500, dst: 2500,
weight: 0.5,
flags: 0,
};
shard.add_edge(edge); }
#[test]
fn test_sort_edges() {
let mut shard = CsrShard::new(0, 1000, 2000);
shard.add_edge(CsrEdge {
src: 1500,
dst: 2500,
weight: 0.3,
flags: 0,
});
shard.add_edge(CsrEdge {
src: 1200,
dst: 2300,
weight: 0.5,
flags: 0,
});
shard.add_edge(CsrEdge {
src: 1500,
dst: 2400,
weight: 0.2,
flags: 0,
});
shard.sort_edges();
assert_eq!(shard.edges[0].src, 1200);
assert_eq!(shard.edges[1].src, 1500);
assert_eq!(shard.edges[1].dst, 2400); assert_eq!(shard.edges[2].dst, 2500);
}
}