1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
use crate::uses::*; pub trait Fetcher<K, T> { fn get(&self, _: K) -> &T; fn take(&self, _: K) -> T; } pub struct Prefetched<'a, K, T, M: Fetcher<K, T>> { s: UnsafeCell<mSelf<'a, K, T, M>>, } enum mSelf<'a, K, T, M: Fetcher<K, T>> { Started(Box<Option<(K, &'a M)>>), Done(&'a T), } impl<'a, K, T, M: Fetcher<K, T>> Prefetched<'a, K, T, M> { pub fn new(k: K, m: &'a M) -> Self { Self { s: UnsafeCell::new(Started(Box::new(Some((k, m))))), } } pub fn get(&self) -> &T { let s = unsafe { &mut *self.s.get() }; match s { Done(v) => v, Started(b) => { let (k, m) = b.take().unwrap(); let v = m.get(k); *s = Done(v); v } } } pub fn take(self) -> T { let s = self.s.into_inner(); match s { Done(_) => ASSERT!(false, "Batched value already borrowed, can't take"), Started(b) => { let (k, m) = b.unwrap(); m.take(k) } } } } use mSelf::{Done, Started};