mirror of
https://github.com/LibreQoE/LibreQoS.git
synced 2025-02-25 18:55:32 -06:00
LTS data collection was occasionally overflowing on calculating
the mean average. If a large-enough block had to be summed, the total could overflow the storage type. To prevent this from ever happening, we instead calculate the median - which is likely to give a better representation anyway. Also fixes a compile warning.
This commit is contained in:
@@ -78,7 +78,7 @@ impl UnixSocketServer {
|
||||
}
|
||||
|
||||
fn make_socket_public() -> Result<(), UnixSocketServerError> {
|
||||
lqos_utils::run_success!(
|
||||
let _ = lqos_utils::run_success!(
|
||||
"/bin/chmod",
|
||||
"-R",
|
||||
"a+rwx",
|
||||
|
||||
@@ -7,6 +7,21 @@ pub(crate) struct MinMaxAvg<T> {
|
||||
pub(crate) avg: T,
|
||||
}
|
||||
|
||||
fn median<T>(stats: &[T]) -> T
|
||||
where
|
||||
T: Bounded + Zero + std::ops::AddAssign<T> + Copy + std::cmp::Ord + CheckedDiv + NumCast,
|
||||
{
|
||||
let mut sorted = stats.to_vec();
|
||||
sorted.sort();
|
||||
let len = sorted.len();
|
||||
let mid = len / 2;
|
||||
if len % 2 == 0 {
|
||||
(sorted[mid] + sorted[mid - 1]).checked_div(&T::from(2).unwrap()).unwrap_or(T::zero())
|
||||
} else {
|
||||
sorted[mid]
|
||||
}
|
||||
}
|
||||
|
||||
impl<
|
||||
T: Bounded
|
||||
+ Zero
|
||||
@@ -20,17 +35,13 @@ impl<
|
||||
pub(crate) fn from_slice(stats: &[T]) -> Self {
|
||||
let mut min = T::max_value();
|
||||
let mut max = T::min_value();
|
||||
let mut avg = T::zero();
|
||||
|
||||
stats.iter().for_each(|n| {
|
||||
avg += *n;
|
||||
min = T::min(min, *n);
|
||||
max = T::max(max, *n);
|
||||
});
|
||||
let len = T::from(stats.len()).unwrap();
|
||||
avg = avg.checked_div(&len).unwrap_or(T::zero());
|
||||
|
||||
Self { max, min, avg }
|
||||
Self { max, min, avg: median(stats) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user