1use std::collections::{btree_map::Entry, hash_map::RandomState, BTreeMap, BTreeSet};
7
8use linked_hash_map::LinkedHashMap;
9use serde::{Deserialize, Serialize};
10
11use crate::common::get_key_range_for_prefix;
12
13#[derive(Clone, Debug, Serialize, Deserialize)]
15pub struct StorageCacheConfig {
16 pub max_cache_size: usize,
18 pub max_value_entry_size: usize,
20 pub max_find_keys_entry_size: usize,
22 pub max_find_key_values_entry_size: usize,
24 pub max_cache_entries: usize,
26 pub max_cache_value_size: usize,
28 pub max_cache_find_keys_size: usize,
30 pub max_cache_find_key_values_size: usize,
32}
33
34#[derive(Eq, Hash, PartialEq, Debug)]
35enum CacheKey {
36 Value(Vec<u8>),
37 FindKeys(Vec<u8>),
38 FindKeyValues(Vec<u8>),
39}
40
41enum ValueEntry {
42 DoesNotExist,
43 Exists,
44 Value(Vec<u8>),
45}
46
47impl ValueEntry {
48 fn size(&self) -> usize {
49 match self {
50 ValueEntry::Value(vec) => vec.len(),
51 _ => 0,
52 }
53 }
54}
55
56struct FindKeysEntry(BTreeSet<Vec<u8>>);
57
58impl FindKeysEntry {
59 fn size(&self) -> usize {
60 self.0.iter().map(Vec::len).sum()
61 }
62
63 fn get_keys_by_prefix(&self, key_prefix: Vec<u8>) -> Vec<Vec<u8>> {
64 let prefix_len = key_prefix.len();
65 self.0
66 .range(get_key_range_for_prefix(key_prefix))
67 .map(|key| key[prefix_len..].to_vec())
68 .collect()
69 }
70
71 fn contains_key(&self, key: &[u8]) -> bool {
72 self.0.contains(key)
73 }
74
75 fn update_entry(&mut self, key: &[u8], is_some: bool) {
76 if is_some {
77 self.0.insert(key.to_vec());
78 } else {
79 self.0.remove(key);
80 }
81 }
82
83 fn delete_prefix(&mut self, key_prefix: &[u8]) {
84 let keys = self
85 .0
86 .range(get_key_range_for_prefix(key_prefix.to_vec()))
87 .cloned()
88 .collect::<Vec<_>>();
89 for key in keys {
90 self.0.remove(&key);
91 }
92 }
93}
94
95struct FindKeyValuesEntry(BTreeMap<Vec<u8>, Vec<u8>>);
96
97impl FindKeyValuesEntry {
98 fn size(&self) -> usize {
99 self.0
100 .iter()
101 .map(|(key, value)| key.len() + value.len())
102 .sum()
103 }
104
105 fn get_keys_by_prefix(&self, key_prefix: Vec<u8>) -> Vec<Vec<u8>> {
106 let prefix_len = key_prefix.len();
107 self.0
108 .range(get_key_range_for_prefix(key_prefix))
109 .map(|(key, _)| key[prefix_len..].to_vec())
110 .collect()
111 }
112
113 fn get_find_key_values(&self, key_prefix: &[u8]) -> Vec<(Vec<u8>, Vec<u8>)> {
114 let key_prefix = key_prefix.to_vec();
115 let prefix_len = key_prefix.len();
116 self.0
117 .range(get_key_range_for_prefix(key_prefix))
118 .map(|(key, value)| (key[prefix_len..].to_vec(), value.to_vec()))
119 .collect()
120 }
121
122 fn contains_key(&self, key: &[u8]) -> bool {
123 self.0.contains_key(key)
124 }
125
126 fn get_read_value(&self, key: &[u8]) -> Option<Vec<u8>> {
127 self.0.get(key).cloned()
128 }
129
130 fn update_entry(&mut self, key: &[u8], new_value: Option<Vec<u8>>) {
131 match new_value {
132 None => {
133 self.0.remove(key);
134 }
135 Some(new_value) => {
136 self.0.insert(key.to_vec(), new_value);
137 }
138 }
139 }
140
141 fn delete_prefix(&mut self, key_prefix: &[u8]) {
142 let keys = self
143 .0
144 .range(get_key_range_for_prefix(key_prefix.to_vec()))
145 .map(|(key, _)| key.clone())
146 .collect::<Vec<_>>();
147 for key in keys {
148 self.0.remove(&key);
149 }
150 }
151}
152
153pub(crate) struct LruPrefixCache {
158 value_map: BTreeMap<Vec<u8>, ValueEntry>,
159 find_keys_map: BTreeMap<Vec<u8>, FindKeysEntry>,
160 find_key_values_map: BTreeMap<Vec<u8>, FindKeyValuesEntry>,
161 queue: LinkedHashMap<CacheKey, usize, RandomState>,
162 config: StorageCacheConfig,
163 total_size: usize,
164 total_value_size: usize,
165 total_find_keys_size: usize,
166 total_find_key_values_size: usize,
167 has_exclusive_access: bool,
169}
170
171impl LruPrefixCache {
172 pub(crate) fn new(config: StorageCacheConfig, has_exclusive_access: bool) -> Self {
174 Self {
175 value_map: BTreeMap::new(),
176 find_keys_map: BTreeMap::new(),
177 find_key_values_map: BTreeMap::new(),
178 queue: LinkedHashMap::new(),
179 config,
180 total_size: 0,
181 total_value_size: 0,
182 total_find_keys_size: 0,
183 total_find_key_values_size: 0,
184 has_exclusive_access,
185 }
186 }
187
188 pub(crate) fn has_exclusive_access(&self) -> bool {
190 self.has_exclusive_access
191 }
192
193 fn move_cache_key_on_top(&mut self, cache_key: CacheKey) {
195 let size = self
196 .queue
197 .remove(&cache_key)
198 .expect("cache_key should be present");
199 self.queue.insert(cache_key, size);
200 }
201
202 fn update_sizes(&mut self, cache_key: &CacheKey, old_size: usize, new_size: usize) {
204 use std::cmp::Ordering;
205 match new_size.cmp(&old_size) {
206 Ordering::Greater => {
207 let increase_size = new_size - old_size;
208 self.total_size += increase_size;
209 match cache_key {
210 CacheKey::Value(_) => {
211 self.total_value_size += increase_size;
212 }
213 CacheKey::FindKeys(_) => {
214 self.total_find_keys_size += increase_size;
215 }
216 CacheKey::FindKeyValues(_) => {
217 self.total_find_key_values_size += increase_size;
218 }
219 }
220 }
221 Ordering::Less => {
222 let decrease_size = old_size - new_size;
223 self.total_size -= decrease_size;
224 match cache_key {
225 CacheKey::Value(_) => {
226 self.total_value_size -= decrease_size;
227 }
228 CacheKey::FindKeys(_) => {
229 self.total_find_keys_size -= decrease_size;
230 }
231 CacheKey::FindKeyValues(_) => {
232 self.total_find_key_values_size -= decrease_size;
233 }
234 }
235 }
236 Ordering::Equal => {
237 }
239 }
240 }
241
242 fn increase_sizes(&mut self, cache_key: &CacheKey, size: usize) {
244 self.update_sizes(cache_key, 0, size);
245 }
246
247 fn decrease_sizes(&mut self, cache_key: &CacheKey, size: usize) {
249 self.update_sizes(cache_key, size, 0);
250 }
251
252 fn remove_cache_key_from_map(&mut self, cache_key: &CacheKey) {
254 match cache_key {
255 CacheKey::Value(key) => {
256 assert!(self.value_map.remove(key).is_some());
257 }
258 CacheKey::FindKeys(key) => {
259 assert!(self.find_keys_map.remove(key).is_some());
260 }
261 CacheKey::FindKeyValues(key) => {
262 assert!(self.find_key_values_map.remove(key).is_some());
263 }
264 }
265 }
266
267 fn remove_cache_key(&mut self, cache_key: &CacheKey) {
269 let size = self
270 .queue
271 .remove(cache_key)
272 .expect("cache_key should be present");
273 self.decrease_sizes(cache_key, size);
274 }
275
276 fn remove_cache_key_if_exists(&mut self, cache_key: &CacheKey) {
278 let size = self.queue.remove(cache_key);
279 if let Some(size) = size {
280 self.decrease_sizes(cache_key, size);
281 self.remove_cache_key_from_map(cache_key);
282 }
283 }
284
285 fn update_cache_key_sizes(&mut self, cache_key: &CacheKey, new_size: usize) {
287 let size = self
288 .queue
289 .get_mut(cache_key)
290 .expect("cache_key should be present");
291 let old_size = *size;
292 *size = new_size;
293 self.update_sizes(cache_key, old_size, new_size);
294 }
295
296 fn insert_cache_key(&mut self, cache_key: CacheKey, size: usize) {
298 self.increase_sizes(&cache_key, size);
299 assert!(self.queue.insert(cache_key, size).is_none());
300 }
301
302 fn get_existing_find_keys_entry(&self, key: &[u8]) -> Option<(&Vec<u8>, &FindKeysEntry)> {
336 match self.find_keys_map.range(..=key.to_vec()).next_back() {
337 None => None,
338 Some((stored_key, value)) => {
339 if key.starts_with(stored_key) {
340 Some((stored_key, value))
341 } else {
342 None
343 }
344 }
345 }
346 }
347
348 fn get_existing_keys_entry_mut(
350 &mut self,
351 key: &[u8],
352 ) -> Option<(&Vec<u8>, &mut FindKeysEntry)> {
353 match self.find_keys_map.range_mut(..=key.to_vec()).next_back() {
354 None => None,
355 Some((stored_key, value)) => {
356 if key.starts_with(stored_key) {
357 Some((stored_key, value))
358 } else {
359 None
360 }
361 }
362 }
363 }
364
365 fn get_existing_find_key_values_entry(
368 &self,
369 key: &[u8],
370 ) -> Option<(&Vec<u8>, &FindKeyValuesEntry)> {
371 match self.find_key_values_map.range(..=key.to_vec()).next_back() {
372 None => None,
373 Some((stored_key, value)) => {
374 if key.starts_with(stored_key) {
375 Some((stored_key, value))
376 } else {
377 None
378 }
379 }
380 }
381 }
382
383 fn get_existing_find_key_values_entry_mut(
385 &mut self,
386 key: &[u8],
387 ) -> Option<(&Vec<u8>, &mut FindKeyValuesEntry)> {
388 match self
389 .find_key_values_map
390 .range_mut(..=key.to_vec())
391 .next_back()
392 {
393 None => None,
394 Some((stored_key, value)) => {
395 if key.starts_with(stored_key) {
396 Some((stored_key, value))
397 } else {
398 None
399 }
400 }
401 }
402 }
403
404 fn trim_value_cache(&mut self) {
406 let mut keys = Vec::new();
407 let mut control_size = self.total_value_size;
408 let mut iter = self.queue.iter();
409 loop {
410 let value = iter.next();
411 let Some((cache_key, size)) = value else {
412 break;
413 };
414 if control_size < self.config.max_cache_value_size {
415 break;
416 }
417 if let CacheKey::Value(key) = cache_key {
418 control_size -= size;
419 keys.push(key.to_vec());
420 }
421 }
422 for key in keys {
423 assert!(self.value_map.remove(&key).is_some());
424 let cache_key = CacheKey::Value(key);
425 self.remove_cache_key(&cache_key);
426 }
427 }
428
429 fn trim_find_keys_cache(&mut self) {
431 let mut prefixes = Vec::new();
432 let mut control_size = self.total_find_keys_size;
433 let mut iter = self.queue.iter();
434 loop {
435 let value = iter.next();
436 let Some((cache_key, size)) = value else {
437 break;
438 };
439 if control_size < self.config.max_cache_find_keys_size {
440 break;
441 }
442 if let CacheKey::FindKeys(prefix) = cache_key {
443 control_size -= size;
444 prefixes.push(prefix.to_vec());
445 }
446 }
447 for prefix in prefixes {
448 assert!(self.find_keys_map.remove(&prefix).is_some());
449 let cache_key = CacheKey::FindKeys(prefix);
450 self.remove_cache_key(&cache_key);
451 }
452 }
453
454 fn trim_find_key_values_cache(&mut self) {
456 let mut prefixes = Vec::new();
457 let mut control_size = self.total_find_key_values_size;
458 let mut iter = self.queue.iter();
459 loop {
460 let value = iter.next();
461 let Some((cache_key, size)) = value else {
462 break;
463 };
464 if control_size < self.config.max_cache_find_key_values_size {
465 break;
466 }
467 if let CacheKey::FindKeyValues(prefix) = cache_key {
468 control_size -= size;
469 prefixes.push(prefix.to_vec());
470 }
471 }
472 for prefix in prefixes {
473 assert!(self.find_key_values_map.remove(&prefix).is_some());
474 let cache_key = CacheKey::FindKeyValues(prefix);
475 self.remove_cache_key(&cache_key);
476 }
477 }
478
479 fn trim_cache(&mut self) {
481 while self.total_size >= self.config.max_cache_size
482 || self.queue.len() >= self.config.max_cache_entries
483 {
484 let Some((cache_key, size)) = self.queue.pop_front() else {
485 break;
486 };
487 self.decrease_sizes(&cache_key, size);
488 self.remove_cache_key_from_map(&cache_key);
489 }
490 }
491
492 fn insert_value(&mut self, key: &[u8], cache_entry: ValueEntry) {
494 if self.config.max_value_entry_size == 0 {
495 return;
497 }
498 let size = key.len() + cache_entry.size();
499 if (matches!(cache_entry, ValueEntry::DoesNotExist) && !self.has_exclusive_access)
500 || size > self.config.max_value_entry_size
501 {
502 if self.value_map.remove(key).is_some() {
503 let cache_key = CacheKey::Value(key.to_vec());
504 self.remove_cache_key(&cache_key);
505 };
506 return;
507 }
508 match self.value_map.entry(key.to_vec()) {
509 Entry::Occupied(mut entry) => {
510 entry.insert(cache_entry);
511 let cache_key = CacheKey::Value(key.to_vec());
513 self.remove_cache_key(&cache_key);
514 self.insert_cache_key(cache_key, size);
515 }
516 Entry::Vacant(entry) => {
517 entry.insert(cache_entry);
518 let cache_key = CacheKey::Value(key.to_vec());
519 self.insert_cache_key(cache_key, size);
520 }
521 }
522 self.trim_value_cache();
523 self.trim_cache();
524 }
525
526 pub(crate) fn put_key_value(&mut self, key: &[u8], value: &[u8]) {
528 if self.has_exclusive_access {
529 let lower_bound = self.get_existing_keys_entry_mut(key);
530 if let Some((lower_bound, cache_entry)) = lower_bound {
531 let reduced_key = &key[lower_bound.len()..];
532 cache_entry.update_entry(reduced_key, true);
533 let cache_key = CacheKey::FindKeys(lower_bound.to_vec());
534 let new_size = lower_bound.len() + cache_entry.size();
535 self.update_cache_key_sizes(&cache_key, new_size);
536 }
537 match self.get_existing_find_key_values_entry_mut(key) {
538 Some((lower_bound, cache_entry)) => {
539 let reduced_key = &key[lower_bound.len()..];
540 cache_entry.update_entry(reduced_key, Some(value.to_vec()));
541 let cache_key = CacheKey::FindKeyValues(lower_bound.to_vec());
542 let new_size = lower_bound.len() + cache_entry.size();
543 self.update_cache_key_sizes(&cache_key, new_size);
544 let cache_key = CacheKey::Value(key.to_vec());
545 self.remove_cache_key_if_exists(&cache_key);
546 }
547 None => {
548 let cache_entry = ValueEntry::Value(value.to_vec());
549 self.insert_value(key, cache_entry);
550 }
551 }
552 } else {
553 let cache_entry = ValueEntry::Value(value.to_vec());
554 self.insert_value(key, cache_entry);
555 }
556 }
557
558 pub(crate) fn delete_key(&mut self, key: &[u8]) {
560 if self.has_exclusive_access {
561 let lower_bound = self.get_existing_keys_entry_mut(key);
562 let mut matching = false; if let Some((lower_bound, cache_entry)) = lower_bound {
564 let reduced_key = &key[lower_bound.len()..];
565 cache_entry.update_entry(reduced_key, false);
566 let cache_key = CacheKey::FindKeys(lower_bound.to_vec());
567 let new_size = lower_bound.len() + cache_entry.size();
568 self.update_cache_key_sizes(&cache_key, new_size);
569 matching = true;
570 }
571 let lower_bound = self.get_existing_find_key_values_entry_mut(key);
572 if let Some((lower_bound, cache_entry)) = lower_bound {
573 let reduced_key = &key[lower_bound.len()..];
574 cache_entry.update_entry(reduced_key, None);
575 let cache_key = CacheKey::FindKeyValues(lower_bound.to_vec());
576 let new_size = lower_bound.len() + cache_entry.size();
577 self.update_cache_key_sizes(&cache_key, new_size);
578 matching = true;
579 }
580 if !matching {
581 let cache_entry = ValueEntry::DoesNotExist;
582 self.insert_value(key, cache_entry);
583 } else {
584 let cache_key = CacheKey::Value(key.to_vec());
585 self.remove_cache_key_if_exists(&cache_key);
586 }
587 } else {
588 let cache_key = CacheKey::Value(key.to_vec());
589 self.remove_cache_key_if_exists(&cache_key);
590 }
591 }
592
593 pub(crate) fn insert_read_value(&mut self, key: &[u8], value: &Option<Vec<u8>>) {
595 let cache_entry = match value {
598 None => ValueEntry::DoesNotExist,
599 Some(vec) => ValueEntry::Value(vec.to_vec()),
600 };
601 self.insert_value(key, cache_entry)
602 }
603
604 pub(crate) fn insert_contains_key(&mut self, key: &[u8], result: bool) {
606 let cache_entry = if result {
609 ValueEntry::Exists
610 } else {
611 ValueEntry::DoesNotExist
612 };
613 self.insert_value(key, cache_entry)
614 }
615
616 pub(crate) fn insert_find_keys(&mut self, key_prefix: Vec<u8>, keys: &[Vec<u8>]) {
618 if self.config.max_find_keys_entry_size == 0 {
619 return;
621 }
622 let size = key_prefix.len() + keys.iter().map(Vec::len).sum::<usize>();
623 if size > self.config.max_find_keys_entry_size {
624 return;
626 }
627 let find_entry = FindKeysEntry(keys.iter().cloned().collect());
628 let keys = self
630 .find_keys_map
631 .range(get_key_range_for_prefix(key_prefix.clone()))
632 .map(|(x, _)| x.clone())
633 .collect::<Vec<_>>();
634 for key in keys {
635 assert!(self.find_keys_map.remove(&key).is_some());
636 let cache_key = CacheKey::FindKeys(key);
637 self.remove_cache_key(&cache_key);
638 }
639 let keys = self
642 .value_map
643 .range(get_key_range_for_prefix(key_prefix.clone()))
644 .filter_map(|(key, value)| match value {
645 ValueEntry::DoesNotExist => Some(key.to_vec()),
646 ValueEntry::Exists => Some(key.to_vec()),
647 ValueEntry::Value(_) => None,
648 })
649 .collect::<Vec<_>>();
650 for key in keys {
651 assert!(self.value_map.remove(&key).is_some());
652 let cache_key = CacheKey::Value(key);
653 self.remove_cache_key(&cache_key);
654 }
655 let cache_key = CacheKey::FindKeys(key_prefix.clone());
656 assert!(self.find_keys_map.insert(key_prefix, find_entry).is_none());
658 self.insert_cache_key(cache_key, size);
659 self.trim_find_keys_cache();
660 self.trim_cache();
661 }
662
663 pub(crate) fn insert_find_key_values(
665 &mut self,
666 key_prefix: Vec<u8>,
667 key_values: &[(Vec<u8>, Vec<u8>)],
668 ) {
669 if self.config.max_find_key_values_entry_size == 0 {
670 return;
672 }
673 let size = key_prefix.len()
674 + key_values
675 .iter()
676 .map(|(k, v)| k.len() + v.len())
677 .sum::<usize>();
678 if size > self.config.max_find_key_values_entry_size {
679 return;
681 }
682 let find_entry = FindKeyValuesEntry(
683 key_values
684 .iter()
685 .map(|(k, v)| (k.to_vec(), v.to_vec()))
686 .collect(),
687 );
688 let prefixes = self
690 .find_keys_map
691 .range(get_key_range_for_prefix(key_prefix.clone()))
692 .map(|(x, _)| x.clone())
693 .collect::<Vec<_>>();
694 for prefix in prefixes {
695 assert!(self.find_keys_map.remove(&prefix).is_some());
696 let cache_key = CacheKey::FindKeys(prefix);
697 self.remove_cache_key(&cache_key);
698 }
699 let prefixes = self
701 .find_key_values_map
702 .range(get_key_range_for_prefix(key_prefix.clone()))
703 .map(|(x, _)| x.clone())
704 .collect::<Vec<_>>();
705 for prefix in prefixes {
706 assert!(self.find_key_values_map.remove(&prefix).is_some());
707 let cache_key = CacheKey::FindKeyValues(prefix);
708 self.remove_cache_key(&cache_key);
709 }
710 let keys = self
712 .value_map
713 .range(get_key_range_for_prefix(key_prefix.clone()))
714 .map(|(x, _)| x.clone())
715 .collect::<Vec<_>>();
716 for key in keys {
717 assert!(self.value_map.remove(&key).is_some());
718 let cache_key = CacheKey::Value(key);
719 self.remove_cache_key(&cache_key);
720 }
721 let cache_key = CacheKey::FindKeyValues(key_prefix.clone());
722 assert!(self
724 .find_key_values_map
725 .insert(key_prefix, find_entry)
726 .is_none());
727 self.insert_cache_key(cache_key, size);
728 self.trim_find_key_values_cache();
729 self.trim_cache();
730 }
731
732 pub(crate) fn delete_prefix(&mut self, key_prefix: &[u8]) {
735 let mut keys = Vec::new();
741 for (key, _) in self
742 .value_map
743 .range(get_key_range_for_prefix(key_prefix.to_vec()))
744 {
745 keys.push(key.to_vec());
746 }
747 for key in keys {
748 assert!(self.value_map.remove(&key).is_some());
749 let cache_key = CacheKey::Value(key);
750 self.remove_cache_key(&cache_key);
751 }
752 if self.has_exclusive_access {
753 let mut prefixes = Vec::new();
755 for (prefix, _) in self
756 .find_keys_map
757 .range(get_key_range_for_prefix(key_prefix.to_vec()))
758 {
759 prefixes.push(prefix.to_vec());
760 }
761 for prefix in prefixes {
762 assert!(self.find_keys_map.remove(&prefix).is_some());
763 let cache_key = CacheKey::FindKeys(prefix);
764 self.remove_cache_key(&cache_key);
765 }
766 let mut prefixes = Vec::new();
768 for (prefix, _) in self
769 .find_key_values_map
770 .range(get_key_range_for_prefix(key_prefix.to_vec()))
771 {
772 prefixes.push(prefix.to_vec());
773 }
774 for prefix in prefixes {
775 assert!(self.find_key_values_map.remove(&prefix).is_some());
776 let cache_key = CacheKey::FindKeyValues(prefix);
777 self.remove_cache_key(&cache_key);
778 }
779 let lower_bound = self.get_existing_keys_entry_mut(key_prefix);
781 let result = if let Some((lower_bound, find_entry)) = lower_bound {
782 let key_prefix_red = &key_prefix[lower_bound.len()..];
784 find_entry.delete_prefix(key_prefix_red);
785 let new_cache_size = find_entry.size() + lower_bound.len();
786 Some((new_cache_size, lower_bound.clone()))
787 } else {
788 None
789 };
790 if let Some((new_cache_size, lower_bound)) = result {
791 let cache_key = CacheKey::FindKeys(lower_bound.clone());
793 self.update_cache_key_sizes(&cache_key, new_cache_size);
794 }
795 let lower_bound = self.get_existing_find_key_values_entry_mut(key_prefix);
797 let result = if let Some((lower_bound, find_entry)) = lower_bound {
798 let key_prefix_red = &key_prefix[lower_bound.len()..];
800 find_entry.delete_prefix(key_prefix_red);
801 let new_cache_size = find_entry.size() + lower_bound.len();
802 Some((new_cache_size, lower_bound.clone()))
803 } else {
804 None
805 };
806 if let Some((new_cache_size, lower_bound)) = result {
807 let cache_key = CacheKey::FindKeyValues(lower_bound.clone());
809 self.update_cache_key_sizes(&cache_key, new_cache_size);
810 } else {
811 let size = key_prefix.len();
814 let cache_key = CacheKey::FindKeyValues(key_prefix.to_vec());
815 let find_key_values_entry = FindKeyValuesEntry(BTreeMap::new());
816 self.find_key_values_map
817 .insert(key_prefix.to_vec(), find_key_values_entry);
818 self.insert_cache_key(cache_key, size);
819 }
820 }
821 }
822
823 pub(crate) fn query_read_value(&mut self, key: &[u8]) -> Option<Option<Vec<u8>>> {
827 let result = match self.value_map.get(key) {
829 None => None,
830 Some(entry) => match entry {
831 ValueEntry::DoesNotExist => Some(None),
832 ValueEntry::Exists => None,
833 ValueEntry::Value(vec) => Some(Some(vec.clone())),
834 },
835 };
836 if result.is_some() {
837 let cache_key = CacheKey::Value(key.to_vec());
838 self.move_cache_key_on_top(cache_key);
839 return result;
840 }
841 if self.has_exclusive_access {
842 let lower_bound = self.get_existing_find_key_values_entry(key);
844 let (lower_bound, result) = if let Some((lower_bound, find_entry)) = lower_bound {
845 let reduced_key = &key[lower_bound.len()..];
846 (lower_bound, find_entry.get_read_value(reduced_key))
847 } else {
848 return None;
849 };
850 let cache_key = CacheKey::FindKeyValues(lower_bound.clone());
851 self.move_cache_key_on_top(cache_key);
852 Some(result)
853 } else {
854 None
855 }
856 }
857
858 pub(crate) fn query_contains_key(&mut self, key: &[u8]) -> Option<bool> {
861 let result = self
863 .value_map
864 .get(key)
865 .map(|entry| !matches!(entry, ValueEntry::DoesNotExist));
866 if result.is_some() {
867 let cache_key = CacheKey::Value(key.to_vec());
868 self.move_cache_key_on_top(cache_key);
869 return result;
870 }
871 if self.has_exclusive_access {
872 let lower_bound = self.get_existing_find_keys_entry(key);
874 let result = if let Some((lower_bound, find_entry)) = lower_bound {
875 let reduced_key = &key[lower_bound.len()..];
876 Some((lower_bound, find_entry.contains_key(reduced_key)))
877 } else {
878 None
879 };
880 if let Some((lower_bound, result)) = result {
881 let cache_key = CacheKey::FindKeys(lower_bound.clone());
882 self.move_cache_key_on_top(cache_key);
883 return Some(result);
884 }
885 let lower_bound = self.get_existing_find_key_values_entry(key);
887 let (lower_bound, result) = if let Some((lower_bound, find_entry)) = lower_bound {
888 let reduced_key = &key[lower_bound.len()..];
889 (lower_bound, find_entry.contains_key(reduced_key))
890 } else {
891 return None;
892 };
893 let cache_key = CacheKey::FindKeyValues(lower_bound.clone());
894 self.move_cache_key_on_top(cache_key);
895 return Some(result);
896 }
897 result
898 }
899
900 pub(crate) fn query_find_keys(&mut self, key_prefix: &[u8]) -> Option<Vec<Vec<u8>>> {
902 let result = match self.get_existing_find_keys_entry(key_prefix) {
904 None => None,
905 Some((lower_bound, cache_entry)) => {
906 let key_prefix_red = key_prefix[lower_bound.len()..].to_vec();
907 Some((lower_bound, cache_entry.get_keys_by_prefix(key_prefix_red)))
908 }
909 };
910 if let Some((lower_bound, keys)) = result {
911 let cache_key = CacheKey::FindKeys(lower_bound.clone());
912 self.move_cache_key_on_top(cache_key);
913 return Some(keys);
914 }
915 let (lower_bound, result) = match self.get_existing_find_key_values_entry(key_prefix) {
917 None => {
918 return None;
919 }
920 Some((lower_bound, cache_entry)) => {
921 let key_prefix_red = key_prefix[lower_bound.len()..].to_vec();
922 (lower_bound, cache_entry.get_keys_by_prefix(key_prefix_red))
923 }
924 };
925 let cache_key = CacheKey::FindKeyValues(lower_bound.clone());
926 self.move_cache_key_on_top(cache_key);
927 Some(result)
928 }
929
930 pub(crate) fn query_find_key_values(
932 &mut self,
933 key_prefix: &[u8],
934 ) -> Option<Vec<(Vec<u8>, Vec<u8>)>> {
935 let (lower_bound, result) = match self.get_existing_find_key_values_entry(key_prefix) {
936 None => {
937 return None;
938 }
939 Some((lower_bound, cache_entry)) => {
940 let key_prefix_red = &key_prefix[lower_bound.len()..];
941 (lower_bound, cache_entry.get_find_key_values(key_prefix_red))
942 }
943 };
944 let cache_key = CacheKey::FindKeyValues(lower_bound.to_vec());
945 self.move_cache_key_on_top(cache_key);
946 Some(result)
947 }
948}
949
950#[cfg(test)]
951mod tests {
952 #![allow(clippy::cast_possible_truncation)]
953
954 use std::collections::BTreeSet;
955
956 use rand::Rng;
957
958 use super::*;
959
960 fn check_prefix_free(set: BTreeSet<Vec<u8>>) {
961 let keys = set.into_iter().collect::<Vec<_>>();
962 let num_keys = keys.len();
963 println!("keys={keys:?}");
964 for i in 0..num_keys {
965 for j in 0..num_keys {
966 if i != j {
967 let key1 = keys[i].clone();
968 let key2 = keys[j].clone();
969 println!("i={i} j={j} key1={key1:?} key2={key2:?}");
970 assert!(!key1.starts_with(&key2));
971 }
972 }
973 }
974 }
975
976 fn check_intersection(keys: Vec<Vec<u8>>, prefixes: &BTreeSet<Vec<u8>>) {
977 for key in keys {
978 for prefix in prefixes {
979 assert!(!key.starts_with(prefix), "key matches a prefix");
980 }
981 }
982 }
983
984 impl LruPrefixCache {
985 fn check_coherence(&self) {
986 let value_map_set = self
987 .value_map
988 .keys()
989 .cloned()
990 .collect::<BTreeSet<Vec<u8>>>();
991 let find_keys_map_set = self
992 .find_keys_map
993 .keys()
994 .cloned()
995 .collect::<BTreeSet<Vec<u8>>>();
996 let find_key_values_map_set = self
997 .find_key_values_map
998 .keys()
999 .cloned()
1000 .collect::<BTreeSet<Vec<u8>>>();
1001 check_prefix_free(find_keys_map_set.clone());
1003 check_prefix_free(find_key_values_map_set.clone());
1004 let mut value_queue_set = BTreeSet::new();
1007 let mut find_keys_queue_set = BTreeSet::new();
1008 let mut find_key_values_queue_set = BTreeSet::new();
1009 let mut total_size = 0;
1010 let mut total_value_size = 0;
1011 let mut total_find_keys_size = 0;
1012 let mut total_find_key_values_size = 0;
1013 for (cache_key, size) in &self.queue {
1014 let queue_size = *size;
1015 match cache_key {
1016 CacheKey::Value(key) => {
1017 let value = self.value_map.get(key).unwrap();
1018 let map_size = key.len() + value.size();
1019 assert_eq!(map_size, queue_size, "Incoherence in value size");
1020 value_queue_set.insert(key.clone());
1021 total_value_size += queue_size;
1022 }
1023 CacheKey::FindKeys(key) => {
1024 let value = self.find_keys_map.get(key).unwrap();
1025 let map_size = key.len() + value.size();
1026 assert_eq!(map_size, queue_size, "Incoherence in find-keys size");
1027 find_keys_queue_set.insert(key.clone());
1028 total_find_keys_size += queue_size;
1029 }
1030 CacheKey::FindKeyValues(key) => {
1031 let value = self.find_key_values_map.get(key).unwrap();
1032 let map_size = key.len() + value.size();
1033 assert_eq!(map_size, queue_size, "Incoherence in find-keys size");
1034 find_key_values_queue_set.insert(key.clone());
1035 total_find_key_values_size += queue_size;
1036 }
1037 }
1038 total_size += queue_size;
1039 }
1040 let value_map_vect = self.value_map.keys().cloned().collect::<Vec<_>>();
1042 check_intersection(value_map_vect, &find_key_values_map_set);
1043 let value_existence_map_vect = self
1044 .value_map
1045 .iter()
1046 .filter_map(|(key, value)| match value {
1047 ValueEntry::DoesNotExist => Some(key.to_vec()),
1048 ValueEntry::Exists => Some(key.to_vec()),
1049 ValueEntry::Value(_) => None,
1050 })
1051 .collect::<Vec<_>>();
1052 check_intersection(value_existence_map_vect, &find_keys_map_set);
1053 assert_eq!(
1055 value_queue_set, value_map_set,
1056 "Incoherence in value_map keys"
1057 );
1058 assert_eq!(
1059 find_keys_queue_set, find_keys_map_set,
1060 "Incoherence in find_keys_map keys"
1061 );
1062 assert_eq!(
1063 find_key_values_queue_set, find_key_values_map_set,
1064 "Incoherence in find_key_values_map keys"
1065 );
1066 assert_eq!(total_size, self.total_size, "The total_size are incoherent");
1068 assert_eq!(
1069 total_value_size, self.total_value_size,
1070 "The total_value_size are incoherent"
1071 );
1072 assert_eq!(
1073 total_find_keys_size, self.total_find_keys_size,
1074 "The total_find_keys_size are incoherent"
1075 );
1076 assert_eq!(
1077 total_find_key_values_size, self.total_find_key_values_size,
1078 "The total_find_key_values_size are incoherent"
1079 );
1080 if self.config.max_cache_size > 0 {
1082 assert!(
1083 total_size < self.config.max_cache_size,
1084 "The total_size is too large"
1085 );
1086 } else {
1087 assert!(total_size == 0, "The total_size should be 0");
1088 }
1089 if self.config.max_cache_value_size > 0 {
1090 assert!(
1091 total_value_size < self.config.max_cache_value_size,
1092 "The total_value_size is too large"
1093 );
1094 } else {
1095 assert!(total_value_size == 0, "The total_value_size should be 0");
1096 }
1097 if self.config.max_cache_find_keys_size > 0 {
1098 assert!(
1099 total_find_keys_size < self.config.max_cache_find_keys_size,
1100 "The total_value_size is too large"
1101 );
1102 } else {
1103 assert!(
1104 total_find_keys_size == 0,
1105 "The total_find_keys_size should be 0"
1106 );
1107 }
1108 if self.config.max_cache_find_key_values_size > 0 {
1109 assert!(
1110 total_find_key_values_size < self.config.max_cache_find_key_values_size,
1111 "The total_find_key_values_size is too large"
1112 );
1113 } else {
1114 assert!(
1115 total_find_key_values_size == 0,
1116 "The total_find_key_values_size should be 0"
1117 );
1118 }
1119 }
1120 }
1121
1122 fn create_test_cache(has_exclusive_access: bool) -> LruPrefixCache {
1123 let config = StorageCacheConfig {
1124 max_cache_size: 1000,
1125 max_value_entry_size: 50,
1126 max_find_keys_entry_size: 100,
1127 max_find_key_values_entry_size: 200,
1128 max_cache_entries: 10,
1129 max_cache_value_size: 500,
1130 max_cache_find_keys_size: 500,
1131 max_cache_find_key_values_size: 500,
1132 };
1133 LruPrefixCache::new(config, has_exclusive_access)
1134 }
1135
1136 #[test]
1137 fn test_new_cache_creation() {
1138 let cache = create_test_cache(true);
1139 assert_eq!(cache.total_size, 0);
1140 assert_eq!(cache.total_value_size, 0);
1141 assert_eq!(cache.total_find_keys_size, 0);
1142 assert_eq!(cache.total_find_key_values_size, 0);
1143 assert!(cache.has_exclusive_access);
1144 assert!(cache.value_map.is_empty());
1145 assert!(cache.find_keys_map.is_empty());
1146 assert!(cache.find_key_values_map.is_empty());
1147 assert!(cache.queue.is_empty());
1148 }
1149
1150 #[test]
1151 fn test_insert_and_query_read_value() {
1152 let mut cache = create_test_cache(true);
1153 let key = vec![1, 2, 3];
1154 let value = vec![4, 5, 6];
1155
1156 cache.insert_read_value(&key, &Some(value.clone()));
1158 cache.check_coherence();
1159
1160 let result = cache.query_read_value(&key);
1162 assert_eq!(result, Some(Some(value)));
1163
1164 let result = cache.query_read_value(&[9, 9, 9]);
1166 assert_eq!(result, None);
1167 }
1168
1169 #[test]
1170 fn test_insert_and_query_contains_key() {
1171 let mut cache = create_test_cache(true);
1172 let key = vec![1, 2, 3];
1173
1174 cache.insert_contains_key(&key, true);
1176 cache.check_coherence();
1177
1178 let result = cache.query_contains_key(&key);
1180 assert_eq!(result, Some(true));
1181
1182 let key2 = vec![4, 5, 6];
1184 cache.insert_contains_key(&key2, false);
1185
1186 let result = cache.query_contains_key(&key2);
1187 assert_eq!(result, Some(false));
1188 }
1189
1190 #[test]
1191 fn test_insert_and_query_find_keys() {
1192 let mut cache = create_test_cache(true);
1193 let prefix = vec![1, 2];
1194 let keys = vec![vec![3], vec![4], vec![5]];
1195
1196 cache.insert_find_keys(prefix.clone(), &keys);
1198 cache.check_coherence();
1199
1200 let result = cache.query_find_keys(&prefix);
1202 assert_eq!(result, Some(keys.clone()));
1203
1204 let longer_prefix = vec![1, 2, 3];
1206 let result = cache.query_find_keys(&longer_prefix);
1207 assert_eq!(result, Some(vec![vec![]])); let result = cache.query_find_keys(&[9, 9]);
1211 assert_eq!(result, None);
1212 }
1213
1214 #[test]
1215 fn test_insert_and_query_find_key_values() {
1216 let mut cache = create_test_cache(true);
1217 let prefix = vec![1, 2];
1218 let key_values = vec![(vec![3], vec![10]), (vec![4], vec![20])];
1219
1220 cache.insert_find_key_values(prefix.clone(), &key_values);
1222 cache.check_coherence();
1223
1224 let result = cache.query_find_key_values(&prefix);
1226 assert_eq!(result, Some(key_values.clone()));
1227
1228 let result = cache.query_find_key_values(&[9, 9]);
1230 assert_eq!(result, None);
1231 }
1232
1233 #[test]
1234 fn test_lru_eviction_by_cache_size() {
1235 let mut cache = create_test_cache(true);
1236
1237 for i in 0..20 {
1239 let key = vec![i];
1240 let value = vec![0; 100]; cache.insert_read_value(&key, &Some(value));
1242 cache.check_coherence();
1243 }
1244
1245 assert!(cache.total_size <= cache.config.max_cache_size);
1247 assert!(cache.queue.len() <= cache.config.max_cache_entries);
1248 }
1249
1250 #[test]
1251 fn test_lru_eviction_by_entry_count() {
1252 let mut cache = create_test_cache(true);
1253
1254 for i in 0..15 {
1256 let key = vec![i];
1257 let value = vec![i]; cache.insert_read_value(&key, &Some(value));
1259 cache.check_coherence();
1260 }
1261
1262 assert!(cache.queue.len() <= cache.config.max_cache_entries);
1264 }
1265
1266 #[test]
1267 fn test_cache_entry_promotion() {
1268 let mut cache = create_test_cache(true);
1269 let key1 = vec![1];
1270 let key2 = vec![2];
1271 let key3 = vec![3];
1272 let value = vec![42];
1273
1274 cache.insert_read_value(&key1, &Some(value.clone()));
1276 cache.check_coherence();
1277 cache.insert_read_value(&key2, &Some(value.clone()));
1278 cache.check_coherence();
1279
1280 assert_eq!(Some(Some(value)), cache.query_read_value(&key1));
1282
1283 assert_eq!(None, cache.query_read_value(&key3));
1285
1286 let queue_keys = cache.queue.keys().collect::<Vec<_>>();
1288 assert_eq!(queue_keys[queue_keys.len() - 1], &CacheKey::Value(key1));
1289 }
1290
1291 #[test]
1292 fn test_update_find_entry_mut() {
1293 let mut cache = create_test_cache(true);
1294 let prefix = vec![1];
1295 let key = vec![1, 2];
1296 let original_keys = vec![vec![2], vec![3]];
1297
1298 cache.insert_find_keys(prefix.clone(), &original_keys);
1300 cache.check_coherence();
1301
1302 cache.put_key_value(&key, &[42]);
1304 cache.check_coherence();
1305
1306 let result = cache.query_find_keys(&prefix);
1308 assert!(result.is_some());
1309 let keys = result.unwrap();
1310 assert!(keys.contains(&vec![2]));
1311 }
1312
1313 #[test]
1314 fn test_delete_prefix_with_exclusive_access() {
1315 let mut cache = create_test_cache(true);
1316 let prefix = vec![1];
1317 let key1 = vec![1, 2];
1318 let key2 = vec![1, 3];
1319 let key3 = vec![2, 4]; let value = vec![42];
1321
1322 cache.insert_read_value(&key1, &Some(value.clone()));
1324 cache.check_coherence();
1325 cache.insert_read_value(&key2, &Some(value.clone()));
1326 cache.check_coherence();
1327 cache.insert_read_value(&key3, &Some(value.clone()));
1328 cache.check_coherence();
1329
1330 cache.delete_prefix(&prefix);
1332 cache.check_coherence();
1333
1334 let result1 = cache.query_read_value(&key1);
1336 assert_eq!(result1, Some(None));
1337
1338 let result2 = cache.query_read_value(&key2);
1339 assert_eq!(result2, Some(None));
1340
1341 let result3 = cache.query_read_value(&key3);
1343 assert_eq!(result3, Some(Some(value)));
1344 }
1345
1346 #[test]
1347 fn test_value_entry_size_limits() {
1348 let mut cache = create_test_cache(true);
1349 let key = vec![1];
1350 let large_value = vec![0; cache.config.max_value_entry_size + 1];
1351
1352 cache.insert_read_value(&key, &Some(large_value));
1355 cache.check_coherence();
1356
1357 let result = cache.query_read_value(&key);
1359 assert_eq!(result, None);
1360 }
1361
1362 #[test]
1363 fn test_findkeys_entry_size_limits() {
1364 let mut cache = create_test_cache(true);
1365 let key_prefix = vec![1];
1366 let mut keys = Vec::new();
1367 for i in 0..cache.config.max_find_keys_entry_size {
1368 keys.push(vec![i as u8]);
1369 }
1370 let size = keys.iter().map(Vec::len).sum::<usize>();
1371 assert_eq!(cache.config.max_find_keys_entry_size, size);
1372 cache.insert_find_keys(key_prefix.clone(), &keys);
1375 cache.check_coherence();
1376
1377 let result = cache.query_find_keys(&key_prefix);
1379 assert_eq!(result, None);
1380 }
1381
1382 #[test]
1383 fn test_findkeyvalues_entry_size_limits() {
1384 let mut cache = create_test_cache(true);
1385 let key_prefix = vec![1];
1386 let mut key_values = Vec::new();
1387 for i in 0..cache.config.max_find_key_values_entry_size / 2 {
1388 key_values.push((vec![i as u8], vec![i as u8]));
1389 }
1390 let size = key_values
1391 .iter()
1392 .map(|(k, v)| k.len() + v.len())
1393 .sum::<usize>();
1394 assert_eq!(cache.config.max_find_key_values_entry_size, size);
1395
1396 cache.insert_find_key_values(key_prefix.clone(), &key_values);
1398 cache.check_coherence();
1399
1400 let result = cache.query_find_key_values(&key_prefix);
1402 assert_eq!(result, None);
1403 }
1404
1405 #[test]
1406 fn test_does_not_exist_entry_without_exclusive_access() {
1407 let mut cache = create_test_cache(false);
1408 let key = vec![1];
1409
1410 cache.insert_read_value(&key, &None);
1412 cache.check_coherence();
1413
1414 let result = cache.query_read_value(&key);
1416 assert_eq!(result, None);
1417 }
1418
1419 #[test]
1420 fn test_find_keys_entry_operations() {
1421 let mut find_entry = FindKeysEntry(BTreeSet::new());
1422 let key1 = vec![1, 2];
1423 let key2 = vec![1, 3];
1424 let key3 = vec![1, 3, 4];
1425
1426 find_entry.update_entry(&key1, true);
1428 find_entry.update_entry(&key2, true);
1429
1430 assert!(find_entry.contains_key(&key1));
1432 assert!(find_entry.contains_key(&key2));
1433 assert!(!find_entry.contains_key(&key3));
1434 assert!(!find_entry.contains_key(&[9, 9]));
1435
1436 let keys = find_entry.get_keys_by_prefix(vec![1]);
1438 assert_eq!(keys.len(), 2);
1439 assert!(keys.contains(&vec![2]));
1440 assert!(keys.contains(&vec![3]));
1441
1442 find_entry.update_entry(&key1, false);
1444 assert!(!find_entry.contains_key(&key1));
1445 assert!(find_entry.contains_key(&key2));
1446 }
1447
1448 #[test]
1449 fn test_find_key_values_entry_operations() {
1450 let mut find_entry = FindKeyValuesEntry(BTreeMap::new());
1451 let key1 = vec![1, 2];
1452 let key2 = vec![1, 3];
1453 let value1 = vec![42];
1454 let value2 = vec![43];
1455
1456 find_entry.update_entry(&key1, Some(value1.clone()));
1458 find_entry.update_entry(&key2, Some(value2.clone()));
1459
1460 assert!(find_entry.contains_key(&key1));
1462 assert!(find_entry.contains_key(&key2));
1463
1464 assert_eq!(find_entry.get_read_value(&key1), Some(value1.clone()));
1466 assert_eq!(find_entry.get_read_value(&key2), Some(value2.clone()));
1467
1468 let key_values = find_entry.get_find_key_values(&[1]);
1470 assert_eq!(key_values.len(), 2);
1471 assert!(key_values.contains(&(vec![2], value1.clone())));
1472 assert!(key_values.contains(&(vec![3], value2.clone())));
1473
1474 find_entry.update_entry(&key1, None);
1476 assert!(!find_entry.contains_key(&key1));
1477 assert_eq!(find_entry.get_read_value(&key1), None);
1478 }
1479
1480 #[test]
1481 fn test_cache_size_tracking() {
1482 let mut cache = create_test_cache(true);
1483 let initial_size = cache.total_size;
1484 let initial_value_size = cache.total_value_size;
1485
1486 let key = vec![1, 2, 3];
1487 let value = vec![4, 5, 6];
1488 cache.insert_read_value(&key, &Some(value.clone()));
1489 cache.check_coherence();
1490
1491 assert!(cache.total_size > initial_size);
1493 assert!(cache.total_value_size > initial_value_size);
1494
1495 let value_size_with_entry = cache.total_value_size;
1496
1497 cache.insert_read_value(&key, &None);
1499 cache.check_coherence();
1500
1501 assert!(cache.total_value_size < value_size_with_entry);
1504 }
1505
1506 #[test]
1507 fn test_trim_value_cache() {
1508 let mut cache = LruPrefixCache::new(
1509 StorageCacheConfig {
1510 max_cache_size: 10000,
1511 max_value_entry_size: 500,
1512 max_find_keys_entry_size: 1000,
1513 max_find_key_values_entry_size: 2000,
1514 max_cache_entries: 100,
1515 max_cache_value_size: 50, max_cache_find_keys_size: 1000,
1517 max_cache_find_key_values_size: 1000,
1518 },
1519 true,
1520 );
1521
1522 for i in 0..10 {
1524 let key = vec![i];
1525 let value = vec![0; 20]; cache.insert_read_value(&key, &Some(value));
1527 cache.check_coherence();
1528 }
1529
1530 assert!(cache.total_value_size <= cache.config.max_cache_value_size);
1532 }
1533
1534 fn has_a_prefix_slow_method(prefixes: &BTreeSet<Vec<u8>>, key: &[u8]) -> bool {
1535 for prefix in prefixes {
1536 if key.starts_with(prefix) {
1537 return true;
1538 }
1539 }
1540 false
1541 }
1542
1543 fn has_a_prefix_fast_method(prefixes: &BTreeSet<Vec<u8>>, key: &[u8]) -> bool {
1544 match prefixes.range(..=key.to_vec()).next_back() {
1545 None => false,
1546 Some(prefix) => key.starts_with(prefix),
1547 }
1548 }
1549
1550 fn has_a_prefix(prefixes: &BTreeSet<Vec<u8>>, key: &[u8]) -> bool {
1551 let test1 = has_a_prefix_slow_method(prefixes, key);
1552 let test2 = has_a_prefix_fast_method(prefixes, key);
1553 assert_eq!(
1554 test1, test2,
1555 "The methods for testing prefix return different results"
1556 );
1557 test1
1558 }
1559
1560 fn get_prefix<R: Rng>(rng: &mut R, max_len: usize, entry_size: usize) -> Vec<u8> {
1561 let len = rng.gen_range(1..=max_len);
1562 let mut prefix = Vec::new();
1563 for _ in 0..len {
1564 let entry = rng.gen_range(0..entry_size);
1565 prefix.push(entry as u8);
1566 }
1567 prefix
1568 }
1569
1570 fn insert_into_prefix_set(prefixes: &mut BTreeSet<Vec<u8>>, new_prefix: Vec<u8>) {
1571 if has_a_prefix(prefixes, &new_prefix) {
1572 return;
1573 }
1574 let removed_keys1 = prefixes
1575 .range(get_key_range_for_prefix(new_prefix.clone()))
1576 .cloned()
1577 .collect::<BTreeSet<Vec<u8>>>();
1578 let mut removed_keys2 = BTreeSet::new();
1579 for prefix in prefixes.clone() {
1580 if prefix.starts_with(&new_prefix) {
1581 removed_keys2.insert(prefix);
1582 }
1583 }
1584 assert_eq!(
1585 removed_keys1, removed_keys2,
1586 "Inconsistent result of the computation of the intervals"
1587 );
1588 for prefix in removed_keys2 {
1589 prefixes.remove(&prefix);
1590 }
1591 prefixes.insert(new_prefix);
1592 }
1593
1594 fn test_prefix_free_set(max_len: usize, num_gen: usize, key_size: usize) {
1595 let mut rng = crate::random::make_deterministic_rng();
1596 let mut prefixes = BTreeSet::new();
1597 for _ in 0..num_gen {
1598 let new_prefix = get_prefix(&mut rng, max_len, key_size);
1599 insert_into_prefix_set(&mut prefixes, new_prefix);
1600 }
1601 }
1602
1603 #[test]
1608 fn test_lower_bounds() {
1609 test_prefix_free_set(10, 500, 2);
1610 test_prefix_free_set(6, 500, 3);
1611 test_prefix_free_set(5, 500, 4);
1612 }
1613
1614 #[test]
1615 fn test_delete_key_operations() {
1616 let mut cache = create_test_cache(true);
1617 let key1 = vec![1, 2, 3];
1618 let key2 = vec![1, 2, 4];
1619 let key3 = vec![2, 3, 4];
1620 let value = vec![42, 43, 44];
1621
1622 cache.put_key_value(&key1, &value);
1624 cache.check_coherence();
1625 cache.put_key_value(&key2, &value);
1626 cache.check_coherence();
1627 cache.put_key_value(&key3, &value);
1628 cache.check_coherence();
1629
1630 assert_eq!(cache.query_read_value(&key1), Some(Some(value.clone())));
1632 assert_eq!(cache.query_read_value(&key2), Some(Some(value.clone())));
1633 assert_eq!(cache.query_read_value(&key3), Some(Some(value.clone())));
1634
1635 cache.delete_key(&key1);
1637 cache.check_coherence();
1638
1639 assert_eq!(cache.query_read_value(&key1), Some(None));
1641 assert_eq!(cache.query_read_value(&key2), Some(Some(value.clone())));
1643 assert_eq!(cache.query_read_value(&key3), Some(Some(value.clone())));
1644
1645 cache.delete_key(&key2);
1647 cache.check_coherence();
1648
1649 assert_eq!(cache.query_read_value(&key2), Some(None));
1651 assert_eq!(cache.query_read_value(&key3), Some(Some(value)));
1653 }
1654
1655 #[test]
1656 fn test_find_key_values_entry_delete_prefix() {
1657 let mut find_entry = FindKeyValuesEntry(BTreeMap::new());
1658
1659 let key1 = vec![1, 2, 3];
1661 let key2 = vec![1, 2, 4];
1662 let key3 = vec![1, 3, 5];
1663 let key4 = vec![2, 4, 6];
1664 let value = vec![42];
1665
1666 find_entry.update_entry(&key1, Some(value.clone()));
1667 find_entry.update_entry(&key2, Some(value.clone()));
1668 find_entry.update_entry(&key3, Some(value.clone()));
1669 find_entry.update_entry(&key4, Some(value.clone()));
1670
1671 assert!(find_entry.contains_key(&key1));
1673 assert!(find_entry.contains_key(&key2));
1674 assert!(find_entry.contains_key(&key3));
1675 assert!(find_entry.contains_key(&key4));
1676
1677 find_entry.delete_prefix(&[1, 2]);
1679
1680 assert!(!find_entry.contains_key(&key1));
1682 assert!(!find_entry.contains_key(&key2));
1683 assert!(find_entry.contains_key(&key3));
1685 assert!(find_entry.contains_key(&key4));
1686
1687 find_entry.delete_prefix(&[1]);
1689
1690 assert!(!find_entry.contains_key(&key3));
1692 assert!(find_entry.contains_key(&key4));
1694 }
1695
1696 #[test]
1697 fn test_trim_value_cache_removes_entries() {
1698 let mut cache = LruPrefixCache::new(
1699 StorageCacheConfig {
1700 max_cache_size: 10000,
1701 max_value_entry_size: 500,
1702 max_find_keys_entry_size: 1000,
1703 max_find_key_values_entry_size: 2000,
1704 max_cache_entries: 100,
1705 max_cache_value_size: 30, max_cache_find_keys_size: 1000,
1707 max_cache_find_key_values_size: 1000,
1708 },
1709 true,
1710 );
1711
1712 let mut inserted_keys = Vec::new();
1714 for i in 0..6 {
1715 let key = vec![i];
1716 let value = vec![0; 10]; cache.insert_read_value(&key, &Some(value));
1718 cache.check_coherence();
1719 inserted_keys.push(key);
1720 }
1721
1722 assert!(cache.total_value_size <= cache.config.max_cache_value_size);
1724
1725 let mut remaining_count = 0;
1727 for key in &inserted_keys {
1728 if cache.query_read_value(key).is_some() {
1729 remaining_count += 1;
1730 }
1731 }
1732
1733 assert!(remaining_count < inserted_keys.len());
1735
1736 let last_key = &inserted_keys[inserted_keys.len() - 1];
1738 assert!(cache.query_read_value(last_key).is_some());
1739 }
1740
1741 #[test]
1742 fn test_max_value_entry_size_zero_early_termination() {
1743 let mut cache = LruPrefixCache::new(
1744 StorageCacheConfig {
1745 max_cache_size: 1000,
1746 max_value_entry_size: 0, max_find_keys_entry_size: 100,
1748 max_find_key_values_entry_size: 200,
1749 max_cache_entries: 10,
1750 max_cache_value_size: 500,
1751 max_cache_find_keys_size: 500,
1752 max_cache_find_key_values_size: 500,
1753 },
1754 true,
1755 );
1756
1757 let key1 = vec![1, 2, 3];
1758 let key2 = vec![4, 5, 6];
1759 let value = vec![42, 43, 44];
1760
1761 cache.insert_read_value(&key1, &Some(value.clone()));
1763 cache.check_coherence();
1764 cache.insert_read_value(&key2, &None);
1765 cache.check_coherence();
1766
1767 assert_eq!(cache.query_read_value(&key1), None);
1769 assert_eq!(cache.query_read_value(&key2), None);
1770
1771 assert_eq!(cache.total_size, 0);
1773 assert_eq!(cache.total_value_size, 0);
1774 assert!(cache.value_map.is_empty());
1775 assert!(cache.queue.is_empty());
1776
1777 cache.put_key_value(&key1, &value);
1779 cache.check_coherence();
1780
1781 assert_eq!(cache.query_read_value(&key1), None);
1782 assert_eq!(cache.total_size, 0);
1783
1784 cache.delete_key(&key1);
1786 cache.check_coherence();
1787
1788 assert_eq!(cache.query_read_value(&key1), None);
1789 assert_eq!(cache.total_size, 0);
1790 }
1791
1792 #[test]
1793 fn test_key_value_replacement_same_length() {
1794 let mut cache = create_test_cache(true);
1795 let key = vec![1, 2, 3];
1796 let value1 = vec![42, 43, 44]; let value2 = vec![99, 98, 97]; cache.put_key_value(&key, &value1);
1801 cache.check_coherence();
1802
1803 assert_eq!(cache.query_read_value(&key), Some(Some(value1.clone())));
1805
1806 let initial_size = cache.total_size;
1807 let initial_value_size = cache.total_value_size;
1808
1809 cache.put_key_value(&key, &value2);
1811 cache.check_coherence();
1812
1813 assert_eq!(cache.query_read_value(&key), Some(Some(value2.clone())));
1815
1816 assert_eq!(cache.total_size, initial_size);
1818 assert_eq!(cache.total_value_size, initial_value_size);
1819
1820 assert_eq!(cache.value_map.len(), 1);
1822 assert_eq!(cache.queue.len(), 1);
1823
1824 let value3 = vec![11, 22, 33]; cache.insert_read_value(&key, &Some(value3.clone()));
1827 cache.check_coherence();
1828
1829 assert_eq!(cache.query_read_value(&key), Some(Some(value3)));
1831
1832 assert_eq!(cache.total_size, initial_size);
1834 assert_eq!(cache.total_value_size, initial_value_size);
1835 }
1836
1837 #[test]
1838 fn test_max_find_keys_entry_size_zero_early_termination() {
1839 let mut cache = LruPrefixCache::new(
1840 StorageCacheConfig {
1841 max_cache_size: 1000,
1842 max_value_entry_size: 100,
1843 max_find_keys_entry_size: 0, max_find_key_values_entry_size: 200,
1845 max_cache_entries: 10,
1846 max_cache_value_size: 500,
1847 max_cache_find_keys_size: 500,
1848 max_cache_find_key_values_size: 500,
1849 },
1850 true,
1851 );
1852
1853 let prefix = vec![1, 2];
1854 let keys = vec![vec![3], vec![4], vec![5]];
1855
1856 cache.insert_find_keys(prefix.clone(), &keys);
1858 cache.check_coherence();
1859
1860 assert_eq!(cache.query_find_keys(&prefix), None);
1862
1863 assert_eq!(cache.total_find_keys_size, 0);
1865 assert!(cache.find_keys_map.is_empty());
1866
1867 for (cache_key, _) in &cache.queue {
1869 assert!(!matches!(cache_key, CacheKey::FindKeys(_)));
1870 }
1871
1872 let prefix2 = vec![9];
1874 let keys2 = vec![vec![1]];
1875 cache.insert_find_keys(prefix2.clone(), &keys2);
1876 cache.check_coherence();
1877
1878 assert_eq!(cache.query_find_keys(&prefix2), None);
1879 assert_eq!(cache.total_find_keys_size, 0);
1880 assert!(cache.find_keys_map.is_empty());
1881 }
1882
1883 #[test]
1884 fn test_max_find_key_values_entry_size_zero_early_termination() {
1885 let mut cache = LruPrefixCache::new(
1886 StorageCacheConfig {
1887 max_cache_size: 1000,
1888 max_value_entry_size: 100,
1889 max_find_keys_entry_size: 100,
1890 max_find_key_values_entry_size: 0, max_cache_entries: 10,
1892 max_cache_value_size: 500,
1893 max_cache_find_keys_size: 500,
1894 max_cache_find_key_values_size: 500,
1895 },
1896 true,
1897 );
1898
1899 let prefix = vec![1, 2];
1900 let key_values = vec![(vec![3], vec![10]), (vec![4], vec![20])];
1901
1902 cache.insert_find_key_values(prefix.clone(), &key_values);
1904 cache.check_coherence();
1905
1906 assert_eq!(cache.query_find_key_values(&prefix), None);
1908
1909 assert_eq!(cache.total_find_key_values_size, 0);
1911 assert!(cache.find_key_values_map.is_empty());
1912
1913 for (cache_key, _) in &cache.queue {
1915 assert!(!matches!(cache_key, CacheKey::FindKeyValues(_)));
1916 }
1917
1918 let prefix2 = vec![9];
1920 let key_values2 = vec![(vec![1], vec![100])];
1921 cache.insert_find_key_values(prefix2.clone(), &key_values2);
1922 cache.check_coherence();
1923
1924 assert_eq!(cache.query_find_key_values(&prefix2), None);
1925 assert_eq!(cache.total_find_key_values_size, 0);
1926 assert!(cache.find_key_values_map.is_empty());
1927 }
1928
1929 #[test]
1930 fn test_value_entry_exists_returns_none() {
1931 let mut cache = create_test_cache(true);
1932 let key = vec![1, 2, 3];
1933
1934 cache.insert_contains_key(&key, true);
1936 cache.check_coherence();
1937
1938 assert_eq!(cache.query_contains_key(&key), Some(true));
1940
1941 assert_eq!(cache.query_read_value(&key), None);
1944
1945 let key2 = vec![4, 5, 6];
1947 cache.insert_contains_key(&key2, false);
1948 cache.check_coherence();
1949
1950 assert_eq!(cache.query_contains_key(&key2), Some(false));
1952
1953 assert_eq!(cache.query_read_value(&key2), Some(None));
1955
1956 assert_eq!(cache.value_map.len(), 2);
1958 assert_eq!(cache.queue.len(), 2);
1959
1960 assert!(matches!(
1962 cache.value_map.get(&key),
1963 Some(ValueEntry::Exists)
1964 ));
1965 assert!(matches!(
1966 cache.value_map.get(&key2),
1967 Some(ValueEntry::DoesNotExist)
1968 ));
1969 }
1970
1971 #[test]
1972 fn test_find_keys_entry_delete_prefix_function() {
1973 let mut find_entry = FindKeysEntry(BTreeSet::new());
1974
1975 let key1 = vec![1, 2, 3];
1977 let key2 = vec![1, 2, 4];
1978 let key3 = vec![1, 3, 5];
1979 let key4 = vec![2, 4, 6];
1980
1981 find_entry.update_entry(&key1, true);
1982 find_entry.update_entry(&key2, true);
1983 find_entry.update_entry(&key3, true);
1984 find_entry.update_entry(&key4, true);
1985
1986 assert!(find_entry.contains_key(&key1));
1988 assert!(find_entry.contains_key(&key2));
1989 assert!(find_entry.contains_key(&key3));
1990 assert!(find_entry.contains_key(&key4));
1991 assert_eq!(find_entry.0.len(), 4);
1992
1993 find_entry.delete_prefix(&[1, 2]);
1995
1996 assert!(!find_entry.contains_key(&key1));
1998 assert!(!find_entry.contains_key(&key2));
1999 assert!(find_entry.contains_key(&key3));
2001 assert!(find_entry.contains_key(&key4));
2002 assert_eq!(find_entry.0.len(), 2);
2003
2004 find_entry.delete_prefix(&[1]);
2006
2007 assert!(!find_entry.contains_key(&key3));
2009 assert!(find_entry.contains_key(&key4));
2011 assert_eq!(find_entry.0.len(), 1);
2012
2013 find_entry.delete_prefix(&[]);
2015
2016 assert!(!find_entry.contains_key(&key4));
2018 assert_eq!(find_entry.0.len(), 0);
2019 }
2020
2021 #[test]
2022 fn test_find_keys_size_decrease() {
2023 let mut cache = create_test_cache(true);
2024 let prefix = vec![1];
2025 let initial_keys = vec![vec![2, 3, 4], vec![3, 4, 5]]; cache.insert_find_keys(prefix.clone(), &initial_keys);
2029 cache.check_coherence();
2030
2031 let initial_total_size = cache.total_size;
2032 let initial_find_keys_size = cache.total_find_keys_size;
2033
2034 let key_to_delete = vec![1, 2, 3, 4]; cache.delete_key(&key_to_delete);
2037 cache.check_coherence();
2038
2039 assert!(cache.total_size < initial_total_size);
2041 assert!(cache.total_find_keys_size < initial_find_keys_size);
2042
2043 let result = cache.query_find_keys(&prefix);
2045 assert!(result.is_some());
2046 let keys = result.unwrap();
2047 assert!(keys.contains(&vec![3, 4, 5])); assert!(!keys.contains(&vec![2, 3, 4])); cache.check_coherence();
2051 }
2052
2053 #[test]
2054 fn test_trim_find_keys_cache_lru_eviction() {
2055 let mut cache = LruPrefixCache::new(
2056 StorageCacheConfig {
2057 max_cache_size: 10000,
2058 max_value_entry_size: 500,
2059 max_find_keys_entry_size: 1000,
2060 max_find_key_values_entry_size: 2000,
2061 max_cache_entries: 100,
2062 max_cache_value_size: 5000,
2063 max_cache_find_keys_size: 50, max_cache_find_key_values_size: 5000,
2065 },
2066 true,
2067 );
2068
2069 let prefix1 = vec![1];
2071 let keys1 = vec![vec![2; 10], vec![3; 10]]; cache.insert_find_keys(prefix1.clone(), &keys1);
2073 cache.check_coherence();
2074
2075 let prefix2 = vec![2];
2077 let keys2 = vec![vec![4; 10], vec![5; 10]]; cache.insert_find_keys(prefix2.clone(), &keys2);
2079 cache.check_coherence();
2080
2081 assert!(cache.query_find_keys(&prefix1).is_some());
2083 assert!(cache.query_find_keys(&prefix2).is_some());
2084
2085 let prefix3 = vec![3];
2087 let keys3 = vec![vec![6; 10], vec![7; 10]]; cache.insert_find_keys(prefix3.clone(), &keys3);
2089 cache.check_coherence();
2090
2091 assert!(cache.total_find_keys_size <= cache.config.max_cache_find_keys_size);
2093
2094 assert_eq!(cache.query_find_keys(&prefix1), None);
2096
2097 assert!(cache.query_find_keys(&prefix2).is_some());
2099 assert!(cache.query_find_keys(&prefix3).is_some());
2100
2101 assert!(cache.find_keys_map.len() < 3);
2103 }
2104
2105 #[test]
2106 fn test_find_keys_removal_from_map() {
2107 let mut cache = LruPrefixCache::new(
2108 StorageCacheConfig {
2109 max_cache_size: 100, max_value_entry_size: 50,
2111 max_find_keys_entry_size: 1000,
2112 max_find_key_values_entry_size: 2000,
2113 max_cache_entries: 3, max_cache_value_size: 500,
2115 max_cache_find_keys_size: 500,
2116 max_cache_find_key_values_size: 500,
2117 },
2118 true,
2119 );
2120
2121 let prefix1 = vec![1];
2122 let prefix2 = vec![2];
2123 let prefix3 = vec![3];
2124 let keys = vec![vec![1], vec![2]];
2125
2126 cache.insert_find_keys(prefix1.clone(), &keys);
2128 cache.check_coherence();
2129 cache.insert_find_keys(prefix2.clone(), &keys);
2130 cache.check_coherence();
2131
2132 assert!(cache.find_keys_map.contains_key(&prefix1));
2134 assert!(cache.find_keys_map.contains_key(&prefix2));
2135
2136 cache.insert_find_keys(prefix3.clone(), &keys);
2138 cache.check_coherence();
2139
2140 assert!(!cache.find_keys_map.contains_key(&prefix1));
2142 assert!(cache.find_keys_map.contains_key(&prefix2));
2144 assert!(cache.find_keys_map.contains_key(&prefix3));
2145
2146 assert!(cache.queue.len() <= cache.config.max_cache_entries);
2148 }
2149
2150 #[test]
2151 fn test_find_key_values_removal_from_map() {
2152 let mut cache = LruPrefixCache::new(
2153 StorageCacheConfig {
2154 max_cache_size: 100, max_value_entry_size: 50,
2156 max_find_keys_entry_size: 1000,
2157 max_find_key_values_entry_size: 2000,
2158 max_cache_entries: 3, max_cache_value_size: 500,
2160 max_cache_find_keys_size: 500,
2161 max_cache_find_key_values_size: 500,
2162 },
2163 true,
2164 );
2165
2166 let prefix1 = vec![1];
2167 let prefix2 = vec![2];
2168 let prefix3 = vec![3];
2169 let key_values = vec![(vec![1], vec![10]), (vec![2], vec![20])];
2170
2171 cache.insert_find_key_values(prefix1.clone(), &key_values);
2173 cache.check_coherence();
2174 cache.insert_find_key_values(prefix2.clone(), &key_values);
2175 cache.check_coherence();
2176
2177 assert!(cache.find_key_values_map.contains_key(&prefix1));
2179 assert!(cache.find_key_values_map.contains_key(&prefix2));
2180
2181 cache.insert_find_key_values(prefix3.clone(), &key_values);
2183 cache.check_coherence();
2184
2185 assert!(!cache.find_key_values_map.contains_key(&prefix1));
2187 assert!(cache.find_key_values_map.contains_key(&prefix2));
2189 assert!(cache.find_key_values_map.contains_key(&prefix3));
2190
2191 assert!(cache.queue.len() <= cache.config.max_cache_entries);
2193 }
2194
2195 #[test]
2196 fn test_contains_key_failing_without_exclusive_access() {
2197 let mut cache = create_test_cache(false); let key = vec![1, 2, 3];
2199
2200 let result = cache.query_contains_key(&key);
2203 assert_eq!(result, None);
2204
2205 cache.insert_contains_key(&key, true);
2207 cache.check_coherence();
2208
2209 let result = cache.query_contains_key(&key);
2211 assert_eq!(result, Some(true));
2212 }
2213
2214 #[test]
2215 fn test_contains_key_found_in_find_key_values() {
2216 let mut cache = create_test_cache(true); let prefix = vec![1, 2];
2218 let key = vec![1, 2, 3, 4];
2219 let key_values = vec![(vec![3, 4], vec![100]), (vec![5, 6], vec![200])];
2220
2221 cache.insert_find_key_values(prefix.clone(), &key_values);
2223 cache.check_coherence();
2224
2225 let result = cache.query_contains_key(&key);
2227 assert_eq!(result, Some(true));
2228
2229 let non_existent_key = vec![1, 2, 7, 8];
2231 let result = cache.query_contains_key(&non_existent_key);
2232 assert_eq!(result, Some(false)); let unmatched_key = vec![9, 9, 9];
2236 let result = cache.query_contains_key(&unmatched_key);
2237 assert_eq!(result, None); }
2239
2240 #[test]
2241 fn test_find_keys_removal_when_inserting_broader_find_keys() {
2242 let mut cache = create_test_cache(true);
2243
2244 let specific_prefix = vec![1, 2, 3, 4];
2246 let keys2 = vec![vec![6], vec![7]];
2247 cache.insert_find_keys(specific_prefix.clone(), &keys2);
2248 cache.check_coherence();
2249
2250 let narrow_prefix = vec![1, 2, 3];
2252 let keys1 = vec![vec![4, 6], vec![4, 7]];
2253 cache.insert_find_keys(narrow_prefix.clone(), &keys1);
2254 cache.check_coherence();
2255 }
2256
2257 #[test]
2258 fn test_overlapping_find_key_values_removes_find_keys_and_find_key_values() {
2259 let mut cache = create_test_cache(true);
2260
2261 let find_keys_prefix = vec![1, 2, 3];
2263 let keys = vec![vec![4, 6], vec![4, 7], vec![5]];
2264 cache.insert_find_keys(find_keys_prefix.clone(), &keys);
2265 cache.check_coherence();
2266
2267 let find_key_values_prefix = vec![1, 2, 3, 4];
2269 let key_values1 = vec![(vec![6], vec![10]), (vec![7], vec![20])];
2270 cache.insert_find_key_values(find_key_values_prefix.clone(), &key_values1);
2271 cache.check_coherence();
2272
2273 cache.put_key_value(&[1, 2, 8, 9], &[254]);
2275 cache.check_coherence();
2276
2277 let broad_prefix = vec![1, 2];
2279 let key_values2 = vec![
2280 (vec![3, 4, 6], vec![10]),
2281 (vec![3, 4, 7], vec![20]),
2282 (vec![3, 5], vec![34]),
2283 (vec![8, 9], vec![254]),
2284 ];
2285 cache.insert_find_key_values(broad_prefix.clone(), &key_values2);
2286 cache.check_coherence();
2287
2288 assert!(!cache.find_keys_map.contains_key(&find_keys_prefix));
2290
2291 assert!(!cache
2293 .find_key_values_map
2294 .contains_key(&find_key_values_prefix));
2295
2296 assert!(cache.find_key_values_map.contains_key(&broad_prefix));
2298
2299 let key_values = cache.query_find_key_values(&broad_prefix).unwrap();
2301 assert!(key_values.contains(&(vec![3, 4, 6], vec![10])));
2302 assert!(key_values.contains(&(vec![3, 4, 7], vec![20])));
2303 assert!(key_values.contains(&(vec![8, 9], vec![254])));
2304
2305 let query_result = cache.query_contains_key(&[1, 2, 3, 1]);
2307 assert_eq!(query_result, Some(false)); }
2309
2310 #[test]
2311 fn test_delete_prefix_removes_entire_find_keys_entry() {
2312 let mut cache = create_test_cache(true); let prefix = vec![1, 2, 3];
2316 let keys = vec![vec![4], vec![5], vec![6]];
2317 cache.insert_find_keys(prefix.clone(), &keys);
2318 cache.check_coherence();
2319
2320 assert!(cache.find_keys_map.contains_key(&prefix));
2322 let result = cache.query_find_keys(&prefix);
2323 assert!(result.is_some());
2324
2325 let delete_prefix = vec![1, 2]; cache.delete_prefix(&delete_prefix);
2328 cache.check_coherence();
2329
2330 let result = cache.query_find_keys(&prefix);
2332 assert_eq!(result, Some(vec![]));
2333
2334 for (cache_key, _) in &cache.queue {
2336 assert!(!matches!(cache_key, CacheKey::FindKeys(key) if key == &prefix));
2337 }
2338 }
2339
2340 #[test]
2341 fn test_delete_prefix_removes_keys_within_find_keys_entry() {
2342 let mut cache = create_test_cache(true); let find_keys_prefix = vec![1];
2346 let keys = vec![vec![2, 3, 4], vec![2, 3, 5], vec![2, 4, 6], vec![3, 7, 8]];
2347 cache.insert_find_keys(find_keys_prefix.clone(), &keys);
2348 cache.check_coherence();
2349
2350 assert!(cache.find_keys_map.contains_key(&find_keys_prefix));
2352 let initial_keys = cache.query_find_keys(&find_keys_prefix).unwrap();
2353 assert!(initial_keys.contains(&vec![2, 3, 4]));
2354 assert!(initial_keys.contains(&vec![2, 3, 5]));
2355 assert!(initial_keys.contains(&vec![2, 4, 6]));
2356 assert!(initial_keys.contains(&vec![3, 7, 8]));
2357
2358 let initial_size = cache.total_find_keys_size;
2359
2360 let delete_prefix = vec![1, 2, 3]; cache.delete_prefix(&delete_prefix);
2363 cache.check_coherence();
2364
2365 assert!(cache.find_keys_map.contains_key(&find_keys_prefix));
2367
2368 let remaining_keys = cache.query_find_keys(&find_keys_prefix).unwrap();
2370 assert!(!remaining_keys.contains(&vec![2, 3, 4])); assert!(!remaining_keys.contains(&vec![2, 3, 5])); assert!(remaining_keys.contains(&vec![2, 4, 6])); assert!(remaining_keys.contains(&vec![3, 7, 8])); assert!(cache.total_find_keys_size < initial_size);
2377
2378 let delete_prefix2 = vec![1, 2]; cache.delete_prefix(&delete_prefix2);
2381 cache.check_coherence();
2382
2383 let final_keys = cache.query_find_keys(&find_keys_prefix).unwrap();
2385 assert!(!final_keys.contains(&vec![2, 4, 6])); assert!(final_keys.contains(&vec![3, 7, 8])); }
2388
2389 #[test]
2390 fn test_put_key_value_without_find_key_values_match() {
2391 let mut cache = create_test_cache(false); let key = vec![1, 2, 3, 4];
2393 let value = vec![100, 200];
2394
2395 cache.put_key_value(&key, &value);
2397 cache.check_coherence();
2398
2399 assert_eq!(cache.query_read_value(&key), Some(Some(value.clone())));
2401 assert!(cache.value_map.contains_key(&key));
2402 }
2403
2404 #[test]
2405 fn test_delete_key_without_exclusive_access() {
2406 let mut cache = create_test_cache(false); let key = vec![1, 2, 3];
2408 let value = vec![42, 43, 44];
2409
2410 cache.insert_read_value(&key, &Some(value.clone()));
2412 cache.check_coherence();
2413
2414 assert_eq!(cache.query_read_value(&key), Some(Some(value)));
2416 assert!(cache.value_map.contains_key(&key));
2417
2418 cache.delete_key(&key);
2421 cache.check_coherence();
2422
2423 assert!(!cache.value_map.contains_key(&key));
2425 assert_eq!(cache.query_read_value(&key), None);
2426
2427 for (cache_key, _) in &cache.queue {
2429 assert!(!matches!(cache_key, CacheKey::Value(k) if k == &key));
2430 }
2431
2432 let non_existent_key = vec![9, 9, 9];
2434 cache.delete_key(&non_existent_key); cache.check_coherence();
2436 }
2437
2438 #[test]
2439 fn test_line_502_insert_then_delete_without_exclusive_access() {
2440 let mut cache = create_test_cache(false); let key = vec![1, 2, 3, 4];
2442 let value = vec![100, 200, 201];
2443
2444 cache.insert_read_value(&key, &Some(value.clone()));
2446 cache.check_coherence();
2447
2448 assert_eq!(cache.query_read_value(&key), Some(Some(value)));
2450 assert!(cache.value_map.contains_key(&key));
2451
2452 cache.insert_read_value(&key, &None);
2455 cache.check_coherence();
2456
2457 assert!(!cache.value_map.contains_key(&key));
2459 assert_eq!(cache.query_read_value(&key), None);
2460
2461 let queue_contains_key = cache
2463 .queue
2464 .iter()
2465 .any(|(cache_key, _)| matches!(cache_key, CacheKey::Value(k) if k == &key));
2466 assert!(!queue_contains_key);
2467 }
2468
2469 #[test]
2470 fn test_does_not_exist_removal_during_insert_find_keys() {
2471 let mut cache = create_test_cache(true); let prefix = vec![1, 2];
2473 let key1 = vec![1, 2, 3];
2474 let key2 = vec![1, 2, 4];
2475 let key3 = vec![1, 2, 5];
2476
2477 cache.insert_read_value(&key1, &None); cache.insert_read_value(&key2, &None); cache.insert_read_value(&key3, &Some(vec![100])); cache.check_coherence();
2482
2483 assert_eq!(cache.query_read_value(&key1), Some(None));
2485 assert_eq!(cache.query_read_value(&key2), Some(None));
2486 assert_eq!(cache.query_read_value(&key3), Some(Some(vec![100])));
2487 assert!(cache.value_map.contains_key(&key1));
2488 assert!(cache.value_map.contains_key(&key2));
2489 assert!(cache.value_map.contains_key(&key3));
2490
2491 let find_keys_result = vec![key1.clone(), key2.clone(), key3.clone()];
2494 cache.insert_find_keys(prefix.clone(), &find_keys_result);
2495 cache.check_coherence();
2496
2497 assert_eq!(cache.query_read_value(&key1), None); assert_eq!(cache.query_read_value(&key2), None); assert_eq!(cache.query_read_value(&key3), Some(Some(vec![100]))); assert!(!cache.value_map.contains_key(&key1));
2503 assert!(!cache.value_map.contains_key(&key2));
2504 assert!(cache.value_map.contains_key(&key3)); assert_eq!(cache.query_find_keys(&prefix), Some(find_keys_result));
2508 }
2509
2510 #[test]
2511 fn test_trim_value_cache_complete_iteration() {
2512 let mut cache = create_test_cache(true);
2513
2514 let key1 = vec![1, 2, 3];
2516 let key2 = vec![4, 5, 6];
2517 let value1 = vec![100, 200];
2518 let value2 = vec![203, 177];
2519
2520 cache.insert_read_value(&key1, &Some(value1));
2521 cache.insert_read_value(&key2, &Some(value2));
2522 cache.check_coherence();
2523
2524 cache.config.max_cache_value_size = 0;
2526
2527 cache.trim_value_cache();
2530 cache.check_coherence();
2531
2532 assert!(!cache.value_map.contains_key(&key1));
2534 assert!(!cache.value_map.contains_key(&key2));
2535 }
2536
2537 #[test]
2538 fn test_trim_find_keys_cache_complete_iteration() {
2539 let mut cache = create_test_cache(true);
2540
2541 let prefix1 = vec![1, 2];
2543 let prefix2 = vec![3, 4];
2544 let keys1 = vec![vec![1, 2, 3], vec![1, 2, 4]];
2545 let keys2 = vec![vec![3, 4, 5], vec![3, 4, 6]];
2546
2547 cache.insert_find_keys(prefix1, &keys1);
2548 cache.insert_find_keys(prefix2, &keys2);
2549 cache.check_coherence();
2550
2551 cache.config.max_cache_find_keys_size = 0;
2553
2554 cache.trim_find_keys_cache();
2557 cache.check_coherence();
2558
2559 assert!(cache.find_keys_map.is_empty());
2561 }
2562
2563 #[test]
2564 fn test_trim_find_key_values_cache_complete_iteration() {
2565 let mut cache = create_test_cache(true);
2566
2567 let prefix1 = vec![1, 2];
2569 let prefix2 = vec![3, 4];
2570 let key_values1 = vec![(vec![1, 2, 3], vec![100]), (vec![1, 2, 4], vec![200])];
2571 let key_values2 = vec![(vec![3, 4, 5], vec![203]), (vec![3, 4, 6], vec![177])];
2572
2573 cache.insert_find_key_values(prefix1, &key_values1);
2574 cache.insert_find_key_values(prefix2, &key_values2);
2575 cache.check_coherence();
2576
2577 cache.config.max_cache_find_key_values_size = 0;
2579
2580 cache.trim_find_key_values_cache();
2583 cache.check_coherence();
2584
2585 assert!(cache.find_key_values_map.is_empty());
2587 }
2588
2589 #[test]
2590 fn test_trim_cache_breaks_on_empty_queue() {
2591 let mut cache = LruPrefixCache::new(
2592 StorageCacheConfig {
2593 max_cache_size: 10000, max_value_entry_size: 10000, max_find_keys_entry_size: 10000,
2596 max_find_key_values_entry_size: 10000,
2597 max_cache_entries: 10,
2598 max_cache_value_size: 500,
2599 max_cache_find_keys_size: 500,
2600 max_cache_find_key_values_size: 500,
2601 },
2602 true,
2603 );
2604
2605 for i in 0..10 {
2607 let key = vec![1, 2, i];
2608 let value = vec![100 + i];
2609 cache.insert_read_value(&key, &Some(value));
2610 cache.check_coherence();
2611 }
2612
2613 cache.config.max_cache_size = 0;
2615
2616 let key = vec![1, 2];
2618 let value = vec![100];
2619 cache.insert_read_value(&key, &Some(value));
2620 cache.check_coherence();
2621 }
2622}