1use std::cmp::Ordering;
2
3#[cfg(any(unix, windows))]
4#[allow(unsafe_code)]
5pub(crate) fn fastcmp(l: &[u8], r: &[u8]) -> Ordering {
6 let len = std::cmp::min(l.len(), r.len());
7 let cmp = unsafe { libc::memcmp(l.as_ptr() as _, r.as_ptr() as _, len) };
8 match cmp {
9 a if a > 0 => Ordering::Greater,
10 a if a < 0 => Ordering::Less,
11 _ => l.len().cmp(&r.len()),
12 }
13}
14
15#[cfg(not(any(unix, windows)))]
16#[allow(unsafe_code)]
17pub(crate) fn fastcmp(l: &[u8], r: &[u8]) -> Ordering {
18 l.cmp(r)
19}
20
21#[cfg(test)]
22mod qc {
23 use super::fastcmp;
24
25 fn prop_cmp_matches(l: &[u8], r: &[u8]) -> bool {
26 assert_eq!(fastcmp(l, r), l.cmp(r));
27 assert_eq!(fastcmp(r, l), r.cmp(l));
28 assert_eq!(fastcmp(l, l), l.cmp(l));
29 assert_eq!(fastcmp(r, r), r.cmp(r));
30 true
31 }
32
33 #[test]
34 fn test_fastcmp() {
35 let cases: [&[u8]; 8] = [
36 &[],
37 &[0],
38 &[1],
39 &[1],
40 &[255],
41 &[1, 2, 3],
42 &[1, 2, 3, 0],
43 &[1, 2, 3, 55],
44 ];
45 for pair in cases.windows(2) {
46 prop_cmp_matches(pair[0], pair[1]);
47 }
48 }
49
50 quickcheck::quickcheck! {
51 #[cfg_attr(miri, ignore)]
52 fn qc_fastcmp(l: Vec<u8>, r: Vec<u8>) -> bool {
53 prop_cmp_matches(&l, &r)
54 }
55 }
56}