perl_workspace/semantic/
invalidation.rs1#[derive(Debug, Clone, Copy, PartialEq, Eq)]
9pub struct ShardCategoryHashes {
10 pub content_hash: u64,
12 pub anchors_hash: Option<u64>,
14 pub entities_hash: Option<u64>,
16 pub occurrences_hash: Option<u64>,
18 pub edges_hash: Option<u64>,
20}
21
22#[derive(Debug, Clone, PartialEq, Eq)]
28pub struct ShardReplaceResult {
29 pub content_unchanged: bool,
32 pub anchors_updated: bool,
34 pub entities_updated: bool,
36 pub occurrences_updated: bool,
38 pub edges_updated: bool,
40}
41
42pub fn plan_shard_replacement(
45 old: Option<ShardCategoryHashes>,
46 new: ShardCategoryHashes,
47) -> ShardReplaceResult {
48 if let Some(old_hashes) = old {
49 if old_hashes.content_hash == new.content_hash {
50 return ShardReplaceResult {
51 content_unchanged: true,
52 anchors_updated: false,
53 entities_updated: false,
54 occurrences_updated: false,
55 edges_updated: false,
56 };
57 }
58 }
59
60 ShardReplaceResult {
61 content_unchanged: false,
62 anchors_updated: category_hash_changed(
63 old.and_then(|hashes| hashes.anchors_hash),
64 new.anchors_hash,
65 ),
66 entities_updated: category_hash_changed(
67 old.and_then(|hashes| hashes.entities_hash),
68 new.entities_hash,
69 ),
70 occurrences_updated: category_hash_changed(
71 old.and_then(|hashes| hashes.occurrences_hash),
72 new.occurrences_hash,
73 ),
74 edges_updated: category_hash_changed(
75 old.and_then(|hashes| hashes.edges_hash),
76 new.edges_hash,
77 ),
78 }
79}
80
81pub fn category_hash_changed(old: Option<u64>, new: Option<u64>) -> bool {
87 match (old, new) {
88 (Some(o), Some(n)) => o != n,
89 _ => true,
90 }
91}
92
93#[cfg(test)]
94mod tests {
95 use super::*;
96
97 fn hashes(
98 content_hash: u64,
99 anchors_hash: Option<u64>,
100 entities_hash: Option<u64>,
101 occurrences_hash: Option<u64>,
102 edges_hash: Option<u64>,
103 ) -> ShardCategoryHashes {
104 ShardCategoryHashes {
105 content_hash,
106 anchors_hash,
107 entities_hash,
108 occurrences_hash,
109 edges_hash,
110 }
111 }
112
113 #[test]
114 fn unchanged_content_skips_all_categories() {
115 let old = hashes(1, Some(10), Some(20), Some(30), Some(40));
116 let new = hashes(1, Some(11), Some(21), Some(31), Some(41));
117
118 let plan = plan_shard_replacement(Some(old), new);
119
120 assert!(plan.content_unchanged);
121 assert!(!plan.anchors_updated);
122 assert!(!plan.entities_updated);
123 assert!(!plan.occurrences_updated);
124 assert!(!plan.edges_updated);
125 }
126
127 #[test]
128 fn changed_content_compares_each_category() {
129 let old = hashes(1, Some(10), Some(20), Some(30), Some(40));
130 let new = hashes(2, Some(10), Some(21), None, Some(40));
131
132 let plan = plan_shard_replacement(Some(old), new);
133
134 assert!(!plan.content_unchanged);
135 assert!(!plan.anchors_updated);
136 assert!(plan.entities_updated);
137 assert!(plan.occurrences_updated);
138 assert!(!plan.edges_updated);
139 }
140}