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 use std::collections::BTreeSet;
953
954 use rand::Rng;
955
956 use super::*;
957
958 fn check_prefix_free(set: BTreeSet<Vec<u8>>) {
959 let keys = set.into_iter().collect::<Vec<_>>();
960 let num_keys = keys.len();
961 println!("keys={keys:?}");
962 for i in 0..num_keys {
963 for j in 0..num_keys {
964 if i != j {
965 let key1 = keys[i].clone();
966 let key2 = keys[j].clone();
967 println!("i={i} j={j} key1={key1:?} key2={key2:?}");
968 assert!(!key1.starts_with(&key2));
969 }
970 }
971 }
972 }
973
974 fn check_intersection(keys: Vec<Vec<u8>>, prefixes: &BTreeSet<Vec<u8>>) {
975 for key in keys {
976 for prefix in prefixes {
977 assert!(!key.starts_with(prefix), "key matches a prefix");
978 }
979 }
980 }
981
982 impl LruPrefixCache {
983 fn check_coherence(&self) {
984 let value_map_set = self
985 .value_map
986 .keys()
987 .cloned()
988 .collect::<BTreeSet<Vec<u8>>>();
989 let find_keys_map_set = self
990 .find_keys_map
991 .keys()
992 .cloned()
993 .collect::<BTreeSet<Vec<u8>>>();
994 let find_key_values_map_set = self
995 .find_key_values_map
996 .keys()
997 .cloned()
998 .collect::<BTreeSet<Vec<u8>>>();
999 check_prefix_free(find_keys_map_set.clone());
1001 check_prefix_free(find_key_values_map_set.clone());
1002 let mut value_queue_set = BTreeSet::new();
1005 let mut find_keys_queue_set = BTreeSet::new();
1006 let mut find_key_values_queue_set = BTreeSet::new();
1007 let mut total_size = 0;
1008 let mut total_value_size = 0;
1009 let mut total_find_keys_size = 0;
1010 let mut total_find_key_values_size = 0;
1011 for (cache_key, size) in &self.queue {
1012 let queue_size = *size;
1013 match cache_key {
1014 CacheKey::Value(key) => {
1015 let value = self.value_map.get(key).unwrap();
1016 let map_size = key.len() + value.size();
1017 assert_eq!(map_size, queue_size, "Incoherence in value size");
1018 value_queue_set.insert(key.clone());
1019 total_value_size += queue_size;
1020 }
1021 CacheKey::FindKeys(key) => {
1022 let value = self.find_keys_map.get(key).unwrap();
1023 let map_size = key.len() + value.size();
1024 assert_eq!(map_size, queue_size, "Incoherence in find-keys size");
1025 find_keys_queue_set.insert(key.clone());
1026 total_find_keys_size += queue_size;
1027 }
1028 CacheKey::FindKeyValues(key) => {
1029 let value = self.find_key_values_map.get(key).unwrap();
1030 let map_size = key.len() + value.size();
1031 assert_eq!(map_size, queue_size, "Incoherence in find-keys size");
1032 find_key_values_queue_set.insert(key.clone());
1033 total_find_key_values_size += queue_size;
1034 }
1035 }
1036 total_size += queue_size;
1037 }
1038 let value_map_vect = self.value_map.keys().cloned().collect::<Vec<_>>();
1040 check_intersection(value_map_vect, &find_key_values_map_set);
1041 let value_existence_map_vect = self
1042 .value_map
1043 .iter()
1044 .filter_map(|(key, value)| match value {
1045 ValueEntry::DoesNotExist => Some(key.to_vec()),
1046 ValueEntry::Exists => Some(key.to_vec()),
1047 ValueEntry::Value(_) => None,
1048 })
1049 .collect::<Vec<_>>();
1050 check_intersection(value_existence_map_vect, &find_keys_map_set);
1051 assert_eq!(
1053 value_queue_set, value_map_set,
1054 "Incoherence in value_map keys"
1055 );
1056 assert_eq!(
1057 find_keys_queue_set, find_keys_map_set,
1058 "Incoherence in find_keys_map keys"
1059 );
1060 assert_eq!(
1061 find_key_values_queue_set, find_key_values_map_set,
1062 "Incoherence in find_key_values_map keys"
1063 );
1064 assert_eq!(total_size, self.total_size, "The total_size are incoherent");
1066 assert_eq!(
1067 total_value_size, self.total_value_size,
1068 "The total_value_size are incoherent"
1069 );
1070 assert_eq!(
1071 total_find_keys_size, self.total_find_keys_size,
1072 "The total_find_keys_size are incoherent"
1073 );
1074 assert_eq!(
1075 total_find_key_values_size, self.total_find_key_values_size,
1076 "The total_find_key_values_size are incoherent"
1077 );
1078 if self.config.max_cache_size > 0 {
1080 assert!(
1081 total_size < self.config.max_cache_size,
1082 "The total_size is too large"
1083 );
1084 } else {
1085 assert!(total_size == 0, "The total_size should be 0");
1086 }
1087 if self.config.max_cache_value_size > 0 {
1088 assert!(
1089 total_value_size < self.config.max_cache_value_size,
1090 "The total_value_size is too large"
1091 );
1092 } else {
1093 assert!(total_value_size == 0, "The total_value_size should be 0");
1094 }
1095 if self.config.max_cache_find_keys_size > 0 {
1096 assert!(
1097 total_find_keys_size < self.config.max_cache_find_keys_size,
1098 "The total_value_size is too large"
1099 );
1100 } else {
1101 assert!(
1102 total_find_keys_size == 0,
1103 "The total_find_keys_size should be 0"
1104 );
1105 }
1106 if self.config.max_cache_find_key_values_size > 0 {
1107 assert!(
1108 total_find_key_values_size < self.config.max_cache_find_key_values_size,
1109 "The total_find_key_values_size is too large"
1110 );
1111 } else {
1112 assert!(
1113 total_find_key_values_size == 0,
1114 "The total_find_key_values_size should be 0"
1115 );
1116 }
1117 }
1118 }
1119
1120 fn create_test_cache(has_exclusive_access: bool) -> LruPrefixCache {
1121 let config = StorageCacheConfig {
1122 max_cache_size: 1000,
1123 max_value_entry_size: 50,
1124 max_find_keys_entry_size: 100,
1125 max_find_key_values_entry_size: 200,
1126 max_cache_entries: 10,
1127 max_cache_value_size: 500,
1128 max_cache_find_keys_size: 500,
1129 max_cache_find_key_values_size: 500,
1130 };
1131 LruPrefixCache::new(config, has_exclusive_access)
1132 }
1133
1134 #[test]
1135 fn test_new_cache_creation() {
1136 let cache = create_test_cache(true);
1137 assert_eq!(cache.total_size, 0);
1138 assert_eq!(cache.total_value_size, 0);
1139 assert_eq!(cache.total_find_keys_size, 0);
1140 assert_eq!(cache.total_find_key_values_size, 0);
1141 assert!(cache.has_exclusive_access);
1142 assert!(cache.value_map.is_empty());
1143 assert!(cache.find_keys_map.is_empty());
1144 assert!(cache.find_key_values_map.is_empty());
1145 assert!(cache.queue.is_empty());
1146 }
1147
1148 #[test]
1149 fn test_insert_and_query_read_value() {
1150 let mut cache = create_test_cache(true);
1151 let key = vec![1, 2, 3];
1152 let value = vec![4, 5, 6];
1153
1154 cache.insert_read_value(&key, &Some(value.clone()));
1156 cache.check_coherence();
1157
1158 let result = cache.query_read_value(&key);
1160 assert_eq!(result, Some(Some(value)));
1161
1162 let result = cache.query_read_value(&[9, 9, 9]);
1164 assert_eq!(result, None);
1165 }
1166
1167 #[test]
1168 fn test_insert_and_query_contains_key() {
1169 let mut cache = create_test_cache(true);
1170 let key = vec![1, 2, 3];
1171
1172 cache.insert_contains_key(&key, true);
1174 cache.check_coherence();
1175
1176 let result = cache.query_contains_key(&key);
1178 assert_eq!(result, Some(true));
1179
1180 let key2 = vec![4, 5, 6];
1182 cache.insert_contains_key(&key2, false);
1183
1184 let result = cache.query_contains_key(&key2);
1185 assert_eq!(result, Some(false));
1186 }
1187
1188 #[test]
1189 fn test_insert_and_query_find_keys() {
1190 let mut cache = create_test_cache(true);
1191 let prefix = vec![1, 2];
1192 let keys = vec![vec![3], vec![4], vec![5]];
1193
1194 cache.insert_find_keys(prefix.clone(), &keys);
1196 cache.check_coherence();
1197
1198 let result = cache.query_find_keys(&prefix);
1200 assert_eq!(result, Some(keys.clone()));
1201
1202 let longer_prefix = vec![1, 2, 3];
1204 let result = cache.query_find_keys(&longer_prefix);
1205 assert_eq!(result, Some(vec![vec![]])); let result = cache.query_find_keys(&[9, 9]);
1209 assert_eq!(result, None);
1210 }
1211
1212 #[test]
1213 fn test_insert_and_query_find_key_values() {
1214 let mut cache = create_test_cache(true);
1215 let prefix = vec![1, 2];
1216 let key_values = vec![(vec![3], vec![10]), (vec![4], vec![20])];
1217
1218 cache.insert_find_key_values(prefix.clone(), &key_values);
1220 cache.check_coherence();
1221
1222 let result = cache.query_find_key_values(&prefix);
1224 assert_eq!(result, Some(key_values.clone()));
1225
1226 let result = cache.query_find_key_values(&[9, 9]);
1228 assert_eq!(result, None);
1229 }
1230
1231 #[test]
1232 fn test_lru_eviction_by_cache_size() {
1233 let mut cache = create_test_cache(true);
1234
1235 for i in 0..20 {
1237 let key = vec![i];
1238 let value = vec![0; 100]; cache.insert_read_value(&key, &Some(value));
1240 cache.check_coherence();
1241 }
1242
1243 assert!(cache.total_size <= cache.config.max_cache_size);
1245 assert!(cache.queue.len() <= cache.config.max_cache_entries);
1246 }
1247
1248 #[test]
1249 fn test_lru_eviction_by_entry_count() {
1250 let mut cache = create_test_cache(true);
1251
1252 for i in 0..15 {
1254 let key = vec![i];
1255 let value = vec![i]; cache.insert_read_value(&key, &Some(value));
1257 cache.check_coherence();
1258 }
1259
1260 assert!(cache.queue.len() <= cache.config.max_cache_entries);
1262 }
1263
1264 #[test]
1265 fn test_cache_entry_promotion() {
1266 let mut cache = create_test_cache(true);
1267 let key1 = vec![1];
1268 let key2 = vec![2];
1269 let key3 = vec![3];
1270 let value = vec![42];
1271
1272 cache.insert_read_value(&key1, &Some(value.clone()));
1274 cache.check_coherence();
1275 cache.insert_read_value(&key2, &Some(value.clone()));
1276 cache.check_coherence();
1277
1278 assert_eq!(Some(Some(value)), cache.query_read_value(&key1));
1280
1281 assert_eq!(None, cache.query_read_value(&key3));
1283
1284 let queue_keys = cache.queue.keys().collect::<Vec<_>>();
1286 assert_eq!(queue_keys[queue_keys.len() - 1], &CacheKey::Value(key1));
1287 }
1288
1289 #[test]
1290 fn test_update_find_entry_mut() {
1291 let mut cache = create_test_cache(true);
1292 let prefix = vec![1];
1293 let key = vec![1, 2];
1294 let original_keys = vec![vec![2], vec![3]];
1295
1296 cache.insert_find_keys(prefix.clone(), &original_keys);
1298 cache.check_coherence();
1299
1300 cache.put_key_value(&key, &[42]);
1302 cache.check_coherence();
1303
1304 let result = cache.query_find_keys(&prefix);
1306 assert!(result.is_some());
1307 let keys = result.unwrap();
1308 assert!(keys.contains(&vec![2]));
1309 }
1310
1311 #[test]
1312 fn test_delete_prefix_with_exclusive_access() {
1313 let mut cache = create_test_cache(true);
1314 let prefix = vec![1];
1315 let key1 = vec![1, 2];
1316 let key2 = vec![1, 3];
1317 let key3 = vec![2, 4]; let value = vec![42];
1319
1320 cache.insert_read_value(&key1, &Some(value.clone()));
1322 cache.check_coherence();
1323 cache.insert_read_value(&key2, &Some(value.clone()));
1324 cache.check_coherence();
1325 cache.insert_read_value(&key3, &Some(value.clone()));
1326 cache.check_coherence();
1327
1328 cache.delete_prefix(&prefix);
1330 cache.check_coherence();
1331
1332 let result1 = cache.query_read_value(&key1);
1334 assert_eq!(result1, Some(None));
1335
1336 let result2 = cache.query_read_value(&key2);
1337 assert_eq!(result2, Some(None));
1338
1339 let result3 = cache.query_read_value(&key3);
1341 assert_eq!(result3, Some(Some(value)));
1342 }
1343
1344 #[test]
1345 fn test_value_entry_size_limits() {
1346 let mut cache = create_test_cache(true);
1347 let key = vec![1];
1348 let large_value = vec![0; cache.config.max_value_entry_size + 1];
1349
1350 cache.insert_read_value(&key, &Some(large_value));
1353 cache.check_coherence();
1354
1355 let result = cache.query_read_value(&key);
1357 assert_eq!(result, None);
1358 }
1359
1360 #[test]
1361 fn test_findkeys_entry_size_limits() {
1362 let mut cache = create_test_cache(true);
1363 let key_prefix = vec![1];
1364 let mut keys = Vec::new();
1365 for i in 0..cache.config.max_find_keys_entry_size {
1366 keys.push(vec![i as u8]);
1367 }
1368 let size = keys.iter().map(Vec::len).sum::<usize>();
1369 assert_eq!(cache.config.max_find_keys_entry_size, size);
1370 cache.insert_find_keys(key_prefix.clone(), &keys);
1373 cache.check_coherence();
1374
1375 let result = cache.query_find_keys(&key_prefix);
1377 assert_eq!(result, None);
1378 }
1379
1380 #[test]
1381 fn test_findkeyvalues_entry_size_limits() {
1382 let mut cache = create_test_cache(true);
1383 let key_prefix = vec![1];
1384 let mut key_values = Vec::new();
1385 for i in 0..cache.config.max_find_key_values_entry_size / 2 {
1386 key_values.push((vec![i as u8], vec![i as u8]));
1387 }
1388 let size = key_values
1389 .iter()
1390 .map(|(k, v)| k.len() + v.len())
1391 .sum::<usize>();
1392 assert_eq!(cache.config.max_find_key_values_entry_size, size);
1393
1394 cache.insert_find_key_values(key_prefix.clone(), &key_values);
1396 cache.check_coherence();
1397
1398 let result = cache.query_find_key_values(&key_prefix);
1400 assert_eq!(result, None);
1401 }
1402
1403 #[test]
1404 fn test_does_not_exist_entry_without_exclusive_access() {
1405 let mut cache = create_test_cache(false);
1406 let key = vec![1];
1407
1408 cache.insert_read_value(&key, &None);
1410 cache.check_coherence();
1411
1412 let result = cache.query_read_value(&key);
1414 assert_eq!(result, None);
1415 }
1416
1417 #[test]
1418 fn test_find_keys_entry_operations() {
1419 let mut find_entry = FindKeysEntry(BTreeSet::new());
1420 let key1 = vec![1, 2];
1421 let key2 = vec![1, 3];
1422 let key3 = vec![1, 3, 4];
1423
1424 find_entry.update_entry(&key1, true);
1426 find_entry.update_entry(&key2, true);
1427
1428 assert!(find_entry.contains_key(&key1));
1430 assert!(find_entry.contains_key(&key2));
1431 assert!(!find_entry.contains_key(&key3));
1432 assert!(!find_entry.contains_key(&[9, 9]));
1433
1434 let keys = find_entry.get_keys_by_prefix(vec![1]);
1436 assert_eq!(keys.len(), 2);
1437 assert!(keys.contains(&vec![2]));
1438 assert!(keys.contains(&vec![3]));
1439
1440 find_entry.update_entry(&key1, false);
1442 assert!(!find_entry.contains_key(&key1));
1443 assert!(find_entry.contains_key(&key2));
1444 }
1445
1446 #[test]
1447 fn test_find_key_values_entry_operations() {
1448 let mut find_entry = FindKeyValuesEntry(BTreeMap::new());
1449 let key1 = vec![1, 2];
1450 let key2 = vec![1, 3];
1451 let value1 = vec![42];
1452 let value2 = vec![43];
1453
1454 find_entry.update_entry(&key1, Some(value1.clone()));
1456 find_entry.update_entry(&key2, Some(value2.clone()));
1457
1458 assert!(find_entry.contains_key(&key1));
1460 assert!(find_entry.contains_key(&key2));
1461
1462 assert_eq!(find_entry.get_read_value(&key1), Some(value1.clone()));
1464 assert_eq!(find_entry.get_read_value(&key2), Some(value2.clone()));
1465
1466 let key_values = find_entry.get_find_key_values(&[1]);
1468 assert_eq!(key_values.len(), 2);
1469 assert!(key_values.contains(&(vec![2], value1.clone())));
1470 assert!(key_values.contains(&(vec![3], value2.clone())));
1471
1472 find_entry.update_entry(&key1, None);
1474 assert!(!find_entry.contains_key(&key1));
1475 assert_eq!(find_entry.get_read_value(&key1), None);
1476 }
1477
1478 #[test]
1479 fn test_cache_size_tracking() {
1480 let mut cache = create_test_cache(true);
1481 let initial_size = cache.total_size;
1482 let initial_value_size = cache.total_value_size;
1483
1484 let key = vec![1, 2, 3];
1485 let value = vec![4, 5, 6];
1486 cache.insert_read_value(&key, &Some(value.clone()));
1487 cache.check_coherence();
1488
1489 assert!(cache.total_size > initial_size);
1491 assert!(cache.total_value_size > initial_value_size);
1492
1493 let value_size_with_entry = cache.total_value_size;
1494
1495 cache.insert_read_value(&key, &None);
1497 cache.check_coherence();
1498
1499 assert!(cache.total_value_size < value_size_with_entry);
1502 }
1503
1504 #[test]
1505 fn test_trim_value_cache() {
1506 let mut cache = LruPrefixCache::new(
1507 StorageCacheConfig {
1508 max_cache_size: 10000,
1509 max_value_entry_size: 500,
1510 max_find_keys_entry_size: 1000,
1511 max_find_key_values_entry_size: 2000,
1512 max_cache_entries: 100,
1513 max_cache_value_size: 50, max_cache_find_keys_size: 1000,
1515 max_cache_find_key_values_size: 1000,
1516 },
1517 true,
1518 );
1519
1520 for i in 0..10 {
1522 let key = vec![i];
1523 let value = vec![0; 20]; cache.insert_read_value(&key, &Some(value));
1525 cache.check_coherence();
1526 }
1527
1528 assert!(cache.total_value_size <= cache.config.max_cache_value_size);
1530 }
1531
1532 fn has_a_prefix_slow_method(prefixes: &BTreeSet<Vec<u8>>, key: &[u8]) -> bool {
1533 for prefix in prefixes {
1534 if key.starts_with(prefix) {
1535 return true;
1536 }
1537 }
1538 false
1539 }
1540
1541 fn has_a_prefix_fast_method(prefixes: &BTreeSet<Vec<u8>>, key: &[u8]) -> bool {
1542 match prefixes.range(..=key.to_vec()).next_back() {
1543 None => false,
1544 Some(prefix) => key.starts_with(prefix),
1545 }
1546 }
1547
1548 fn has_a_prefix(prefixes: &BTreeSet<Vec<u8>>, key: &[u8]) -> bool {
1549 let test1 = has_a_prefix_slow_method(prefixes, key);
1550 let test2 = has_a_prefix_fast_method(prefixes, key);
1551 assert_eq!(
1552 test1, test2,
1553 "The methods for testing prefix return different results"
1554 );
1555 test1
1556 }
1557
1558 fn get_prefix<R: Rng>(rng: &mut R, max_len: usize, entry_size: usize) -> Vec<u8> {
1559 let len = rng.gen_range(1..=max_len);
1560 let mut prefix = Vec::new();
1561 for _ in 0..len {
1562 let entry = rng.gen_range(0..entry_size);
1563 prefix.push(entry as u8);
1564 }
1565 prefix
1566 }
1567
1568 fn insert_into_prefix_set(prefixes: &mut BTreeSet<Vec<u8>>, new_prefix: Vec<u8>) {
1569 if has_a_prefix(prefixes, &new_prefix) {
1570 return;
1571 }
1572 let removed_keys1 = prefixes
1573 .range(get_key_range_for_prefix(new_prefix.clone()))
1574 .cloned()
1575 .collect::<BTreeSet<Vec<u8>>>();
1576 let mut removed_keys2 = BTreeSet::new();
1577 for prefix in prefixes.clone() {
1578 if prefix.starts_with(&new_prefix) {
1579 removed_keys2.insert(prefix);
1580 }
1581 }
1582 assert_eq!(
1583 removed_keys1, removed_keys2,
1584 "Inconsistent result of the computation of the intervals"
1585 );
1586 for prefix in removed_keys2 {
1587 prefixes.remove(&prefix);
1588 }
1589 prefixes.insert(new_prefix);
1590 }
1591
1592 fn test_prefix_free_set(max_len: usize, num_gen: usize, key_size: usize) {
1593 let mut rng = crate::random::make_deterministic_rng();
1594 let mut prefixes = BTreeSet::new();
1595 for _ in 0..num_gen {
1596 let new_prefix = get_prefix(&mut rng, max_len, key_size);
1597 insert_into_prefix_set(&mut prefixes, new_prefix);
1598 }
1599 }
1600
1601 #[test]
1606 fn test_lower_bounds() {
1607 test_prefix_free_set(10, 500, 2);
1608 test_prefix_free_set(6, 500, 3);
1609 test_prefix_free_set(5, 500, 4);
1610 }
1611
1612 #[test]
1613 fn test_delete_key_operations() {
1614 let mut cache = create_test_cache(true);
1615 let key1 = vec![1, 2, 3];
1616 let key2 = vec![1, 2, 4];
1617 let key3 = vec![2, 3, 4];
1618 let value = vec![42, 43, 44];
1619
1620 cache.put_key_value(&key1, &value);
1622 cache.check_coherence();
1623 cache.put_key_value(&key2, &value);
1624 cache.check_coherence();
1625 cache.put_key_value(&key3, &value);
1626 cache.check_coherence();
1627
1628 assert_eq!(cache.query_read_value(&key1), Some(Some(value.clone())));
1630 assert_eq!(cache.query_read_value(&key2), Some(Some(value.clone())));
1631 assert_eq!(cache.query_read_value(&key3), Some(Some(value.clone())));
1632
1633 cache.delete_key(&key1);
1635 cache.check_coherence();
1636
1637 assert_eq!(cache.query_read_value(&key1), Some(None));
1639 assert_eq!(cache.query_read_value(&key2), Some(Some(value.clone())));
1641 assert_eq!(cache.query_read_value(&key3), Some(Some(value.clone())));
1642
1643 cache.delete_key(&key2);
1645 cache.check_coherence();
1646
1647 assert_eq!(cache.query_read_value(&key2), Some(None));
1649 assert_eq!(cache.query_read_value(&key3), Some(Some(value)));
1651 }
1652
1653 #[test]
1654 fn test_find_key_values_entry_delete_prefix() {
1655 let mut find_entry = FindKeyValuesEntry(BTreeMap::new());
1656
1657 let key1 = vec![1, 2, 3];
1659 let key2 = vec![1, 2, 4];
1660 let key3 = vec![1, 3, 5];
1661 let key4 = vec![2, 4, 6];
1662 let value = vec![42];
1663
1664 find_entry.update_entry(&key1, Some(value.clone()));
1665 find_entry.update_entry(&key2, Some(value.clone()));
1666 find_entry.update_entry(&key3, Some(value.clone()));
1667 find_entry.update_entry(&key4, Some(value.clone()));
1668
1669 assert!(find_entry.contains_key(&key1));
1671 assert!(find_entry.contains_key(&key2));
1672 assert!(find_entry.contains_key(&key3));
1673 assert!(find_entry.contains_key(&key4));
1674
1675 find_entry.delete_prefix(&[1, 2]);
1677
1678 assert!(!find_entry.contains_key(&key1));
1680 assert!(!find_entry.contains_key(&key2));
1681 assert!(find_entry.contains_key(&key3));
1683 assert!(find_entry.contains_key(&key4));
1684
1685 find_entry.delete_prefix(&[1]);
1687
1688 assert!(!find_entry.contains_key(&key3));
1690 assert!(find_entry.contains_key(&key4));
1692 }
1693
1694 #[test]
1695 fn test_trim_value_cache_removes_entries() {
1696 let mut cache = LruPrefixCache::new(
1697 StorageCacheConfig {
1698 max_cache_size: 10000,
1699 max_value_entry_size: 500,
1700 max_find_keys_entry_size: 1000,
1701 max_find_key_values_entry_size: 2000,
1702 max_cache_entries: 100,
1703 max_cache_value_size: 30, max_cache_find_keys_size: 1000,
1705 max_cache_find_key_values_size: 1000,
1706 },
1707 true,
1708 );
1709
1710 let mut inserted_keys = Vec::new();
1712 for i in 0..6 {
1713 let key = vec![i];
1714 let value = vec![0; 10]; cache.insert_read_value(&key, &Some(value));
1716 cache.check_coherence();
1717 inserted_keys.push(key);
1718 }
1719
1720 assert!(cache.total_value_size <= cache.config.max_cache_value_size);
1722
1723 let mut remaining_count = 0;
1725 for key in &inserted_keys {
1726 if cache.query_read_value(key).is_some() {
1727 remaining_count += 1;
1728 }
1729 }
1730
1731 assert!(remaining_count < inserted_keys.len());
1733
1734 let last_key = &inserted_keys[inserted_keys.len() - 1];
1736 assert!(cache.query_read_value(last_key).is_some());
1737 }
1738
1739 #[test]
1740 fn test_max_value_entry_size_zero_early_termination() {
1741 let mut cache = LruPrefixCache::new(
1742 StorageCacheConfig {
1743 max_cache_size: 1000,
1744 max_value_entry_size: 0, max_find_keys_entry_size: 100,
1746 max_find_key_values_entry_size: 200,
1747 max_cache_entries: 10,
1748 max_cache_value_size: 500,
1749 max_cache_find_keys_size: 500,
1750 max_cache_find_key_values_size: 500,
1751 },
1752 true,
1753 );
1754
1755 let key1 = vec![1, 2, 3];
1756 let key2 = vec![4, 5, 6];
1757 let value = vec![42, 43, 44];
1758
1759 cache.insert_read_value(&key1, &Some(value.clone()));
1761 cache.check_coherence();
1762 cache.insert_read_value(&key2, &None);
1763 cache.check_coherence();
1764
1765 assert_eq!(cache.query_read_value(&key1), None);
1767 assert_eq!(cache.query_read_value(&key2), None);
1768
1769 assert_eq!(cache.total_size, 0);
1771 assert_eq!(cache.total_value_size, 0);
1772 assert!(cache.value_map.is_empty());
1773 assert!(cache.queue.is_empty());
1774
1775 cache.put_key_value(&key1, &value);
1777 cache.check_coherence();
1778
1779 assert_eq!(cache.query_read_value(&key1), None);
1780 assert_eq!(cache.total_size, 0);
1781
1782 cache.delete_key(&key1);
1784 cache.check_coherence();
1785
1786 assert_eq!(cache.query_read_value(&key1), None);
1787 assert_eq!(cache.total_size, 0);
1788 }
1789
1790 #[test]
1791 fn test_key_value_replacement_same_length() {
1792 let mut cache = create_test_cache(true);
1793 let key = vec![1, 2, 3];
1794 let value1 = vec![42, 43, 44]; let value2 = vec![99, 98, 97]; cache.put_key_value(&key, &value1);
1799 cache.check_coherence();
1800
1801 assert_eq!(cache.query_read_value(&key), Some(Some(value1.clone())));
1803
1804 let initial_size = cache.total_size;
1805 let initial_value_size = cache.total_value_size;
1806
1807 cache.put_key_value(&key, &value2);
1809 cache.check_coherence();
1810
1811 assert_eq!(cache.query_read_value(&key), Some(Some(value2.clone())));
1813
1814 assert_eq!(cache.total_size, initial_size);
1816 assert_eq!(cache.total_value_size, initial_value_size);
1817
1818 assert_eq!(cache.value_map.len(), 1);
1820 assert_eq!(cache.queue.len(), 1);
1821
1822 let value3 = vec![11, 22, 33]; cache.insert_read_value(&key, &Some(value3.clone()));
1825 cache.check_coherence();
1826
1827 assert_eq!(cache.query_read_value(&key), Some(Some(value3)));
1829
1830 assert_eq!(cache.total_size, initial_size);
1832 assert_eq!(cache.total_value_size, initial_value_size);
1833 }
1834
1835 #[test]
1836 fn test_max_find_keys_entry_size_zero_early_termination() {
1837 let mut cache = LruPrefixCache::new(
1838 StorageCacheConfig {
1839 max_cache_size: 1000,
1840 max_value_entry_size: 100,
1841 max_find_keys_entry_size: 0, max_find_key_values_entry_size: 200,
1843 max_cache_entries: 10,
1844 max_cache_value_size: 500,
1845 max_cache_find_keys_size: 500,
1846 max_cache_find_key_values_size: 500,
1847 },
1848 true,
1849 );
1850
1851 let prefix = vec![1, 2];
1852 let keys = vec![vec![3], vec![4], vec![5]];
1853
1854 cache.insert_find_keys(prefix.clone(), &keys);
1856 cache.check_coherence();
1857
1858 assert_eq!(cache.query_find_keys(&prefix), None);
1860
1861 assert_eq!(cache.total_find_keys_size, 0);
1863 assert!(cache.find_keys_map.is_empty());
1864
1865 for (cache_key, _) in &cache.queue {
1867 assert!(!matches!(cache_key, CacheKey::FindKeys(_)));
1868 }
1869
1870 let prefix2 = vec![9];
1872 let keys2 = vec![vec![1]];
1873 cache.insert_find_keys(prefix2.clone(), &keys2);
1874 cache.check_coherence();
1875
1876 assert_eq!(cache.query_find_keys(&prefix2), None);
1877 assert_eq!(cache.total_find_keys_size, 0);
1878 assert!(cache.find_keys_map.is_empty());
1879 }
1880
1881 #[test]
1882 fn test_max_find_key_values_entry_size_zero_early_termination() {
1883 let mut cache = LruPrefixCache::new(
1884 StorageCacheConfig {
1885 max_cache_size: 1000,
1886 max_value_entry_size: 100,
1887 max_find_keys_entry_size: 100,
1888 max_find_key_values_entry_size: 0, max_cache_entries: 10,
1890 max_cache_value_size: 500,
1891 max_cache_find_keys_size: 500,
1892 max_cache_find_key_values_size: 500,
1893 },
1894 true,
1895 );
1896
1897 let prefix = vec![1, 2];
1898 let key_values = vec![(vec![3], vec![10]), (vec![4], vec![20])];
1899
1900 cache.insert_find_key_values(prefix.clone(), &key_values);
1902 cache.check_coherence();
1903
1904 assert_eq!(cache.query_find_key_values(&prefix), None);
1906
1907 assert_eq!(cache.total_find_key_values_size, 0);
1909 assert!(cache.find_key_values_map.is_empty());
1910
1911 for (cache_key, _) in &cache.queue {
1913 assert!(!matches!(cache_key, CacheKey::FindKeyValues(_)));
1914 }
1915
1916 let prefix2 = vec![9];
1918 let key_values2 = vec![(vec![1], vec![100])];
1919 cache.insert_find_key_values(prefix2.clone(), &key_values2);
1920 cache.check_coherence();
1921
1922 assert_eq!(cache.query_find_key_values(&prefix2), None);
1923 assert_eq!(cache.total_find_key_values_size, 0);
1924 assert!(cache.find_key_values_map.is_empty());
1925 }
1926
1927 #[test]
1928 fn test_value_entry_exists_returns_none() {
1929 let mut cache = create_test_cache(true);
1930 let key = vec![1, 2, 3];
1931
1932 cache.insert_contains_key(&key, true);
1934 cache.check_coherence();
1935
1936 assert_eq!(cache.query_contains_key(&key), Some(true));
1938
1939 assert_eq!(cache.query_read_value(&key), None);
1942
1943 let key2 = vec![4, 5, 6];
1945 cache.insert_contains_key(&key2, false);
1946 cache.check_coherence();
1947
1948 assert_eq!(cache.query_contains_key(&key2), Some(false));
1950
1951 assert_eq!(cache.query_read_value(&key2), Some(None));
1953
1954 assert_eq!(cache.value_map.len(), 2);
1956 assert_eq!(cache.queue.len(), 2);
1957
1958 assert!(matches!(
1960 cache.value_map.get(&key),
1961 Some(ValueEntry::Exists)
1962 ));
1963 assert!(matches!(
1964 cache.value_map.get(&key2),
1965 Some(ValueEntry::DoesNotExist)
1966 ));
1967 }
1968
1969 #[test]
1970 fn test_find_keys_entry_delete_prefix_function() {
1971 let mut find_entry = FindKeysEntry(BTreeSet::new());
1972
1973 let key1 = vec![1, 2, 3];
1975 let key2 = vec![1, 2, 4];
1976 let key3 = vec![1, 3, 5];
1977 let key4 = vec![2, 4, 6];
1978
1979 find_entry.update_entry(&key1, true);
1980 find_entry.update_entry(&key2, true);
1981 find_entry.update_entry(&key3, true);
1982 find_entry.update_entry(&key4, true);
1983
1984 assert!(find_entry.contains_key(&key1));
1986 assert!(find_entry.contains_key(&key2));
1987 assert!(find_entry.contains_key(&key3));
1988 assert!(find_entry.contains_key(&key4));
1989 assert_eq!(find_entry.0.len(), 4);
1990
1991 find_entry.delete_prefix(&[1, 2]);
1993
1994 assert!(!find_entry.contains_key(&key1));
1996 assert!(!find_entry.contains_key(&key2));
1997 assert!(find_entry.contains_key(&key3));
1999 assert!(find_entry.contains_key(&key4));
2000 assert_eq!(find_entry.0.len(), 2);
2001
2002 find_entry.delete_prefix(&[1]);
2004
2005 assert!(!find_entry.contains_key(&key3));
2007 assert!(find_entry.contains_key(&key4));
2009 assert_eq!(find_entry.0.len(), 1);
2010
2011 find_entry.delete_prefix(&[]);
2013
2014 assert!(!find_entry.contains_key(&key4));
2016 assert_eq!(find_entry.0.len(), 0);
2017 }
2018
2019 #[test]
2020 fn test_find_keys_size_decrease() {
2021 let mut cache = create_test_cache(true);
2022 let prefix = vec![1];
2023 let initial_keys = vec![vec![2, 3, 4], vec![3, 4, 5]]; cache.insert_find_keys(prefix.clone(), &initial_keys);
2027 cache.check_coherence();
2028
2029 let initial_total_size = cache.total_size;
2030 let initial_find_keys_size = cache.total_find_keys_size;
2031
2032 let key_to_delete = vec![1, 2, 3, 4]; cache.delete_key(&key_to_delete);
2035 cache.check_coherence();
2036
2037 assert!(cache.total_size < initial_total_size);
2039 assert!(cache.total_find_keys_size < initial_find_keys_size);
2040
2041 let result = cache.query_find_keys(&prefix);
2043 assert!(result.is_some());
2044 let keys = result.unwrap();
2045 assert!(keys.contains(&vec![3, 4, 5])); assert!(!keys.contains(&vec![2, 3, 4])); cache.check_coherence();
2049 }
2050
2051 #[test]
2052 fn test_trim_find_keys_cache_lru_eviction() {
2053 let mut cache = LruPrefixCache::new(
2054 StorageCacheConfig {
2055 max_cache_size: 10000,
2056 max_value_entry_size: 500,
2057 max_find_keys_entry_size: 1000,
2058 max_find_key_values_entry_size: 2000,
2059 max_cache_entries: 100,
2060 max_cache_value_size: 5000,
2061 max_cache_find_keys_size: 50, max_cache_find_key_values_size: 5000,
2063 },
2064 true,
2065 );
2066
2067 let prefix1 = vec![1];
2069 let keys1 = vec![vec![2; 10], vec![3; 10]]; cache.insert_find_keys(prefix1.clone(), &keys1);
2071 cache.check_coherence();
2072
2073 let prefix2 = vec![2];
2075 let keys2 = vec![vec![4; 10], vec![5; 10]]; cache.insert_find_keys(prefix2.clone(), &keys2);
2077 cache.check_coherence();
2078
2079 assert!(cache.query_find_keys(&prefix1).is_some());
2081 assert!(cache.query_find_keys(&prefix2).is_some());
2082
2083 let prefix3 = vec![3];
2085 let keys3 = vec![vec![6; 10], vec![7; 10]]; cache.insert_find_keys(prefix3.clone(), &keys3);
2087 cache.check_coherence();
2088
2089 assert!(cache.total_find_keys_size <= cache.config.max_cache_find_keys_size);
2091
2092 assert_eq!(cache.query_find_keys(&prefix1), None);
2094
2095 assert!(cache.query_find_keys(&prefix2).is_some());
2097 assert!(cache.query_find_keys(&prefix3).is_some());
2098
2099 assert!(cache.find_keys_map.len() < 3);
2101 }
2102
2103 #[test]
2104 fn test_find_keys_removal_from_map() {
2105 let mut cache = LruPrefixCache::new(
2106 StorageCacheConfig {
2107 max_cache_size: 100, max_value_entry_size: 50,
2109 max_find_keys_entry_size: 1000,
2110 max_find_key_values_entry_size: 2000,
2111 max_cache_entries: 3, max_cache_value_size: 500,
2113 max_cache_find_keys_size: 500,
2114 max_cache_find_key_values_size: 500,
2115 },
2116 true,
2117 );
2118
2119 let prefix1 = vec![1];
2120 let prefix2 = vec![2];
2121 let prefix3 = vec![3];
2122 let keys = vec![vec![1], vec![2]];
2123
2124 cache.insert_find_keys(prefix1.clone(), &keys);
2126 cache.check_coherence();
2127 cache.insert_find_keys(prefix2.clone(), &keys);
2128 cache.check_coherence();
2129
2130 assert!(cache.find_keys_map.contains_key(&prefix1));
2132 assert!(cache.find_keys_map.contains_key(&prefix2));
2133
2134 cache.insert_find_keys(prefix3.clone(), &keys);
2136 cache.check_coherence();
2137
2138 assert!(!cache.find_keys_map.contains_key(&prefix1));
2140 assert!(cache.find_keys_map.contains_key(&prefix2));
2142 assert!(cache.find_keys_map.contains_key(&prefix3));
2143
2144 assert!(cache.queue.len() <= cache.config.max_cache_entries);
2146 }
2147
2148 #[test]
2149 fn test_find_key_values_removal_from_map() {
2150 let mut cache = LruPrefixCache::new(
2151 StorageCacheConfig {
2152 max_cache_size: 100, max_value_entry_size: 50,
2154 max_find_keys_entry_size: 1000,
2155 max_find_key_values_entry_size: 2000,
2156 max_cache_entries: 3, max_cache_value_size: 500,
2158 max_cache_find_keys_size: 500,
2159 max_cache_find_key_values_size: 500,
2160 },
2161 true,
2162 );
2163
2164 let prefix1 = vec![1];
2165 let prefix2 = vec![2];
2166 let prefix3 = vec![3];
2167 let key_values = vec![(vec![1], vec![10]), (vec![2], vec![20])];
2168
2169 cache.insert_find_key_values(prefix1.clone(), &key_values);
2171 cache.check_coherence();
2172 cache.insert_find_key_values(prefix2.clone(), &key_values);
2173 cache.check_coherence();
2174
2175 assert!(cache.find_key_values_map.contains_key(&prefix1));
2177 assert!(cache.find_key_values_map.contains_key(&prefix2));
2178
2179 cache.insert_find_key_values(prefix3.clone(), &key_values);
2181 cache.check_coherence();
2182
2183 assert!(!cache.find_key_values_map.contains_key(&prefix1));
2185 assert!(cache.find_key_values_map.contains_key(&prefix2));
2187 assert!(cache.find_key_values_map.contains_key(&prefix3));
2188
2189 assert!(cache.queue.len() <= cache.config.max_cache_entries);
2191 }
2192
2193 #[test]
2194 fn test_contains_key_failing_without_exclusive_access() {
2195 let mut cache = create_test_cache(false); let key = vec![1, 2, 3];
2197
2198 let result = cache.query_contains_key(&key);
2201 assert_eq!(result, None);
2202
2203 cache.insert_contains_key(&key, true);
2205 cache.check_coherence();
2206
2207 let result = cache.query_contains_key(&key);
2209 assert_eq!(result, Some(true));
2210 }
2211
2212 #[test]
2213 fn test_contains_key_found_in_find_key_values() {
2214 let mut cache = create_test_cache(true); let prefix = vec![1, 2];
2216 let key = vec![1, 2, 3, 4];
2217 let key_values = vec![(vec![3, 4], vec![100]), (vec![5, 6], vec![200])];
2218
2219 cache.insert_find_key_values(prefix.clone(), &key_values);
2221 cache.check_coherence();
2222
2223 let result = cache.query_contains_key(&key);
2225 assert_eq!(result, Some(true));
2226
2227 let non_existent_key = vec![1, 2, 7, 8];
2229 let result = cache.query_contains_key(&non_existent_key);
2230 assert_eq!(result, Some(false)); let unmatched_key = vec![9, 9, 9];
2234 let result = cache.query_contains_key(&unmatched_key);
2235 assert_eq!(result, None); }
2237
2238 #[test]
2239 fn test_find_keys_removal_when_inserting_broader_find_keys() {
2240 let mut cache = create_test_cache(true);
2241
2242 let specific_prefix = vec![1, 2, 3, 4];
2244 let keys2 = vec![vec![6], vec![7]];
2245 cache.insert_find_keys(specific_prefix.clone(), &keys2);
2246 cache.check_coherence();
2247
2248 let narrow_prefix = vec![1, 2, 3];
2250 let keys1 = vec![vec![4, 6], vec![4, 7]];
2251 cache.insert_find_keys(narrow_prefix.clone(), &keys1);
2252 cache.check_coherence();
2253 }
2254
2255 #[test]
2256 fn test_overlapping_find_key_values_removes_find_keys_and_find_key_values() {
2257 let mut cache = create_test_cache(true);
2258
2259 let find_keys_prefix = vec![1, 2, 3];
2261 let keys = vec![vec![4, 6], vec![4, 7], vec![5]];
2262 cache.insert_find_keys(find_keys_prefix.clone(), &keys);
2263 cache.check_coherence();
2264
2265 let find_key_values_prefix = vec![1, 2, 3, 4];
2267 let key_values1 = vec![(vec![6], vec![10]), (vec![7], vec![20])];
2268 cache.insert_find_key_values(find_key_values_prefix.clone(), &key_values1);
2269 cache.check_coherence();
2270
2271 cache.put_key_value(&[1, 2, 8, 9], &[254]);
2273 cache.check_coherence();
2274
2275 let broad_prefix = vec![1, 2];
2277 let key_values2 = vec![
2278 (vec![3, 4, 6], vec![10]),
2279 (vec![3, 4, 7], vec![20]),
2280 (vec![3, 5], vec![34]),
2281 (vec![8, 9], vec![254]),
2282 ];
2283 cache.insert_find_key_values(broad_prefix.clone(), &key_values2);
2284 cache.check_coherence();
2285
2286 assert!(!cache.find_keys_map.contains_key(&find_keys_prefix));
2288
2289 assert!(!cache
2291 .find_key_values_map
2292 .contains_key(&find_key_values_prefix));
2293
2294 assert!(cache.find_key_values_map.contains_key(&broad_prefix));
2296
2297 let key_values = cache.query_find_key_values(&broad_prefix).unwrap();
2299 assert!(key_values.contains(&(vec![3, 4, 6], vec![10])));
2300 assert!(key_values.contains(&(vec![3, 4, 7], vec![20])));
2301 assert!(key_values.contains(&(vec![8, 9], vec![254])));
2302
2303 let query_result = cache.query_contains_key(&[1, 2, 3, 1]);
2305 assert_eq!(query_result, Some(false)); }
2307
2308 #[test]
2309 fn test_delete_prefix_removes_entire_find_keys_entry() {
2310 let mut cache = create_test_cache(true); let prefix = vec![1, 2, 3];
2314 let keys = vec![vec![4], vec![5], vec![6]];
2315 cache.insert_find_keys(prefix.clone(), &keys);
2316 cache.check_coherence();
2317
2318 assert!(cache.find_keys_map.contains_key(&prefix));
2320 let result = cache.query_find_keys(&prefix);
2321 assert!(result.is_some());
2322
2323 let delete_prefix = vec![1, 2]; cache.delete_prefix(&delete_prefix);
2326 cache.check_coherence();
2327
2328 let result = cache.query_find_keys(&prefix);
2330 assert_eq!(result, Some(vec![]));
2331
2332 for (cache_key, _) in &cache.queue {
2334 assert!(!matches!(cache_key, CacheKey::FindKeys(key) if key == &prefix));
2335 }
2336 }
2337
2338 #[test]
2339 fn test_delete_prefix_removes_keys_within_find_keys_entry() {
2340 let mut cache = create_test_cache(true); let find_keys_prefix = vec![1];
2344 let keys = vec![vec![2, 3, 4], vec![2, 3, 5], vec![2, 4, 6], vec![3, 7, 8]];
2345 cache.insert_find_keys(find_keys_prefix.clone(), &keys);
2346 cache.check_coherence();
2347
2348 assert!(cache.find_keys_map.contains_key(&find_keys_prefix));
2350 let initial_keys = cache.query_find_keys(&find_keys_prefix).unwrap();
2351 assert!(initial_keys.contains(&vec![2, 3, 4]));
2352 assert!(initial_keys.contains(&vec![2, 3, 5]));
2353 assert!(initial_keys.contains(&vec![2, 4, 6]));
2354 assert!(initial_keys.contains(&vec![3, 7, 8]));
2355
2356 let initial_size = cache.total_find_keys_size;
2357
2358 let delete_prefix = vec![1, 2, 3]; cache.delete_prefix(&delete_prefix);
2361 cache.check_coherence();
2362
2363 assert!(cache.find_keys_map.contains_key(&find_keys_prefix));
2365
2366 let remaining_keys = cache.query_find_keys(&find_keys_prefix).unwrap();
2368 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);
2375
2376 let delete_prefix2 = vec![1, 2]; cache.delete_prefix(&delete_prefix2);
2379 cache.check_coherence();
2380
2381 let final_keys = cache.query_find_keys(&find_keys_prefix).unwrap();
2383 assert!(!final_keys.contains(&vec![2, 4, 6])); assert!(final_keys.contains(&vec![3, 7, 8])); }
2386
2387 #[test]
2388 fn test_put_key_value_without_find_key_values_match() {
2389 let mut cache = create_test_cache(false); let key = vec![1, 2, 3, 4];
2391 let value = vec![100, 200];
2392
2393 cache.put_key_value(&key, &value);
2395 cache.check_coherence();
2396
2397 assert_eq!(cache.query_read_value(&key), Some(Some(value.clone())));
2399 assert!(cache.value_map.contains_key(&key));
2400 }
2401
2402 #[test]
2403 fn test_delete_key_without_exclusive_access() {
2404 let mut cache = create_test_cache(false); let key = vec![1, 2, 3];
2406 let value = vec![42, 43, 44];
2407
2408 cache.insert_read_value(&key, &Some(value.clone()));
2410 cache.check_coherence();
2411
2412 assert_eq!(cache.query_read_value(&key), Some(Some(value)));
2414 assert!(cache.value_map.contains_key(&key));
2415
2416 cache.delete_key(&key);
2419 cache.check_coherence();
2420
2421 assert!(!cache.value_map.contains_key(&key));
2423 assert_eq!(cache.query_read_value(&key), None);
2424
2425 for (cache_key, _) in &cache.queue {
2427 assert!(!matches!(cache_key, CacheKey::Value(k) if k == &key));
2428 }
2429
2430 let non_existent_key = vec![9, 9, 9];
2432 cache.delete_key(&non_existent_key); cache.check_coherence();
2434 }
2435
2436 #[test]
2437 fn test_line_502_insert_then_delete_without_exclusive_access() {
2438 let mut cache = create_test_cache(false); let key = vec![1, 2, 3, 4];
2440 let value = vec![100, 200, 201];
2441
2442 cache.insert_read_value(&key, &Some(value.clone()));
2444 cache.check_coherence();
2445
2446 assert_eq!(cache.query_read_value(&key), Some(Some(value)));
2448 assert!(cache.value_map.contains_key(&key));
2449
2450 cache.insert_read_value(&key, &None);
2453 cache.check_coherence();
2454
2455 assert!(!cache.value_map.contains_key(&key));
2457 assert_eq!(cache.query_read_value(&key), None);
2458
2459 let queue_contains_key = cache
2461 .queue
2462 .iter()
2463 .any(|(cache_key, _)| matches!(cache_key, CacheKey::Value(k) if k == &key));
2464 assert!(!queue_contains_key);
2465 }
2466
2467 #[test]
2468 fn test_does_not_exist_removal_during_insert_find_keys() {
2469 let mut cache = create_test_cache(true); let prefix = vec![1, 2];
2471 let key1 = vec![1, 2, 3];
2472 let key2 = vec![1, 2, 4];
2473 let key3 = vec![1, 2, 5];
2474
2475 cache.insert_read_value(&key1, &None); cache.insert_read_value(&key2, &None); cache.insert_read_value(&key3, &Some(vec![100])); cache.check_coherence();
2480
2481 assert_eq!(cache.query_read_value(&key1), Some(None));
2483 assert_eq!(cache.query_read_value(&key2), Some(None));
2484 assert_eq!(cache.query_read_value(&key3), Some(Some(vec![100])));
2485 assert!(cache.value_map.contains_key(&key1));
2486 assert!(cache.value_map.contains_key(&key2));
2487 assert!(cache.value_map.contains_key(&key3));
2488
2489 let find_keys_result = vec![key1.clone(), key2.clone(), key3.clone()];
2492 cache.insert_find_keys(prefix.clone(), &find_keys_result);
2493 cache.check_coherence();
2494
2495 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));
2501 assert!(!cache.value_map.contains_key(&key2));
2502 assert!(cache.value_map.contains_key(&key3)); assert_eq!(cache.query_find_keys(&prefix), Some(find_keys_result));
2506 }
2507
2508 #[test]
2509 fn test_trim_value_cache_complete_iteration() {
2510 let mut cache = create_test_cache(true);
2511
2512 let key1 = vec![1, 2, 3];
2514 let key2 = vec![4, 5, 6];
2515 let value1 = vec![100, 200];
2516 let value2 = vec![203, 177];
2517
2518 cache.insert_read_value(&key1, &Some(value1));
2519 cache.insert_read_value(&key2, &Some(value2));
2520 cache.check_coherence();
2521
2522 cache.config.max_cache_value_size = 0;
2524
2525 cache.trim_value_cache();
2528 cache.check_coherence();
2529
2530 assert!(!cache.value_map.contains_key(&key1));
2532 assert!(!cache.value_map.contains_key(&key2));
2533 }
2534
2535 #[test]
2536 fn test_trim_find_keys_cache_complete_iteration() {
2537 let mut cache = create_test_cache(true);
2538
2539 let prefix1 = vec![1, 2];
2541 let prefix2 = vec![3, 4];
2542 let keys1 = vec![vec![1, 2, 3], vec![1, 2, 4]];
2543 let keys2 = vec![vec![3, 4, 5], vec![3, 4, 6]];
2544
2545 cache.insert_find_keys(prefix1, &keys1);
2546 cache.insert_find_keys(prefix2, &keys2);
2547 cache.check_coherence();
2548
2549 cache.config.max_cache_find_keys_size = 0;
2551
2552 cache.trim_find_keys_cache();
2555 cache.check_coherence();
2556
2557 assert!(cache.find_keys_map.is_empty());
2559 }
2560
2561 #[test]
2562 fn test_trim_find_key_values_cache_complete_iteration() {
2563 let mut cache = create_test_cache(true);
2564
2565 let prefix1 = vec![1, 2];
2567 let prefix2 = vec![3, 4];
2568 let key_values1 = vec![(vec![1, 2, 3], vec![100]), (vec![1, 2, 4], vec![200])];
2569 let key_values2 = vec![(vec![3, 4, 5], vec![203]), (vec![3, 4, 6], vec![177])];
2570
2571 cache.insert_find_key_values(prefix1, &key_values1);
2572 cache.insert_find_key_values(prefix2, &key_values2);
2573 cache.check_coherence();
2574
2575 cache.config.max_cache_find_key_values_size = 0;
2577
2578 cache.trim_find_key_values_cache();
2581 cache.check_coherence();
2582
2583 assert!(cache.find_key_values_map.is_empty());
2585 }
2586
2587 #[test]
2588 fn test_trim_cache_breaks_on_empty_queue() {
2589 let mut cache = LruPrefixCache::new(
2590 StorageCacheConfig {
2591 max_cache_size: 10000, max_value_entry_size: 10000, max_find_keys_entry_size: 10000,
2594 max_find_key_values_entry_size: 10000,
2595 max_cache_entries: 10,
2596 max_cache_value_size: 500,
2597 max_cache_find_keys_size: 500,
2598 max_cache_find_key_values_size: 500,
2599 },
2600 true,
2601 );
2602
2603 for i in 0..10 {
2605 let key = vec![1, 2, i];
2606 let value = vec![100 + i];
2607 cache.insert_read_value(&key, &Some(value));
2608 cache.check_coherence();
2609 }
2610
2611 cache.config.max_cache_size = 0;
2613
2614 let key = vec![1, 2];
2616 let value = vec![100];
2617 cache.insert_read_value(&key, &Some(value));
2618 cache.check_coherence();
2619 }
2620}