sui_core/
fallback_fetch.rs

1// Copyright (c) 2021, Facebook, Inc. and its affiliates
2// Copyright (c) Mysten Labs, Inc.
3// SPDX-License-Identifier: Apache-2.0
4
5use crate::execution_cache::cache_types::CacheResult;
6use sui_types::error::SuiResult;
7
8/// do_fallback_lookup is a helper function for multi-get operations.
9/// It takes a list of keys and first attempts to look up each key in the cache.
10/// The cache can return a hit, a miss, or a negative hit (if the object is known to not exist).
11/// Any keys that result in a miss are then looked up in the store.
12///
13/// The "get from cache" and "get from store" behavior are implemented by the caller and provided
14/// via the get_cached_key and multiget_fallback functions.
15pub 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}