|
15 | 15 |
|
16 | 16 | use std::fmt::Display;
|
17 | 17 |
|
18 |
| -use hashbrown::{HashMap, HashSet}; |
| 18 | +use hashbrown::HashMap; |
19 | 19 |
|
20 | 20 | /// Node in the doubly linked list
|
21 | 21 | struct Node<K, V> {
|
@@ -198,30 +198,11 @@ impl<K: Eq + std::hash::Hash + Clone, V: Copy> LruCache<K, V> {
|
198 | 198 | &mut self,
|
199 | 199 | mut f: impl FnMut(&K, V) -> Result<(), E>,
|
200 | 200 | ) -> Result<Result<(), E>, LruCacheCorrupted> {
|
201 |
| - let mut current = self.head; |
202 |
| - |
203 |
| - // Keep track of visited nodes to detect cycles |
204 |
| - let mut visited = HashSet::new(); |
205 |
| - |
206 |
| - while current != self.capacity { |
207 |
| - // Detect cycles |
208 |
| - if !visited.insert(current) { |
209 |
| - return Err(LruCacheCorrupted); |
210 |
| - } |
211 |
| - |
212 |
| - let node = self.order.get_mut(current).ok_or(LruCacheCorrupted)?; |
213 |
| - let next = node.next; |
214 |
| - if node.dirty { |
215 |
| - let value = node.value; |
216 |
| - |
217 |
| - // Call the flush function |
218 |
| - match f(&node.key, value) { |
219 |
| - Ok(()) => node.dirty = false, |
220 |
| - Err(e) => return Ok(Err(e)), |
221 |
| - } |
222 |
| - node.dirty = false; |
| 201 | + for node in self.order.iter_mut().filter(|n| n.dirty) { |
| 202 | + match f(&node.key, node.value) { |
| 203 | + Ok(()) => node.dirty = false, |
| 204 | + Err(e) => return Ok(Err(e)), |
223 | 205 | }
|
224 |
| - current = next; |
225 | 206 | }
|
226 | 207 | Ok(Ok(()))
|
227 | 208 | }
|
@@ -374,7 +355,8 @@ mod tests {
|
374 | 355 | .expect("cache corrupted")
|
375 | 356 | .expect("flush failed");
|
376 | 357 |
|
377 |
| - assert_eq!(flushed, vec![(2, 2), (1, 3)]); |
| 358 | + flushed.sort(); |
| 359 | + assert_eq!(flushed, vec![(1, 3), (2, 2)]); |
378 | 360 | }
|
379 | 361 |
|
380 | 362 | #[test]
|
@@ -407,7 +389,8 @@ mod tests {
|
407 | 389 | .expect("cache corrupted")
|
408 | 390 | .expect("flush failed");
|
409 | 391 |
|
410 |
| - assert_eq!(flushed, [(3, 3), (2, 2)]); |
| 392 | + flushed.sort(); |
| 393 | + assert_eq!(flushed, [(2, 2), (3, 3)]); |
411 | 394 | }
|
412 | 395 |
|
413 | 396 | /// Simple LRU implementation for testing
|
@@ -573,6 +556,8 @@ mod property_tests {
|
573 | 556 | simple_flushed.push((*k, v));
|
574 | 557 | Ok::<(), ()>(())
|
575 | 558 | }).unwrap();
|
| 559 | + flushed.sort(); |
| 560 | + simple_flushed.sort(); |
576 | 561 | prop_assert_eq!(flushed, simple_flushed);
|
577 | 562 | }
|
578 | 563 | };
|
|
0 commit comments