brows3r_lib/cache/
invalidation.rs1use crate::ids::{BucketId, ProfileId};
13
14use super::store::CacheHandle;
15use super::CacheKey;
16
17pub fn on_object_mutation(
24 profile: &ProfileId,
25 bucket: &BucketId,
26 prefix: &str,
27 object_key: Option<&crate::ids::ObjectKey>,
28 store: &CacheHandle,
29) {
30 store.invalidate(&CacheKey::Objects {
32 profile: profile.clone(),
33 bucket: bucket.clone(),
34 prefix: prefix.to_string(),
35 });
36
37 if let Some(key) = object_key {
40 store.invalidate(&CacheKey::ObjectHead {
41 profile: profile.clone(),
42 bucket: bucket.clone(),
43 key: key.clone(),
44 });
45 store.invalidate(&CacheKey::Inspector {
47 profile: profile.clone(),
48 bucket: bucket.clone(),
49 key: Some(key.clone()),
50 });
51 }
52}
53
54pub fn on_bucket_mutation(profile: &ProfileId, store: &CacheHandle) {
57 store.invalidate(&CacheKey::Buckets(profile.clone()));
58}
59
60#[cfg(test)]
65mod tests {
66 use super::*;
67 use crate::{
68 cache::{
69 store::{CacheStore, MockClock},
70 CacheConfig,
71 },
72 ids::{BucketId, ObjectKey, ProfileId},
73 };
74
75 fn make_store() -> CacheHandle {
76 CacheStore::new_with_clock(CacheConfig::default(), MockClock::new(1_000_000), None)
77 }
78
79 #[test]
80 fn on_object_mutation_removes_objects_and_head_entries() {
81 let store = make_store();
82 let pid = ProfileId::new("p");
83 let bid = BucketId::new("b");
84 let key = ObjectKey::new("folder/file.txt");
85 let validated = Some(0_i64);
86
87 let objects_key = CacheKey::Objects {
89 profile: pid.clone(),
90 bucket: bid.clone(),
91 prefix: "folder/".to_string(),
92 };
93 let head_key = CacheKey::ObjectHead {
94 profile: pid.clone(),
95 bucket: bid.clone(),
96 key: key.clone(),
97 };
98
99 store
100 .put(&objects_key, serde_json::json!(["file.txt"]), None)
101 .unwrap();
102 store
103 .put(&head_key, serde_json::json!({"size": 42}), None)
104 .unwrap();
105
106 on_object_mutation(&pid, &bid, "folder/", Some(&key), &store);
108
109 assert!(
110 store
111 .get::<serde_json::Value>(&objects_key, validated)
112 .unwrap()
113 .is_none(),
114 "Objects entry must be invalidated"
115 );
116 assert!(
117 store
118 .get::<serde_json::Value>(&head_key, validated)
119 .unwrap()
120 .is_none(),
121 "ObjectHead entry must be invalidated"
122 );
123 }
124
125 #[test]
126 fn on_bucket_mutation_removes_bucket_list_entry() {
127 let store = make_store();
128 let pid = ProfileId::new("p");
129 let validated = Some(0_i64);
130
131 let buckets_key = CacheKey::Buckets(pid.clone());
132 store
133 .put(&buckets_key, serde_json::json!(["b1", "b2"]), None)
134 .unwrap();
135
136 on_bucket_mutation(&pid, &store);
137
138 assert!(
139 store
140 .get::<serde_json::Value>(&buckets_key, validated)
141 .unwrap()
142 .is_none(),
143 "Buckets entry must be invalidated after bucket mutation"
144 );
145 }
146}