Skip to content

Commit

Permalink
auto merge of #9695 : huonw/rust/rand2, r=alexcrichton
Browse files Browse the repository at this point in the history
A pile of changes to `std::rand`:

- Add the 64-bit variant of the ISAAC Rng. This also splits the `Rng.next() -> u32` method into `Rng.next_u32() -> u32` and `Rng.next_u64() -> u64` to be able to actually take advantage of the wider numbers. They have default implementations in terms of each other. (This is ~2× faster than the 32 bit one for generating anything larger than a `u32` on 64-bit computers.)
- Add `ReaderRng` which just wraps a reader as an RNG, useful for `/dev/urandom`, `/dev/random`, `/dev/hwrng`, etc. This also adds the overrideable `fill_bytes` method to `Rng`, since readers can "generate" randomness more than just 8 bytes at a time.
- Add an interface to `/dev/urandom` (and the windows API) that implements `Rng` (`os::OSRng`) so that it is a first-class randomness source. This means that experimenting with things like seeding hashmaps from it will be much easier. It deletes most of the C++ supporting the old form, except for thin wrappers around the Windows API; I don't have access to a windows with Rust other than the try branch. ( **Note:** on unices, this means that `OSRng` requires the runtime, so it's not possible to use it to seed the scheduler RNG; I've replaced it with direct libc calls for reading from `/dev/urandom`.)
- Add the "blessed" `StdRng` which means users who just want a random number generator don't need to worry about the implementation details (which will make changing the underlying implementation from Isaac to something else will be easier, if this every happen). This actually changes between the 32 and 64-bit variants of Isaac depending on the platform at the moment.
- Add a `SeedableRng` trait for random number generators that can be explicitly seeded, 
- Add the `ReseedingRng` wrapper for reseeding a RNG after a certain amount of randomness is emitted. (The method for reseeding is controlled via the `Reseeder` trait from the same module)
- changes to the task rng: 
 - uses `StdRng`
 - it will reseed itself every 32KB, that is, after outputting 32KB of random data it will read new data from the OS (via `OSRng`)
- Implements `Rand` for `char`, and makes the `f32` and `f64` instances more reasonable (and more similar to most other languages I've looked at).
- Documentation, examples and tests
  • Loading branch information
bors committed Oct 9, 2013
2 parents e505d4c + e678435 commit f647ccc
Show file tree
Hide file tree
Showing 19 changed files with 1,703 additions and 576 deletions.
1 change: 0 additions & 1 deletion mk/rt.mk
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@ RUNTIME_CXXS_$(1)_$(2) := \
rt/sync/lock_and_signal.cpp \
rt/sync/rust_thread.cpp \
rt/rust_builtin.cpp \
rt/rust_rng.cpp \
rt/rust_upcall.cpp \
rt/rust_uv.cpp \
rt/miniz.cpp \
Expand Down
20 changes: 10 additions & 10 deletions src/libextra/bitv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1524,16 +1524,16 @@ mod tests {
}

fn rng() -> rand::IsaacRng {
let seed = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
rand::IsaacRng::new_seeded(seed)
let seed = &[1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
rand::SeedableRng::from_seed(seed)
}

#[bench]
fn bench_uint_small(b: &mut BenchHarness) {
let mut r = rng();
let mut bitv = 0 as uint;
do b.iter {
bitv |= (1 << ((r.next() as uint) % uint::bits));
bitv |= (1 << ((r.next_u32() as uint) % uint::bits));
}
}

Expand All @@ -1542,7 +1542,7 @@ mod tests {
let mut r = rng();
let mut bitv = SmallBitv::new(uint::bits);
do b.iter {
bitv.set((r.next() as uint) % uint::bits, true);
bitv.set((r.next_u32() as uint) % uint::bits, true);
}
}

Expand All @@ -1551,7 +1551,7 @@ mod tests {
let mut r = rng();
let mut bitv = BigBitv::new(~[0]);
do b.iter {
bitv.set((r.next() as uint) % uint::bits, true);
bitv.set((r.next_u32() as uint) % uint::bits, true);
}
}

Expand All @@ -1562,7 +1562,7 @@ mod tests {
storage.grow(BENCH_BITS / uint::bits, &0u);
let mut bitv = BigBitv::new(storage);
do b.iter {
bitv.set((r.next() as uint) % BENCH_BITS, true);
bitv.set((r.next_u32() as uint) % BENCH_BITS, true);
}
}

Expand All @@ -1571,7 +1571,7 @@ mod tests {
let mut r = rng();
let mut bitv = Bitv::new(BENCH_BITS, false);
do b.iter {
bitv.set((r.next() as uint) % BENCH_BITS, true);
bitv.set((r.next_u32() as uint) % BENCH_BITS, true);
}
}

Expand All @@ -1580,7 +1580,7 @@ mod tests {
let mut r = rng();
let mut bitv = Bitv::new(uint::bits, false);
do b.iter {
bitv.set((r.next() as uint) % uint::bits, true);
bitv.set((r.next_u32() as uint) % uint::bits, true);
}
}

Expand All @@ -1589,7 +1589,7 @@ mod tests {
let mut r = rng();
let mut bitv = BitvSet::new();
do b.iter {
bitv.insert((r.next() as uint) % uint::bits);
bitv.insert((r.next_u32() as uint) % uint::bits);
}
}

Expand All @@ -1598,7 +1598,7 @@ mod tests {
let mut r = rng();
let mut bitv = BitvSet::new();
do b.iter {
bitv.insert((r.next() as uint) % BENCH_BITS);
bitv.insert((r.next_u32() as uint) % BENCH_BITS);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/libextra/treemap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1013,7 +1013,7 @@ mod test_treemap {
check_equal(ctrl, &map);
assert!(map.find(&5).is_none());

let mut rng = rand::IsaacRng::new_seeded(&[42]);
let mut rng: rand::IsaacRng = rand::SeedableRng::from_seed(&[42]);

do 3.times {
do 90.times {
Expand Down
Loading

0 comments on commit f647ccc

Please sign in to comment.