data.rs

2.2 kB · rust · 76 lines

1use crate::rng::Rng;2use crate::Json;34/// A dataset source: a named, seeded generator of JSON rows.5///6/// Pouring obeys the determinism law: the same seed pours the same rows in7/// the same order, and a shorter pour is a prefix of a longer one. A well8/// may tag a row `{"split": "eval"}` to claim it for evaluation; untagged9/// rows are training rows.10///11/// ```12/// use mrlycore::data::Well;13/// use mrlycore::{json, Json};14///15/// struct Squares;16///17/// impl Well for Squares {18///     fn name(&self) -> &str {19///         "squares"20///     }21///     fn about(&self) -> &str {22///         "The squares of the naturals."23///     }24///     fn pour(&self, _seed: u64, count: usize) -> Vec<Json> {25///         (0..count).map(|n| json!({ "n": n, "square": n * n })).collect()26///     }27/// }28///29/// let well: Box<dyn Well> = Box::new(Squares);30/// assert_eq!(well.pour(7, 2)[..], well.pour(7, 3)[..2]);31/// ```32pub trait Well {33    /// Returns the dataset's name.34    fn name(&self) -> &str;35    /// Returns the dataset's one-line description.36    fn about(&self) -> &str;37    /// Pours count seeded rows, identical for identical seeds, earlier rows first.38    fn pour(&self, seed: u64, count: usize) -> Vec<Json>;39}4041/// Shuffles rows into the seed's order, so a short pour samples an enumeration fairly.42pub fn shuffle(rows: &mut [Json], seed: u64) {43    let mut rng = Rng::new(seed);44    for i in (1..rows.len()).rev() {45        let j = rng.below(i + 1);46        rows.swap(i, j);47    }48}4950#[cfg(test)]51mod tests {52    use super::*;53    use crate::json;5455    #[test]56    fn shuffle_replays_and_reorders() {57        let fresh = || (0..32).map(|n| json!({ "n": n })).collect::<Vec<Json>>();58        let (mut a, mut b, straight) = (fresh(), fresh(), fresh());59        shuffle(&mut a, 7);60        shuffle(&mut b, 7);61        assert_eq!(a, b);62        assert_ne!(a, straight);63        let mut sorted = a.clone();64        sorted.sort_by_key(|row| row["n"].as_i64());65        assert_eq!(sorted, straight);66    }6768    #[test]69    fn different_seeds_deal_different_orders() {70        let fresh = || (0..32).map(|n| json!({ "n": n })).collect::<Vec<Json>>();71        let (mut a, mut b) = (fresh(), fresh());72        shuffle(&mut a, 1);73        shuffle(&mut b, 2);74        assert_ne!(a, b);75    }76}