1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
//! Crate implementing reservoir sampling, a method for getting random samples
//! from a source in a single pass. Useful in situations where size of source is
//! unknown or very large.
//! Read this article for more information: https://en.wikipedia.org/wiki/Reservoir_sampling
//! All algorithms implemented here have been taken from this article only.

//! # Features:
//! - Unweighted reservoir sampling
//! - Weighted reservoir sampling
//! # API Design
//! Functions take:
//! - An iterator of generic type T, with no constraints which serves as a stream of data to sample.
//! - Mutable array slice to store sampled data
//! <br>
//! By default, functions use `rand::thread_rng` to provide RNG.
//! To use your own RNG which implements `rand::RNG`, use functions in `core` module of each feature.

#[cfg(feature = "unweighted")]
pub mod unweighted {
    pub mod core;

    use rand::thread_rng;
    
    /// An implementation of Algorithm `L` (https://en.wikipedia.org/wiki/Reservoir_sampling#An_optimal_algorithm)
    /// # Parameters:
    /// - Type implementing `std::iter::Iterator` as *source*,
    /// - Mutable array slice (i.e. `&mut [T]`) as *sample array (i.e. where sampled data is stored)*
    /// # Notes:
    /// - In case iterator yields less than sample amount, sample will be filled as much as possible, and returned.
    /// - This uses `rand::thread_rng` to provide RNG. To use your own RNG which implements `rand::RNG`, see `reservoir_sampling::core`
    
    pub fn l <I, T>(stream: I, sample: &mut [T])
    where
        I: Iterator<Item=T>,
    {
        let mut rng = thread_rng();
        core::l(stream, sample, &mut rng);
    }

    /// An implementation of algorithm `R` (https://en.wikipedia.org/wiki/Reservoir_sampling#Simple_algorithm)
    /// # Parameters:
    /// - Type implementing `std::iter::Iterator` as *source*,
    /// - Mutable array slice (i.e. `&mut [T]`) as *sample array (i.e. where sampled data is stored)*
    /// - Type implementing `rand::Rng` for random number generation.
    /// In case iterator yields less than sample amount, sample will be filled as much as possible, and returned.

    pub fn r <I, T>(stream: I, sample: &mut [T])
    where
        I: Iterator<Item=T>,
    {
        let mut rng = thread_rng();
        core::r(stream, sample, &mut rng);
    }
}