sui_core/
fallback_fetch.rs1use crate::execution_cache::cache_types::CacheResult;
6use sui_types::error::SuiResult;
7
8pub fn do_fallback_lookup<K: Clone, V: Default + Clone>(
16    keys: &[K],
17    get_cached_key: impl Fn(&K) -> CacheResult<V>,
18    multiget_fallback: impl Fn(&[K]) -> Vec<V>,
19) -> Vec<V> {
20    do_fallback_lookup_fallible(
21        keys,
22        |key| Ok(get_cached_key(key)),
23        |keys| Ok(multiget_fallback(keys)),
24    )
25    .expect("cannot fail")
26}
27
28pub fn do_fallback_lookup_fallible<K: Clone, V: Default + Clone>(
29    keys: &[K],
30    get_cached_key: impl Fn(&K) -> SuiResult<CacheResult<V>>,
31    multiget_fallback: impl Fn(&[K]) -> SuiResult<Vec<V>>,
32) -> SuiResult<Vec<V>> {
33    let mut results = vec![V::default(); keys.len()];
34    let mut fallback_keys = Vec::with_capacity(keys.len());
35    let mut fallback_indices = Vec::with_capacity(keys.len());
36
37    for (i, key) in keys.iter().enumerate() {
38        match get_cached_key(key)? {
39            CacheResult::Miss => {
40                fallback_keys.push(key.clone());
41                fallback_indices.push(i);
42            }
43            CacheResult::NegativeHit => (),
44            CacheResult::Hit(value) => {
45                results[i] = value;
46            }
47        }
48    }
49
50    let fallback_results = multiget_fallback(&fallback_keys)?;
51    assert_eq!(fallback_results.len(), fallback_indices.len());
52    assert_eq!(fallback_results.len(), fallback_keys.len());
53
54    for (i, result) in fallback_indices
55        .into_iter()
56        .zip(fallback_results.into_iter())
57    {
58        results[i] = result;
59    }
60    Ok(results)
61}