1 use std::num::NonZeroUsize; 2 use std::sync::atomic::{AtomicUsize, Ordering}; 3 4 /// Value of the initial revision, as a u64. We don't use 0 5 /// because we want to use a `NonZeroUsize`. 6 const START: usize = 1; 7 8 /// A unique identifier for the current version of the database; each 9 /// time an input is changed, the revision number is incremented. 10 /// `Revision` is used internally to track which values may need to be 11 /// recomputed, but is not something you should have to interact with 12 /// directly as a user of salsa. 13 #[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] 14 pub struct Revision { 15 generation: NonZeroUsize, 16 } 17 18 impl Revision { start() -> Self19 pub(crate) fn start() -> Self { 20 Self::from(START) 21 } 22 from(g: usize) -> Self23 pub(crate) fn from(g: usize) -> Self { 24 Self { 25 generation: NonZeroUsize::new(g).unwrap(), 26 } 27 } 28 next(self) -> Revision29 pub(crate) fn next(self) -> Revision { 30 Self::from(self.generation.get() + 1) 31 } 32 as_usize(self) -> usize33 fn as_usize(self) -> usize { 34 self.generation.get() 35 } 36 } 37 38 impl std::fmt::Debug for Revision { fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result39 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 40 write!(fmt, "R{}", self.generation) 41 } 42 } 43 44 #[derive(Debug)] 45 pub(crate) struct AtomicRevision { 46 data: AtomicUsize, 47 } 48 49 impl AtomicRevision { start() -> Self50 pub(crate) fn start() -> Self { 51 Self { 52 data: AtomicUsize::new(START), 53 } 54 } 55 load(&self) -> Revision56 pub(crate) fn load(&self) -> Revision { 57 Revision::from(self.data.load(Ordering::SeqCst)) 58 } 59 store(&self, r: Revision)60 pub(crate) fn store(&self, r: Revision) { 61 self.data.store(r.as_usize(), Ordering::SeqCst); 62 } 63 64 /// Increment by 1, returning previous value. fetch_then_increment(&self) -> Revision65 pub(crate) fn fetch_then_increment(&self) -> Revision { 66 let v = self.data.fetch_add(1, Ordering::SeqCst); 67 assert!(v != usize::max_value(), "revision overflow"); 68 Revision::from(v) 69 } 70 } 71