#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ShardCategoryHashes {
pub content_hash: u64,
pub anchors_hash: Option<u64>,
pub entities_hash: Option<u64>,
pub occurrences_hash: Option<u64>,
pub edges_hash: Option<u64>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ShardReplaceResult {
pub content_unchanged: bool,
pub anchors_updated: bool,
pub entities_updated: bool,
pub occurrences_updated: bool,
pub edges_updated: bool,
}
pub fn plan_shard_replacement(
old: Option<ShardCategoryHashes>,
new: ShardCategoryHashes,
) -> ShardReplaceResult {
if let Some(old_hashes) = old {
if old_hashes.content_hash == new.content_hash {
return ShardReplaceResult {
content_unchanged: true,
anchors_updated: false,
entities_updated: false,
occurrences_updated: false,
edges_updated: false,
};
}
}
ShardReplaceResult {
content_unchanged: false,
anchors_updated: category_hash_changed(
old.and_then(|hashes| hashes.anchors_hash),
new.anchors_hash,
),
entities_updated: category_hash_changed(
old.and_then(|hashes| hashes.entities_hash),
new.entities_hash,
),
occurrences_updated: category_hash_changed(
old.and_then(|hashes| hashes.occurrences_hash),
new.occurrences_hash,
),
edges_updated: category_hash_changed(
old.and_then(|hashes| hashes.edges_hash),
new.edges_hash,
),
}
}
pub fn category_hash_changed(old: Option<u64>, new: Option<u64>) -> bool {
match (old, new) {
(Some(o), Some(n)) => o != n,
_ => true,
}
}
#[cfg(test)]
mod tests {
use super::*;
fn hashes(
content_hash: u64,
anchors_hash: Option<u64>,
entities_hash: Option<u64>,
occurrences_hash: Option<u64>,
edges_hash: Option<u64>,
) -> ShardCategoryHashes {
ShardCategoryHashes {
content_hash,
anchors_hash,
entities_hash,
occurrences_hash,
edges_hash,
}
}
#[test]
fn unchanged_content_skips_all_categories() {
let old = hashes(1, Some(10), Some(20), Some(30), Some(40));
let new = hashes(1, Some(11), Some(21), Some(31), Some(41));
let plan = plan_shard_replacement(Some(old), new);
assert!(plan.content_unchanged);
assert!(!plan.anchors_updated);
assert!(!plan.entities_updated);
assert!(!plan.occurrences_updated);
assert!(!plan.edges_updated);
}
#[test]
fn changed_content_compares_each_category() {
let old = hashes(1, Some(10), Some(20), Some(30), Some(40));
let new = hashes(2, Some(10), Some(21), None, Some(40));
let plan = plan_shard_replacement(Some(old), new);
assert!(!plan.content_unchanged);
assert!(!plan.anchors_updated);
assert!(plan.entities_updated);
assert!(plan.occurrences_updated);
assert!(!plan.edges_updated);
}
}