use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Manifest {
pub shards: Vec<ShardMetadata>,
pub total_edges: usize,
pub total_sources: usize,
pub version: String,
pub created_at: i64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ShardMetadata {
pub shard_id: usize,
pub source_start: u32,
pub source_end: u32,
pub edge_count: usize,
pub file_name: String,
}
impl Manifest {
pub fn new(shards: Vec<ShardMetadata>, version: String) -> Self {
let total_edges = shards.iter().map(|s| s.edge_count).sum();
let total_sources = shards
.iter()
.map(|s| (s.source_end - s.source_start) as usize)
.sum();
Self {
shards,
total_edges,
total_sources,
version,
created_at: 0, }
}
pub fn get_shard(&self, shard_id: usize) -> Option<&ShardMetadata> {
self.shards.iter().find(|s| s.shard_id == shard_id)
}
pub fn shard_ids(&self) -> Vec<usize> {
let mut ids: Vec<_> = self.shards.iter().map(|s| s.shard_id).collect();
ids.sort();
ids
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_manifest_creation() {
let shards = vec![
ShardMetadata {
shard_id: 0,
source_start: 0,
source_end: 1000,
edge_count: 100,
file_name: "shard_0000.csr".to_string(),
},
ShardMetadata {
shard_id: 1,
source_start: 1000,
source_end: 2000,
edge_count: 150,
file_name: "shard_0001.csr".to_string(),
},
];
let manifest = Manifest::new(shards, "1.0".to_string());
assert_eq!(manifest.total_edges, 250);
assert_eq!(manifest.total_sources, 2000);
assert_eq!(manifest.version, "1.0");
assert_eq!(manifest.created_at, 0);
}
#[test]
fn test_get_shard() {
let shards = vec![
ShardMetadata {
shard_id: 0,
source_start: 0,
source_end: 1000,
edge_count: 100,
file_name: "shard_0000.csr".to_string(),
},
ShardMetadata {
shard_id: 1,
source_start: 1000,
source_end: 2000,
edge_count: 150,
file_name: "shard_0001.csr".to_string(),
},
];
let manifest = Manifest::new(shards, "1.0".to_string());
assert_eq!(manifest.get_shard(0).unwrap().shard_id, 0);
assert_eq!(manifest.get_shard(1).unwrap().shard_id, 1);
assert!(manifest.get_shard(2).is_none());
}
#[test]
fn test_shard_ids() {
let shards = vec![
ShardMetadata {
shard_id: 1,
source_start: 1000,
source_end: 2000,
edge_count: 150,
file_name: "shard_0001.csr".to_string(),
},
ShardMetadata {
shard_id: 0,
source_start: 0,
source_end: 1000,
edge_count: 100,
file_name: "shard_0000.csr".to_string(),
},
];
let manifest = Manifest::new(shards, "1.0".to_string());
let ids = manifest.shard_ids();
assert_eq!(ids, vec![0, 1]); }
}