Skip to content

Commit f647ccc

Browse files
committed
auto merge of #9695 : huonw/rust/rand2, r=alexcrichton
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
2 parents e505d4c + e678435 commit f647ccc

19 files changed

+1703
-576
lines changed

mk/rt.mk

-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,6 @@ RUNTIME_CXXS_$(1)_$(2) := \
8686
rt/sync/lock_and_signal.cpp \
8787
rt/sync/rust_thread.cpp \
8888
rt/rust_builtin.cpp \
89-
rt/rust_rng.cpp \
9089
rt/rust_upcall.cpp \
9190
rt/rust_uv.cpp \
9291
rt/miniz.cpp \

src/libextra/bitv.rs

+10-10
Original file line numberDiff line numberDiff line change
@@ -1524,16 +1524,16 @@ mod tests {
15241524
}
15251525

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

15311531
#[bench]
15321532
fn bench_uint_small(b: &mut BenchHarness) {
15331533
let mut r = rng();
15341534
let mut bitv = 0 as uint;
15351535
do b.iter {
1536-
bitv |= (1 << ((r.next() as uint) % uint::bits));
1536+
bitv |= (1 << ((r.next_u32() as uint) % uint::bits));
15371537
}
15381538
}
15391539

@@ -1542,7 +1542,7 @@ mod tests {
15421542
let mut r = rng();
15431543
let mut bitv = SmallBitv::new(uint::bits);
15441544
do b.iter {
1545-
bitv.set((r.next() as uint) % uint::bits, true);
1545+
bitv.set((r.next_u32() as uint) % uint::bits, true);
15461546
}
15471547
}
15481548

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

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

@@ -1571,7 +1571,7 @@ mod tests {
15711571
let mut r = rng();
15721572
let mut bitv = Bitv::new(BENCH_BITS, false);
15731573
do b.iter {
1574-
bitv.set((r.next() as uint) % BENCH_BITS, true);
1574+
bitv.set((r.next_u32() as uint) % BENCH_BITS, true);
15751575
}
15761576
}
15771577

@@ -1580,7 +1580,7 @@ mod tests {
15801580
let mut r = rng();
15811581
let mut bitv = Bitv::new(uint::bits, false);
15821582
do b.iter {
1583-
bitv.set((r.next() as uint) % uint::bits, true);
1583+
bitv.set((r.next_u32() as uint) % uint::bits, true);
15841584
}
15851585
}
15861586

@@ -1589,7 +1589,7 @@ mod tests {
15891589
let mut r = rng();
15901590
let mut bitv = BitvSet::new();
15911591
do b.iter {
1592-
bitv.insert((r.next() as uint) % uint::bits);
1592+
bitv.insert((r.next_u32() as uint) % uint::bits);
15931593
}
15941594
}
15951595

@@ -1598,7 +1598,7 @@ mod tests {
15981598
let mut r = rng();
15991599
let mut bitv = BitvSet::new();
16001600
do b.iter {
1601-
bitv.insert((r.next() as uint) % BENCH_BITS);
1601+
bitv.insert((r.next_u32() as uint) % BENCH_BITS);
16021602
}
16031603
}
16041604

src/libextra/treemap.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1013,7 +1013,7 @@ mod test_treemap {
10131013
check_equal(ctrl, &map);
10141014
assert!(map.find(&5).is_none());
10151015

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

10181018
do 3.times {
10191019
do 90.times {

0 commit comments

Comments
 (0)