Upgrade deps

This commit is contained in:
Pascal Engélibert 2026-07-15 20:41:30 +02:00
commit 09055da93c
5 changed files with 32 additions and 22 deletions

View file

@ -1,7 +1,7 @@
[package] [package]
name = "median-accumulator" name = "median-accumulator"
version = "0.4.0" version = "0.4.0"
edition = "2021" edition = "2024"
authors = ["tuxmain <tuxmain@zettascript.org>"] authors = ["tuxmain <tuxmain@zettascript.org>"]
license = "AGPL-3.0-only" license = "AGPL-3.0-only"
repository = "https://git.txmn.tk/tuxmain/median-accumulator" repository = "https://git.txmn.tk/tuxmain/median-accumulator"
@ -11,7 +11,7 @@ categories = ["algorithms", "data-structures", "no-std"]
keywords = ["median"] keywords = ["median"]
[dependencies] [dependencies]
cc-traits = { version = "2.0.0", default_features = false } cc-traits = { version = "2.0.0", default-features = false }
smallvec = { version = "^1.6", optional = true } smallvec = { version = "^1.6", optional = true }
[features] [features]
@ -21,9 +21,9 @@ smallvec = ["dep:smallvec", "cc-traits/smallvec"]
default = ["std"] default = ["std"]
[dev-dependencies] [dev-dependencies]
criterion = { version = "0.5.1", features = ["html_reports"] } criterion = { version = "0.8.2", features = ["html_reports"] }
medianheap = "0.4.1" medianheap = "0.4.1"
rand = "0.8.5" rand = "0.10"
smallvec = "^1.6" smallvec = "^1.6"
[[bench]] [[bench]]

View file

@ -44,7 +44,7 @@ For other collections than `Vec` or `SmallVec`, you must implement [cc-traits](h
## License ## License
CopyLeft 2022-2024 Pascal Engélibert [(why copyleft?)](https://txmn.tk/blog/why-copyleft/) CopyLeft 2022-2026 Pascal Engélibert [(why copyleft?)](https://txmn.tk/blog/why-copyleft/)
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, version 3 of the License. This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, version 3 of the License.

View file

@ -1,14 +1,14 @@
use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion}; use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
use rand::Rng; use rand::RngExt;
static ITERS: u32 = 10_000; static ITERS: u32 = 10_000;
fn compare_crates(c: &mut Criterion) { fn compare_crates(c: &mut Criterion) {
let mut rng = rand::thread_rng(); let mut rng = rand::rng();
let mut group = c.benchmark_group("Comparison"); let mut group = c.benchmark_group("Comparison");
for redundancy in [1, 5, 10, 20, 40] { for redundancy in [1, 5, 10, 20, 40] {
let samples: Vec<u32> = (0..ITERS) let samples: Vec<u32> = (0..ITERS)
.map(|_| rng.gen_range(0..ITERS / redundancy)) .map(|_| rng.random_range(0..ITERS / redundancy))
.collect(); .collect();
group.bench_with_input( group.bench_with_input(
BenchmarkId::new("median_accumulator", redundancy), BenchmarkId::new("median_accumulator", redundancy),
@ -17,7 +17,7 @@ fn compare_crates(c: &mut Criterion) {
b.iter(|| { b.iter(|| {
let mut median = median_accumulator::vec::MedianAcc::new(); let mut median = median_accumulator::vec::MedianAcc::new();
samples.iter().for_each(|s| median.push(*s)); samples.iter().for_each(|s| median.push(*s));
black_box(median.get_median()); std::hint::black_box(median.get_median());
}) })
}, },
); );
@ -28,7 +28,7 @@ fn compare_crates(c: &mut Criterion) {
b.iter(|| { b.iter(|| {
let mut median = medianheap::MedianHeap::new(); let mut median = medianheap::MedianHeap::new();
samples.iter().for_each(|s| median.push(*s)); samples.iter().for_each(|s| median.push(*s));
black_box(median.median()); std::hint::black_box(median.median());
}) })
}, },
); );

View file

@ -15,6 +15,13 @@
//! In doc comments, _N_ represents the number of samples, _D_ represents the number of different values taken by the samples. //! In doc comments, _N_ represents the number of samples, _D_ represents the number of different values taken by the samples.
#![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), no_std)]
#![warn(missing_docs)]
#![deny(non_ascii_idents)]
#![deny(unnameable_types)]
#![deny(unreachable_pub)]
#![deny(unstable_features)]
#![warn(unused_qualifications)]
#![allow(clippy::tabs_in_doc_comments)]
mod traits; mod traits;
@ -34,25 +41,26 @@ pub struct MedianAcc<
_t: core::marker::PhantomData<T>, _t: core::marker::PhantomData<T>,
} }
/// Aliases for `Vec` backend
#[cfg(feature = "std")] #[cfg(feature = "std")]
pub mod vec { pub mod vec {
/// Median accumulator using a `Vec`
pub type MedianAcc<T> = crate::MedianAcc<T, Vec<(T, u32)>>; pub type MedianAcc<T> = crate::MedianAcc<T, Vec<(T, u32)>>;
} }
/// Computed median /// Computed median
///
/// `Two` is when the median is the mean of the two values.
/// In this case, `result.0 < result.1`.
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq)]
pub enum MedianResult<T: Clone + Ord> { pub enum MedianResult<T: Clone + Ord> {
/// Median is an element from the list
One(T), One(T),
/// Median is the mean of these two values from the list
///
/// It is guaranteed that `result.0 < result.1`.
Two(T, T), Two(T, T),
} }
impl< impl<T: Clone + Ord, V: DerefMut<Target = [(T, u32)]> + cc_traits::VecMut<(T, u32)> + InsertIndex>
T: Clone + Ord, MedianAcc<T, V>
V: DerefMut<Target = [(T, u32)]> + cc_traits::VecMut<(T, u32)> + InsertIndex,
> MedianAcc<T, V>
{ {
/// Create an empty accumulator /// Create an empty accumulator
/// ///
@ -211,7 +219,7 @@ impl<
mod tests { mod tests {
use super::*; use super::*;
use rand::Rng; use rand::RngExt;
#[cfg(feature = "std")] #[cfg(feature = "std")]
fn naive_median<T: Clone + Ord>(samples: &mut [T]) -> Option<MedianResult<T>> { fn naive_median<T: Clone + Ord>(samples: &mut [T]) -> Option<MedianResult<T>> {
@ -236,11 +244,11 @@ mod tests {
#[cfg(feature = "std")] #[cfg(feature = "std")]
#[test] #[test]
fn correctness() { fn correctness() {
let mut rng = rand::thread_rng(); let mut rng = rand::rng();
for _ in 0..100_000 { for _ in 0..100_000 {
let len: usize = rng.gen_range(0..100); let len: usize = rng.random_range(0..100);
let mut samples: Vec<i32> = (0..len).map(|_| rng.gen_range(-100..100)).collect(); let mut samples: Vec<i32> = (0..len).map(|_| rng.random_range(-100..100)).collect();
let mut median = vec::MedianAcc::new(); let mut median = vec::MedianAcc::new();
for sample in samples.iter() { for sample in samples.iter() {

View file

@ -1,7 +1,9 @@
/// Collection where an item can be inserted at a given index. /// Collection where an item can be inserted at a given index.
pub trait InsertIndex: cc_traits::Collection { pub trait InsertIndex: cc_traits::Collection {
/// Output type of inserting at an index (may be `()`)
type Output; type Output;
/// Insert `element` to the collection at `index`
fn insert_index( fn insert_index(
&mut self, &mut self,
index: usize, index: usize,