Skip to content

Commit

Permalink
Merge pull request #22 from AaronKutch/dev13
Browse files Browse the repository at this point in the history
Dev13
  • Loading branch information
AaronKutch authored Feb 20, 2024
2 parents f94b27a + 5d92437 commit 858b461
Show file tree
Hide file tree
Showing 29 changed files with 1,139 additions and 695 deletions.
35 changes: 35 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,53 @@ jobs:
- name: Run test suite
# The `riscv32i` build is needed to actually detect if the crate is no_std.
# The `-p triple_arena` builds are so that the testcrate isn't always activating flags
# Note that the test crate has a serde_support flag
run: |
cargo b --target=riscv32i-unknown-none-elf -p no_std_test
cargo b --no-default-features -p triple_arena
cargo b --no-default-features --features=serde -p triple_arena
cargo b --no-default-features --features=expose_internal_utils -p triple_arena
cargo b --no-default-features
cargo b --all-features
cargo t --no-default-features
cargo t --all-features
cargo t --release --all-features
cargo r --bin render0
cargo r --bin render1
cargo r --example equation
miri:
name: Miri
runs-on: ubuntu-latest
# note: we have turned on this Miri flag
env:
RUSTFLAGS: -D warnings
MIRIFLAGS: -Zmiri-tree-borrows -Zmiri-strict-provenance
steps:
- uses: actions/checkout@v2
- name: Install most recent Miri
run: |
rustup set profile minimal
rustup default "nightly-$(curl -s https://rust-lang.github.io/rustup-components-history/x86_64-unknown-linux-gnu/miri)"
rustup component add miri
- name: Run test suite with Miri
run: |
cargo miri test
msrv_test_suite:
runs-on: ubuntu-latest
env:
RUSTFLAGS: -D warnings
steps:
- uses: actions/checkout@v2
- name: Install Rust components
run: |
rustup set profile minimal
rustup install nightly-2023-04-14
- name: Run test suite
run: |
cargo build --no-default-features
rustfmt:
name: Rustfmt
runs-on: ubuntu-latest
Expand Down Expand Up @@ -62,3 +96,4 @@ jobs:
- name: Run `cargo clippy`
run: |
cargo clippy --all --all-targets --all-features -- -D clippy::all
cargo clippy --all --all-targets --no-default-features -- -D clippy::all
7 changes: 6 additions & 1 deletion testcrate/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,10 @@ postcard = { version = "1.0", features = ["alloc"] }
rand_xoshiro = "0.6"
serde = "1.0"
serde_derive = "1.0"
triple_arena = { path = "../triple_arena", features = ["expose_internal_utils", "serde_support"] }
triple_arena = { path = "../triple_arena", features = ["expose_internal_utils"] }
triple_arena_render = { path = "../triple_arena_render" }

# separate feature because we need to test the `ptr_struct` macro both ways
[features]
default = ["serde_support"]
serde_support = ["triple_arena/serde_support"]
59 changes: 31 additions & 28 deletions testcrate/src/bin/render1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,39 +12,42 @@ fn main() {
let mut rng = Xoshiro128StarStar::seed_from_u64(1);
let mut a: Arena<P0, MyNode<P0>> = Arena::new();
let mut ptrs = vec![];
for i in 0..100 {
let mut node = MyNode::new(vec![], vec![], vec![]);
if (rng.next_u32() % 8) != 0 {
node.center.push(format!("n{}", i))
}
loop {
if (rng.next_u32() % 8) == 0 {
node.center.push("center".to_string());
} else {
break
for _ in 0..100 {
a.insert_with(|p| {
let mut node = MyNode::new(vec![], vec![], vec![]);
if (rng.next_u32() % 8) != 0 {
node.center.push(format!("{}", p))
}
}
loop {
if (rng.next_u32() % 4) == 0 {
if !ptrs.is_empty() {
let inx = (rng.next_u32() as usize) % ptrs.len();
node.sources.push((ptrs[inx], format!("p{}", inx)));
loop {
if (rng.next_u32() % 8) == 0 {
node.center.push("center".to_string());
} else {
break
}
} else {
break
}
}
loop {
if (rng.next_u32() % 4) == 0 {
if !ptrs.is_empty() {
let inx = (rng.next_u32() as usize) % ptrs.len();
node.sinks.push((ptrs[inx], format!("p{}", inx)));
loop {
if (rng.next_u32() % 4) == 0 {
if !ptrs.is_empty() {
let inx = (rng.next_u32() as usize) % ptrs.len();
node.sources.push((ptrs[inx], format!("p{}", inx)));
}
} else {
break
}
} else {
break
}
}
ptrs.push(a.insert(node))
loop {
if (rng.next_u32() % 4) == 0 {
if !ptrs.is_empty() {
let inx = (rng.next_u32() as usize) % ptrs.len();
node.sinks.push((ptrs[inx], format!("p{}", inx)));
}
} else {
break
}
}
ptrs.push(p);
node
});
}

render_to_svg_file(
Expand Down
10 changes: 5 additions & 5 deletions testcrate/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,10 @@ ptr_struct!(P0[NonZeroU32](NonZeroU128));
ptr_struct!(P1);

thread_local! {
pub static CLONE_COUNT: RefCell<u64> = RefCell::new(0);
pub static CMP_COUNT: RefCell<u64> = RefCell::new(0);
pub static VAL_NUM: RefCell<u64> = RefCell::new(0);
pub static SEED: RefCell<u64> = RefCell::new(0);
pub static CLONE_COUNT: RefCell<u64> = const { RefCell::new(0) };
pub static CMP_COUNT: RefCell<u64> = const { RefCell::new(0) };
pub static VAL_NUM: RefCell<u64> = const { RefCell::new(0) };
pub static SEED: RefCell<u64> = const { RefCell::new(0) };
}

pub fn get_next_seed() -> u64 {
Expand Down Expand Up @@ -115,7 +115,7 @@ impl PartialEq for CKey {
}
}

#[allow(clippy::incorrect_partial_ord_impl_on_ord_type)]
#[allow(clippy::non_canonical_partial_ord_impl)]
impl PartialOrd for CKey {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
inc_cmp_count();
Expand Down
68 changes: 57 additions & 11 deletions testcrate/tests/fuzz_ord.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ const N: usize = if cfg!(miri) {
};

const STATS: (usize, u64, u128) = if cfg!(miri) {
(70, 1, 122)
(69, 1, 122)
} else if cfg!(debug_assertions) {
(239, 107, 14567)
(223, 107, 14569)
} else {
(418, 5049, 749771)
(420, 5049, 749789)
};

macro_rules! next_inx {
Expand Down Expand Up @@ -411,7 +411,42 @@ fn fuzz_ord() {
assert!(a.find_with(|_, k, _| new_k.cmp(k)).is_none());
}
}
550..=994 => {
550..=579 => {
// find_similar_with
let new_k = new_k();
if let Some(set) = b.get(&new_k) {
let (p, ord) = a
.find_similar_with(|p, k, v| {
assert_eq!(a.get(p).unwrap(), (k, v));
new_k.cmp(k)
})
.unwrap();
let v = *a.get_val(p).unwrap();
assert!(set.contains_key(&v));
assert_eq!(ord, Ordering::Equal);
} else if a.is_empty() {
assert!(a.find_similar_with(|_, k, _| new_k.cmp(k)).is_none());
} else {
let (p, ord) = a.find_similar_with(|_, k, _| new_k.cmp(k)).unwrap();
let k = *a.get_key(p).unwrap();
match ord {
Ordering::Less => {
if let Some(prev) = a.get_link(p).unwrap().prev() {
assert!(*a.get_key(prev).unwrap() < new_k);
}
assert!(new_k < k);
}
Ordering::Equal => unreachable!(),
Ordering::Greater => {
if let Some(next) = a.get_link(p).unwrap().next() {
assert!(new_k < *a.get_key(next).unwrap());
}
assert!(k < new_k);
}
}
}
}
580..=994 => {
// find_key with get_val
let new_k = new_k();
if let Some(set) = b.get(&new_k) {
Expand All @@ -423,41 +458,52 @@ fn fuzz_ord() {
}
}
995 => {
// advancer, ptrs, iter, keys, keys_mut, vals, vals_mut
// advancer, ptrs, iter, keys, keys_mut, vals, vals_mut, advancer_starting_from
let mut adv = a.advancer();
let mut ptrs = a.ptrs();
let mut iter = a.iter();
let mut keys = a.keys();
let mut vals = a.vals();
let new_k = new_k();
let p_start = a.find_key(&new_k).unwrap_or(Ptr::invalid());
let mut adv_from = a.advancer_starting_from(p_start);
let mut adv_from_started = false;
while let Some(p) = adv.advance(&a) {
let (k, v) = a.get(p).unwrap();
assert_eq!(ptrs.next().unwrap(), p);
assert_eq!(iter.next().unwrap(), (p, k, v));
assert_eq!(*keys.next().unwrap(), *k);
assert_eq!(*vals.next().unwrap(), *v);
if p_start == p {
adv_from_started = true;
}
if adv_from_started {
assert_eq!(adv_from.advance(&a).unwrap(), p);
}
}
assert!(adv_from.advance(&a).is_none());
for v in a.vals_mut() {
black_box(v);
}
}
996 => {
// min
// first
if len != 0 {
let set = b.first_entry().unwrap();
let v = a.get_val(a.min().unwrap()).unwrap();
let v = a.get_val(a.first().unwrap()).unwrap();
assert!(set.get().contains_key(v));
} else {
assert!(a.min().is_none());
assert!(a.first().is_none());
}
}
997 => {
// max
// last
if len != 0 {
let set = b.last_entry().unwrap();
let v = a.get_val(a.max().unwrap()).unwrap();
let v = a.get_val(a.last().unwrap()).unwrap();
assert!(set.get().contains_key(v));
} else {
assert!(a.max().is_none());
assert!(a.last().is_none());
}
}
998 => {
Expand Down
33 changes: 31 additions & 2 deletions testcrate/tests/imports.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,39 @@
//! makes sure all variations of the macro compile and do not require imports
//! other than the macro itself
//! other than the macro itself, and also that fully qualified names are being
//! used
use std::num::{NonZeroU128, NonZeroU8};
#![allow(dead_code)]

use core::num::{NonZeroU128, NonZeroU8};

use triple_arena::ptr_struct;

mod std {}
mod alloc {}
struct Result {}
struct Option {}
trait Hash {}
trait Clone {}
trait Copy {}
trait PartialEq {}
trait Eq {}
trait PartialOrd {}
trait Ord {}
trait Ptr {}
trait PtrInx {}
trait PtrGen {}
trait Default {}
trait Debug {}
trait Display {}

trait Recast {}
trait Serialize {}
trait Deserialize {}

// so the default uses are correct
trait NonZeroUsize {}
trait NonZeroU64 {}

ptr_struct!(P0[NonZeroU128](NonZeroU128));
ptr_struct!(P1[NonZeroU128]());
ptr_struct!(P2[NonZeroU128]);
Expand Down
41 changes: 40 additions & 1 deletion testcrate/tests/interarena.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use rand_xoshiro::{rand_core::SeedableRng, Xoshiro128StarStar};
use rand_xoshiro::{
rand_core::{RngCore, SeedableRng},
Xoshiro128StarStar,
};
use testcrate::{
fuzz_fill_inst, std_arena, std_chain, std_chain_no_gen, std_ord, std_surject, CKey, CVal, A, P1,
};
Expand Down Expand Up @@ -158,3 +161,39 @@ fn clone_from_to_recast() {
assert_eq!(a1.get(p).unwrap(), (key, val));
});
}

// also retests a bunch of misc stuff
#[test]
fn ord_arena_order() {
let mut rng = Xoshiro128StarStar::seed_from_u64(0);
let mut set_of_vecs = vec![];
for _ in 0..A {
let mut v = vec![];
for _ in 0..(rng.next_u32() % 16) {
v.push((rng.next_u32() % 16, rng.next_u64() % 16));
}
v.sort();
v.dedup_by(|(k0, _), (k1, _)| k0 == k1);
set_of_vecs.push(v);
}
let mut set_of_arenas: Vec<OrdArena<P1, u32, u64>> = vec![];
for v in &set_of_vecs {
set_of_arenas.push(OrdArena::from_iter(v.iter().copied()))
}
set_of_vecs.sort();
// first use `PartialOrd`
let mut tmp = set_of_arenas.clone();
tmp.sort_by(|a, b| a.partial_cmp(b).unwrap());
let res: Vec<Vec<(u32, u64)>> = tmp
.iter()
.map(|a| a.iter().map(|(_, k, v)| (*k, *v)).collect())
.collect();
assert_eq!(set_of_vecs, res);
// use `Ord`
set_of_arenas.sort();
let res: Vec<Vec<(u32, u64)>> = set_of_arenas
.iter()
.map(|a| a.iter().map(|(_, k, v)| (*k, *v)).collect())
.collect();
assert_eq!(set_of_vecs, res);
}
Loading

0 comments on commit 858b461

Please sign in to comment.