zeitgeist icon indicating copy to clipboard operation
zeitgeist copied to clipboard

Research performance cost of duplicate reads and implement a solution if necessary

Open maltekliemann opened this issue 1 year ago • 0 comments

Storage overlay prevents the worst effects of double reads, but the official suggestion is still to avoid excessive use of this feature: https://substrate.stackexchange.com/questions/2574/clarity-on-storage-read-write-caching.

My suggestion is to use the following design:

type DbReader<K, V> = dyn Fn(K) -> Result<V, Box<dyn std::error::Error>> + Send + Sync;

struct Lazy<K, V> {
    key: K,
    object: OnceCell<V>,
    db_reader: Box<DbReader<K, V>>,
}

impl<K: Copy, V> Lazy<K, V> {
    fn new(key: K, db_reader: Box<DbReader<K, V>>) -> Self {
        Lazy {
            key,
            object: OnceCell::new(),
            db_reader,
        }
    }

    fn get(&self) -> Result<&V, Box<dyn std::error::Error>> {
        self.object.get_or_try_init(|| (self.db_reader)(self.key))
    }
}

You can even implement Into<Lazy<MarketId, Market>> for MarketId. All helper and do_* functions should take a wrapped Lazy object.

maltekliemann avatar Aug 21 '23 11:08 maltekliemann