Skip to content

Commit

Permalink
add (default) rand feature, so users can build without rand (closes #10)
Browse files Browse the repository at this point in the history
  • Loading branch information
droundy committed Jun 19, 2020
1 parent 714911a commit 7c82d40
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 11 deletions.
6 changes: 5 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,13 @@ travis-ci = { repository = "droundy/tinyset" }
appveyor = { repository = "droundy/tinyset" }

[dependencies]
rand = "0.7.2"
rand = { version = "0.7.2", optional = true }
itertools = "0.8.1"

[features]

default = ["rand"]

[[bench]]
name = "bench"
harness = false
7 changes: 7 additions & 0 deletions proptest-regressions/setusize.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Seeds for failure cases proptest has generated in the past. It is
# automatically read and these particular cases re-run before any
# novel cases are generated.
#
# It is recommended to check this file in to source control so that
# everyone who runs the test benefits from these saved cases.
cc ba58eac8bcfa93ea30ebf22f46fad0b05ee2fd1543b593b1e0ad3a5cb340b1dd # shrinks to slice = [4611686018427387904]
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@
#![deny(missing_docs)]

mod rand;

#[doc(hidden)]
pub mod setu32b;

Expand Down
50 changes: 50 additions & 0 deletions src/rand.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#[cfg(not(feature = "rand"))]
use std::sync::atomic::{AtomicU64, Ordering};

#[cfg(not(feature = "rand"))]
static SEED: AtomicU64 = AtomicU64::new(0);

#[cfg(not(feature = "rand"))]
pub fn rand32() -> u32 {
rand64() as u32
}

#[cfg(feature = "rand")]
pub fn rand32() -> u32 {
rand::random::<u32>()
}

#[cfg(not(feature = "rand"))]
pub fn rand64() -> u64 {
use std::num::Wrapping;
// This is the SplitMix64 algorithm. It's pretty crude,
// but should actually be good enough in most cases.
let z = Wrapping(SEED.fetch_add(0x9e3779b97f4a7c15, Ordering::Relaxed));
if z == Wrapping(0) {
let seed = std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH).unwrap().subsec_nanos();
SEED.store(seed as u64, Ordering::Relaxed);
return rand64();
}
let z = (z ^ (z >> 30)) * Wrapping(0xbf58476d1ce4e5b9);
let z = (z ^ (z >> 27)) * Wrapping(0x94d049bb133111eb);
(z ^ (z >> 31)).0
// uint64_t z = (x += 0x9e3779b97f4a7c15);
// z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
// z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
// return z ^ (z >> 31);
}

#[cfg(feature = "rand")]
pub fn rand64() -> u64 {
rand::random::<u64>()
}

#[cfg(not(feature = "rand"))]
pub fn rand_usize() -> usize {
rand64() as usize
}

#[cfg(feature = "rand")]
pub fn rand_usize() -> usize {
rand::random::<usize>()
}
10 changes: 5 additions & 5 deletions src/setu32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -832,7 +832,7 @@ impl SetU32 {
(*x.0).bits = if bits == 0 {
let mut b = 0;
while b <= 32 {
b = rand::random();
b = crate::rand::rand32();
}
b
} else {
Expand Down Expand Up @@ -914,7 +914,7 @@ impl SetU32 {
}
InternalMut::Heap { s, a } => {
if compute_array_bits(e) < s.bits {
let newcap = s.cap+1+(rand::random::<u32>() % s.cap);
let newcap = s.cap+1+(crate::rand::rand32() % s.cap);
let mut new = Self::with_capacity_and_bits(newcap as usize,
compute_array_bits(e));
// new.debug_me("\n\nnew set");
Expand Down Expand Up @@ -974,7 +974,7 @@ impl SetU32 {
} else {
// Let's keep things sparse
// A dense set will cost us memory
let newcap: u32 = s.cap + 1 + (rand::random::<u32>() % s.cap);
let newcap: u32 = s.cap + 1 + (crate::rand::rand32() % s.cap);
let mut new = Self::with_capacity_and_bits(newcap as usize, s.bits);
// new.debug_me("initial new");
for v in self.iter() {
Expand All @@ -995,7 +995,7 @@ impl SetU32 {
// a high O(1) cost to reduce collisions.
let had_zero = p_remove(s.bits, a, 0);
loop {
let i: u32 = rand::random();
let i: u32 = crate::rand::rand32();
if i > 32 && !a.iter().any(|&v| v == i) {
s.bits = i;
break;
Expand Down Expand Up @@ -1030,7 +1030,7 @@ impl SetU32 {
return true;
}
// println!("no room in the set... {:?}", a);
let newcap: u32 = s.cap + 1 + (rand::random::<u32>() % s.cap);
let newcap: u32 = s.cap + 1 + (crate::rand::rand32() % s.cap);
let mut new = Self::with_capacity_and_bits(newcap as usize, s.bits);
// new.debug_me("initial new");
match new.internal_mut() {
Expand Down
10 changes: 5 additions & 5 deletions src/setu64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -585,7 +585,7 @@ impl SetU64 {
(*x.0).bits = if bits == 0 {
let mut b = 0;
while b <= 64 {
b = rand::random();
b = crate::rand::rand64();
}
b
} else {
Expand Down Expand Up @@ -678,7 +678,7 @@ impl SetU64 {
}
InternalMut::Heap { s, a } => {
if compute_array_bits(e) < s.bits {
let mut new = Self::with_capacity_and_bits(s.cap+1+2*(rand::random::<usize>() % s.cap),
let mut new = Self::with_capacity_and_bits(s.cap+1+2*(crate::rand::rand_usize() % s.cap),
compute_array_bits(e));
// new.debug_me("\n\nnew set");
for d in self.iter() {
Expand Down Expand Up @@ -733,7 +733,7 @@ impl SetU64 {
} else {
// Let's keep things sparse
// A dense set will cost us memory
let newcap: usize = s.cap + 1 + (rand::random::<usize>() % s.cap);
let newcap: usize = s.cap + 1 + (crate::rand::rand_usize() % s.cap);
let mut new = Self::with_capacity_and_bits(newcap, s.bits);
// new.debug_me("initial new");
for v in self.iter() {
Expand All @@ -754,7 +754,7 @@ impl SetU64 {
// a high O(1) cost to reduce collisions.
let had_zero = p_remove(s.bits, a, 0);
loop {
let i: u64 = rand::random();
let i: u64 = crate::rand::rand64();
if i > 64 && !a.iter().any(|&v| v == i) {
s.bits = i;
break;
Expand Down Expand Up @@ -784,7 +784,7 @@ impl SetU64 {
return true;
}
// println!("no room in the set... {:?}", a);
let newcap: usize = s.cap + 1 + (rand::random::<usize>() % (2*s.cap));
let newcap: usize = s.cap + 1 + (crate::rand::rand_usize() % (2*s.cap));
let mut new = Self::with_capacity_and_bits(newcap, s.bits);
// new.debug_me("initial new");
match new.internal_mut() {
Expand Down

0 comments on commit 7c82d40

Please sign in to comment.