@@ -173,6 +173,13 @@ impl<R: Role> RawNode<R> {
173
173
quorum_size ( self . cluster_size ( ) )
174
174
}
175
175
176
+ /// Returns the quorum value of the given unsorted slice, in descending
177
+ /// order. The slice must have the same size as the cluster.
178
+ fn quorum_value < T : Ord + Copy > ( & self , values : Vec < T > ) -> T {
179
+ assert ! ( values. len( ) == self . cluster_size( ) as usize , "values must match cluster size" ) ;
180
+ quorum_value ( values)
181
+ }
182
+
176
183
/// Sends an event
177
184
fn send ( & self , to : Address , event : Event ) -> Result < ( ) > {
178
185
let msg = Message { term : self . term , from : Address :: Node ( self . id ) , to, event } ;
@@ -228,6 +235,14 @@ fn quorum_size(size: u8) -> u8 {
228
235
size / 2 + 1
229
236
}
230
237
238
+ /// Returns the quorum (median) value of the given unsorted slice, in descending
239
+ /// order. The slice cannot be empty.
240
+ fn quorum_value < T : Ord + Copy > ( mut values : Vec < T > ) -> T {
241
+ assert ! ( !values. is_empty( ) , "no values provided" ) ;
242
+ let index = quorum_size ( values. len ( ) as u8 ) as usize - 1 ;
243
+ * values. select_nth_unstable_by ( index, |a, b : & T | a. cmp ( b) . reverse ( ) ) . 1
244
+ }
245
+
231
246
#[ cfg( test) ]
232
247
mod tests {
233
248
pub use super :: super :: state:: tests:: TestState ;
@@ -534,4 +549,13 @@ mod tests {
534
549
assert_eq ! ( super :: quorum_size( size) , quorum) ;
535
550
}
536
551
}
552
+
553
+ #[ test]
554
+ fn quorum_value ( ) {
555
+ assert_eq ! ( super :: quorum_value( vec![ 1 ] ) , 1 ) ;
556
+ assert_eq ! ( super :: quorum_value( vec![ 1 , 3 , 2 ] ) , 2 ) ;
557
+ assert_eq ! ( super :: quorum_value( vec![ 4 , 1 , 3 , 2 ] ) , 2 ) ;
558
+ assert_eq ! ( super :: quorum_value( vec![ 1 , 1 , 1 , 2 , 2 ] ) , 1 ) ;
559
+ assert_eq ! ( super :: quorum_value( vec![ 1 , 1 , 2 , 2 , 2 ] ) , 2 ) ;
560
+ }
537
561
}
0 commit comments