Struct stateright::semantics::LinearizabilityTester
source · pub struct LinearizabilityTester<ThreadId, RefObj: SequentialSpec> { /* private fields */ }
Expand description
This tester captures a potentially concurrent history of operations and
validates that it adheres to a SequentialSpec
based on the
linearizability consistency model. This model requires that operations be
applied atomically and that sequenced (non-concurrent) operations are
applied in order.
If you’re not sure whether to pick this or SequentialConsistencyTester
, favor
LinearizabilityTester
.
Linearizability
Unlike with sequential consistency, all sequenced (non-concurrent) operations must respect a happens-before relationship, even across threads, which ensures that histories respect “real time” ordering (defined more precisely below). Anomalies are prevented because threads all agree on the viable order of operations. For example, the later read by Thread 2 must read the value of Thread 1’s write (rather than a differing earlier value) since those two operations are not concurrent:
-----------Time------------------------------>
Thread 1: [write invoked... and returns]
Thread 2: [read invoked... and returns]
While “real time” is a common way to phrase an implicit total ordering on non-concurrent events spanning threads, a more precise way to think about this is that prior to Thread 2 starting its read, Thread 1 is capable of communicating with Thread 2 indicating that the write finished. This perspective avoids introducing the notion of a shared global time, which is often a misleading perspective when it comes to distributed systems (or even modern physics in general).
The SequentialSpec
will imply additional ordering constraints based on semantics specific
to each operation. For example, a value cannot be popped off a stack before it is pushed. It is
then the responsibility of this tester to establish whether a valid total ordering of events
exists under these constraints.
See also: SequentialConsistencyTester
.
Implementations§
source§impl<T: Ord, RefObj: SequentialSpec> LinearizabilityTester<T, RefObj>
impl<T: Ord, RefObj: SequentialSpec> LinearizabilityTester<T, RefObj>
Trait Implementations§
source§impl<ThreadId: Clone, RefObj: Clone + SequentialSpec> Clone for LinearizabilityTester<ThreadId, RefObj>where
RefObj::Op: Clone,
RefObj::Ret: Clone,
impl<ThreadId: Clone, RefObj: Clone + SequentialSpec> Clone for LinearizabilityTester<ThreadId, RefObj>where RefObj::Op: Clone, RefObj::Ret: Clone,
source§fn clone(&self) -> LinearizabilityTester<ThreadId, RefObj>
fn clone(&self) -> LinearizabilityTester<ThreadId, RefObj>
1.0.0 · source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source
. Read moresource§impl<T, RefObj> ConsistencyTester<T, RefObj> for LinearizabilityTester<T, RefObj>where
T: Copy + Debug + Ord,
RefObj: Clone + SequentialSpec,
RefObj::Op: Clone + Debug,
RefObj::Ret: Clone + Debug + PartialEq,
impl<T, RefObj> ConsistencyTester<T, RefObj> for LinearizabilityTester<T, RefObj>where T: Copy + Debug + Ord, RefObj: Clone + SequentialSpec, RefObj::Op: Clone + Debug, RefObj::Ret: Clone + Debug + PartialEq,
source§fn on_invoke(
&mut self,
thread_id: T,
op: RefObj::Op
) -> Result<&mut Self, String>
fn on_invoke( &mut self, thread_id: T, op: RefObj::Op ) -> Result<&mut Self, String>
Indicates that a thread invoked an operation. Returns Ok(...)
if the
history is valid, even if it is not lineariable.
source§fn on_return(
&mut self,
thread_id: T,
ret: RefObj::Ret
) -> Result<&mut Self, String>
fn on_return( &mut self, thread_id: T, ret: RefObj::Ret ) -> Result<&mut Self, String>
Indicates that a thread’s earlier operation invocation returned. Returns
Ok(...)
if the history is valid, even if it is not linearizable.
source§fn is_consistent(&self) -> bool
fn is_consistent(&self) -> bool
Indicates whether the recorded history is linearizable.
source§impl<ThreadId: Debug, RefObj: Debug + SequentialSpec> Debug for LinearizabilityTester<ThreadId, RefObj>where
RefObj::Op: Debug,
RefObj::Ret: Debug,
impl<ThreadId: Debug, RefObj: Debug + SequentialSpec> Debug for LinearizabilityTester<ThreadId, RefObj>where RefObj::Op: Debug, RefObj::Ret: Debug,
source§impl<T: Ord, RefObj> Default for LinearizabilityTester<T, RefObj>where
RefObj: Default + SequentialSpec,
impl<T: Ord, RefObj> Default for LinearizabilityTester<T, RefObj>where RefObj: Default + SequentialSpec,
source§impl<ThreadId: Hash, RefObj: Hash + SequentialSpec> Hash for LinearizabilityTester<ThreadId, RefObj>where
RefObj::Op: Hash,
RefObj::Ret: Hash,
impl<ThreadId: Hash, RefObj: Hash + SequentialSpec> Hash for LinearizabilityTester<ThreadId, RefObj>where RefObj::Op: Hash, RefObj::Ret: Hash,
source§impl<ThreadId: PartialEq, RefObj: PartialEq + SequentialSpec> PartialEq<LinearizabilityTester<ThreadId, RefObj>> for LinearizabilityTester<ThreadId, RefObj>where
RefObj::Op: PartialEq,
RefObj::Ret: PartialEq,
impl<ThreadId: PartialEq, RefObj: PartialEq + SequentialSpec> PartialEq<LinearizabilityTester<ThreadId, RefObj>> for LinearizabilityTester<ThreadId, RefObj>where RefObj::Op: PartialEq, RefObj::Ret: PartialEq,
source§fn eq(&self, other: &LinearizabilityTester<ThreadId, RefObj>) -> bool
fn eq(&self, other: &LinearizabilityTester<ThreadId, RefObj>) -> bool
self
and other
values to be equal, and is used
by ==
.