@@ -4,7 +4,7 @@ use smallvec::SmallVec;
44use std:: {
55 cmp:: Ordering ,
66 fmt:: Debug ,
7- ops:: { Index , IndexMut , Shr } ,
7+ ops:: { Index , Shr } ,
88} ;
99
1010use super :: data_race:: NaReadType ;
@@ -92,7 +92,7 @@ impl VTimestamp {
9292 }
9393
9494 #[ inline]
95- pub fn set_read_type ( & mut self , read_type : NaReadType ) {
95+ pub ( super ) fn set_read_type ( & mut self , read_type : NaReadType ) {
9696 self . time_and_read_type = Self :: encode_time_and_read_type ( self . time ( ) , read_type) ;
9797 }
9898
@@ -138,7 +138,7 @@ pub struct VClock(SmallVec<[VTimestamp; SMALL_VECTOR]>);
138138impl VClock {
139139 /// Create a new vector-clock containing all zeros except
140140 /// for a value at the given index
141- pub fn new_with_index ( index : VectorIdx , timestamp : VTimestamp ) -> VClock {
141+ pub ( super ) fn new_with_index ( index : VectorIdx , timestamp : VTimestamp ) -> VClock {
142142 let len = index. index ( ) + 1 ;
143143 let mut vec = smallvec:: smallvec![ VTimestamp :: ZERO ; len] ;
144144 vec[ index. index ( ) ] = timestamp;
@@ -147,10 +147,16 @@ impl VClock {
147147
148148 /// Load the internal timestamp slice in the vector clock
149149 #[ inline]
150- pub fn as_slice ( & self ) -> & [ VTimestamp ] {
150+ pub ( super ) fn as_slice ( & self ) -> & [ VTimestamp ] {
151+ debug_assert ! ( !self . 0 . last( ) . is_some_and( |t| t. time( ) == 0 ) ) ;
151152 self . 0 . as_slice ( )
152153 }
153154
155+ #[ inline]
156+ pub ( super ) fn index_mut ( & mut self , index : VectorIdx ) -> & mut VTimestamp {
157+ self . 0 . as_mut_slice ( ) . get_mut ( index. to_u32 ( ) as usize ) . unwrap ( )
158+ }
159+
154160 /// Get a mutable slice to the internal vector with minimum `min_len`
155161 /// elements. To preserve invariants, the caller must modify
156162 /// the `min_len`-1 nth element to a non-zero value
@@ -166,7 +172,7 @@ impl VClock {
166172 /// Increment the vector clock at a known index
167173 /// this will panic if the vector index overflows
168174 #[ inline]
169- pub fn increment_index ( & mut self , idx : VectorIdx , current_span : Span ) {
175+ pub ( super ) fn increment_index ( & mut self , idx : VectorIdx , current_span : Span ) {
170176 let idx = idx. index ( ) ;
171177 let mut_slice = self . get_mut_with_min_len ( idx + 1 ) ;
172178 let idx_ref = & mut mut_slice[ idx] ;
@@ -190,28 +196,36 @@ impl VClock {
190196 }
191197 }
192198
193- /// Set the element at the current index of the vector
194- pub fn set_at_index ( & mut self , other : & Self , idx : VectorIdx ) {
199+ /// Set the element at the current index of the vector. May only increase elements.
200+ pub ( super ) fn set_at_index ( & mut self , other : & Self , idx : VectorIdx ) {
201+ let new_timestamp = other[ idx] ;
202+ // Setting to 0 is different, since the last element cannot be 0.
203+ if new_timestamp. time ( ) == 0 {
204+ if idx. index ( ) >= self . 0 . len ( ) {
205+ // This index does not even exist yet in our clock. Just do nothing.
206+ return ;
207+ }
208+ // This changes an existing element. Since it can only increase, that
209+ // can never make the last element 0.
210+ }
211+
195212 let mut_slice = self . get_mut_with_min_len ( idx. index ( ) + 1 ) ;
213+ let mut_timestamp = & mut mut_slice[ idx. index ( ) ] ;
196214
197- let prev_span = mut_slice [ idx . index ( ) ] . span ;
215+ let prev_span = mut_timestamp . span ;
198216
199- mut_slice[ idx. index ( ) ] = other[ idx] ;
217+ assert ! ( * mut_timestamp <= new_timestamp, "set_at_index: may only increase the timestamp" ) ;
218+ * mut_timestamp = new_timestamp;
200219
201- let span = & mut mut_slice [ idx . index ( ) ] . span ;
220+ let span = & mut mut_timestamp . span ;
202221 * span = span. substitute_dummy ( prev_span) ;
203222 }
204223
205224 /// Set the vector to the all-zero vector
206225 #[ inline]
207- pub fn set_zero_vector ( & mut self ) {
226+ pub ( super ) fn set_zero_vector ( & mut self ) {
208227 self . 0 . clear ( ) ;
209228 }
210-
211- /// Return if this vector is the all-zero vector
212- pub fn is_zero_vector ( & self ) -> bool {
213- self . 0 . is_empty ( )
214- }
215229}
216230
217231impl Clone for VClock {
@@ -407,13 +421,6 @@ impl Index<VectorIdx> for VClock {
407421 }
408422}
409423
410- impl IndexMut < VectorIdx > for VClock {
411- #[ inline]
412- fn index_mut ( & mut self , index : VectorIdx ) -> & mut VTimestamp {
413- self . 0 . as_mut_slice ( ) . get_mut ( index. to_u32 ( ) as usize ) . unwrap ( )
414- }
415- }
416-
417424/// Test vector clock ordering operations
418425/// data-race detection is tested in the external
419426/// test suite
@@ -553,4 +560,15 @@ mod tests {
553560 "Invalid alt (>=):\n l: {l:?}\n r: {r:?}"
554561 ) ;
555562 }
563+
564+ #[ test]
565+ fn set_index_to_0 ( ) {
566+ let mut clock1 = from_slice ( & [ 0 , 1 , 2 , 3 ] ) ;
567+ let clock2 = from_slice ( & [ 0 , 2 , 3 , 4 , 0 , 5 ] ) ;
568+ // Naively, this would extend clock1 with a new index and set it to 0, making
569+ // the last index 0. Make sure that does not happen.
570+ clock1. set_at_index ( & clock2, VectorIdx ( 4 ) ) ;
571+ // This must not have made the last element 0.
572+ assert ! ( clock1. 0 . last( ) . unwrap( ) . time( ) != 0 ) ;
573+ }
556574}
0 commit comments