Skip to content

Commit 724c9cc

Browse files
committed
---
yaml --- r: 95279 b: refs/heads/dist-snap c: 0223cf6 h: refs/heads/master i: 95277: fc32763 95275: 647038c 95271: c1c80ed 95263: cadaf31 v: v3
1 parent 3f4fa93 commit 724c9cc

File tree

3 files changed

+130
-1
lines changed

3 files changed

+130
-1
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ refs/heads/try: c274a6888410ce3e357e014568b43310ed787d36
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
88
refs/heads/try2: 147ecfdd8221e4a4d4e090486829a06da1e0ca3c
9-
refs/heads/dist-snap: f39a215f270bc8c958a19cc9f693720232340cbc
9+
refs/heads/dist-snap: 0223cf65e41cc1046b306dcd0e3959a20729e0cf
1010
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1111
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503
1212
refs/heads/try3: 9387340aab40a73e8424c48fd42f0c521a4875c0

branches/dist-snap/src/libstd/rand/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ pub mod distributions;
6262
pub mod isaac;
6363
pub mod os;
6464
pub mod reader;
65+
pub mod reseeding;
6566

6667
/// A type that can be randomly generated using an Rng
6768
pub trait Rand {
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
//! A wrapper around another RNG that reseeds it after it
12+
//! generates a certain number of random bytes.
13+
14+
use rand::Rng;
15+
use default::Default;
16+
17+
/// How many bytes of entropy the underling RNG is allowed to generate
18+
/// before it is reseeded.
19+
static DEFAULT_GENERATION_THRESHOLD: uint = 32 * 1024;
20+
21+
/// A wrapper around any RNG which reseeds the underlying RNG after it
22+
/// has generated a certain number of random bytes.
23+
pub struct ReseedingRng<R, Rsdr> {
24+
priv rng: R,
25+
priv generation_threshold: uint,
26+
priv bytes_generated: uint,
27+
/// Controls the behaviour when reseeding the RNG.
28+
reseeder: Rsdr
29+
}
30+
31+
impl<R: Rng, Rsdr: Reseeder<R>> ReseedingRng<R, Rsdr> {
32+
/// Create a new `ReseedingRng` with the given parameters.
33+
///
34+
/// # Arguments
35+
///
36+
/// * `rng`: the random number generator to use.
37+
/// * `generation_threshold`: the number of bytes of entropy at which to reseed the RNG.
38+
/// * `reseeder`: the reseeding object to use.
39+
pub fn new(rng: R, generation_threshold: uint, reseeder: Rsdr) -> ReseedingRng<R,Rsdr> {
40+
ReseedingRng {
41+
rng: rng,
42+
generation_threshold: generation_threshold,
43+
bytes_generated: 0,
44+
reseeder: reseeder
45+
}
46+
}
47+
48+
/// Reseed the internal RNG if the number of bytes that have been
49+
/// generated exceed the threshold.
50+
pub fn reseed_if_necessary(&mut self) {
51+
if self.bytes_generated >= self.generation_threshold {
52+
self.reseeder.reseed(&mut self.rng);
53+
self.bytes_generated = 0;
54+
}
55+
}
56+
}
57+
58+
59+
impl<R: Rng, Rsdr: Reseeder<R>> Rng for ReseedingRng<R, Rsdr> {
60+
fn next_u32(&mut self) -> u32 {
61+
self.reseed_if_necessary();
62+
self.bytes_generated += 4;
63+
self.rng.next_u32()
64+
}
65+
66+
fn next_u64(&mut self) -> u64 {
67+
self.reseed_if_necessary();
68+
self.bytes_generated += 8;
69+
self.rng.next_u64()
70+
}
71+
72+
fn fill_bytes(&mut self, dest: &mut [u8]) {
73+
self.reseed_if_necessary();
74+
self.bytes_generated += dest.len();
75+
self.fill_bytes(dest)
76+
}
77+
}
78+
79+
/// Something that can be used to reseed an RNG via `ReseedingRng`.
80+
pub trait Reseeder<R> {
81+
/// Reseed the given RNG.
82+
fn reseed(&mut self, rng: &mut R);
83+
}
84+
85+
/// Reseed an RNG using a `Default` instance. This reseeds by
86+
/// replacing the RNG with the result of a `Default::default` call.
87+
pub struct ReseedWithDefault;
88+
89+
impl<R: Rng + Default> Reseeder<R> for ReseedWithDefault {
90+
fn reseed(&mut self, rng: &mut R) {
91+
*rng = Default::default();
92+
}
93+
}
94+
95+
#[cfg(test)]
96+
mod test {
97+
use super::*;
98+
use rand::Rng;
99+
use default::Default;
100+
101+
struct Counter {
102+
i: u32
103+
}
104+
105+
impl Rng for Counter {
106+
fn next_u32(&mut self) -> u32 {
107+
self.i += 1;
108+
// very random
109+
self.i - 1
110+
}
111+
}
112+
impl Default for Counter {
113+
fn default() -> Counter {
114+
Counter { i: 0 }
115+
}
116+
}
117+
118+
#[test]
119+
fn test_reseeding() {
120+
let mut rs = ReseedingRng::from_options(Counter {i:0}, 100, ReseedWithDefault);
121+
122+
let mut i = 0;
123+
for _ in range(0, 1000) {
124+
assert_eq!(rs.next_u32(), i % 100);
125+
i += 1;
126+
}
127+
}
128+
}

0 commit comments

Comments
 (0)