update code
This commit is contained in:
parent
e58a65369b
commit
1542e5bf48
8 changed files with 87 additions and 40 deletions
3
examples/.gitignore
vendored
Normal file
3
examples/.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
# these files are auto-derived from the skiplist example
|
||||
skiplist-1-4.p3l
|
||||
skiplist-3-8.p3l
|
|
@ -239,19 +239,20 @@ fn skiplist_insert<V>(
|
|||
|
||||
// NOT PUBLIC API
|
||||
// Find a value in the skiplist, starting the search at a specific node.
|
||||
// Return the value along with the path length of the search.
|
||||
fn skiplist_get_impl<V>(
|
||||
node: SkipListNode<V>,
|
||||
key: int
|
||||
) -> (Option<V>, int) {
|
||||
let steps: int = 1;
|
||||
let pathlen: int = 1;
|
||||
|
||||
if (*node).3 < key {
|
||||
while true {
|
||||
if let Some(next) = (*node).2 {
|
||||
let next_key: int = (*next).3;
|
||||
steps = steps + 1;
|
||||
if next_key <= key {
|
||||
node = next;
|
||||
pathlen = pathlen + 1;
|
||||
if next_key == key {
|
||||
break;
|
||||
} else {
|
||||
|
@ -270,26 +271,26 @@ fn skiplist_get_impl<V>(
|
|||
}
|
||||
|
||||
if (*node).3 != key {
|
||||
return (None, steps);
|
||||
return (None, pathlen);
|
||||
}
|
||||
|
||||
// the value is only stored at the lowest level
|
||||
while let Some(below) = (*node).1 {
|
||||
node = below;
|
||||
}
|
||||
return (Some(unwrap::<V>((*node).4)), steps);
|
||||
return (Some(unwrap::<V>((*node).4)), pathlen);
|
||||
}
|
||||
|
||||
// Find a value in the skiplist.
|
||||
// Find a value in the skiplist. Return the value along with the path
|
||||
// length of the search.
|
||||
fn skiplist_get<V>(list: SkipList<V>, key: int) -> (Option<V>, int) {
|
||||
let steps: int = 0;
|
||||
let pathlen: int = 0;
|
||||
|
||||
while true {
|
||||
if let Some(node) = list.2 {
|
||||
steps = steps + 1;
|
||||
if (*node).3 <= key {
|
||||
let tmp: (Option<V>, int) = skiplist_get_impl::<V>(node, key);
|
||||
return (tmp.0, steps + tmp.1);
|
||||
return (tmp.0, pathlen + tmp.1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -298,7 +299,7 @@ fn skiplist_get<V>(list: SkipList<V>, key: int) -> (Option<V>, int) {
|
|||
continue;
|
||||
}
|
||||
|
||||
return (None, steps);
|
||||
return (None, pathlen);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -375,8 +376,8 @@ let _unit: () = assert_in_range(key, 0, len);
|
|||
let lookup: (Option<()>, int) = skiplist_get::<()>(list, key);
|
||||
let _unit: () = unwrap::<()>(lookup.0);
|
||||
|
||||
let steps: int = lookup.1;
|
||||
let pathlen: int = lookup.1;
|
||||
let lvl: int = skiplist_level::<()>(list);
|
||||
|
||||
output!(len);
|
||||
output!(lvl, steps);
|
||||
output!(lvl, pathlen);
|
||||
|
|
|
@ -239,19 +239,20 @@ fn skiplist_insert<V>(
|
|||
|
||||
// NOT PUBLIC API
|
||||
// Find a value in the skiplist, starting the search at a specific node.
|
||||
// Return the value along with the path length of the search.
|
||||
fn skiplist_get_impl<V>(
|
||||
node: SkipListNode<V>,
|
||||
key: int
|
||||
) -> (Option<V>, int) {
|
||||
let steps: int = 1;
|
||||
let pathlen: int = 1;
|
||||
|
||||
if (*node).3 < key {
|
||||
while true {
|
||||
if let Some(next) = (*node).2 {
|
||||
let next_key: int = (*next).3;
|
||||
steps = steps + 1;
|
||||
if next_key <= key {
|
||||
node = next;
|
||||
pathlen = pathlen + 1;
|
||||
if next_key == key {
|
||||
break;
|
||||
} else {
|
||||
|
@ -270,26 +271,26 @@ fn skiplist_get_impl<V>(
|
|||
}
|
||||
|
||||
if (*node).3 != key {
|
||||
return (None, steps);
|
||||
return (None, pathlen);
|
||||
}
|
||||
|
||||
// the value is only stored at the lowest level
|
||||
while let Some(below) = (*node).1 {
|
||||
node = below;
|
||||
}
|
||||
return (Some(unwrap::<V>((*node).4)), steps);
|
||||
return (Some(unwrap::<V>((*node).4)), pathlen);
|
||||
}
|
||||
|
||||
// Find a value in the skiplist.
|
||||
// Find a value in the skiplist. Return the value along with the path
|
||||
// length of the search.
|
||||
fn skiplist_get<V>(list: SkipList<V>, key: int) -> (Option<V>, int) {
|
||||
let steps: int = 0;
|
||||
let pathlen: int = 0;
|
||||
|
||||
while true {
|
||||
if let Some(node) = list.2 {
|
||||
steps = steps + 1;
|
||||
if (*node).3 <= key {
|
||||
let tmp: (Option<V>, int) = skiplist_get_impl::<V>(node, key);
|
||||
return (tmp.0, steps + tmp.1);
|
||||
return (tmp.0, pathlen + tmp.1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -298,7 +299,7 @@ fn skiplist_get<V>(list: SkipList<V>, key: int) -> (Option<V>, int) {
|
|||
continue;
|
||||
}
|
||||
|
||||
return (None, steps);
|
||||
return (None, pathlen);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -375,8 +376,8 @@ let _unit: () = assert_in_range(key, 0, len);
|
|||
let lookup: (Option<()>, int) = skiplist_get::<()>(list, key);
|
||||
let _unit: () = unwrap::<()>(lookup.0);
|
||||
|
||||
let steps: int = lookup.1;
|
||||
let pathlen: int = lookup.1;
|
||||
let lvl: int = skiplist_level::<()>(list);
|
||||
|
||||
output!(len);
|
||||
output!(lvl, steps);
|
||||
output!(lvl, pathlen);
|
||||
|
|
|
@ -239,19 +239,20 @@ fn skiplist_insert<V>(
|
|||
|
||||
// NOT PUBLIC API
|
||||
// Find a value in the skiplist, starting the search at a specific node.
|
||||
// Return the value along with the path length of the search.
|
||||
fn skiplist_get_impl<V>(
|
||||
node: SkipListNode<V>,
|
||||
key: int
|
||||
) -> (Option<V>, int) {
|
||||
let steps: int = 1;
|
||||
let pathlen: int = 1;
|
||||
|
||||
if (*node).3 < key {
|
||||
while true {
|
||||
if let Some(next) = (*node).2 {
|
||||
let next_key: int = (*next).3;
|
||||
steps = steps + 1;
|
||||
if next_key <= key {
|
||||
node = next;
|
||||
pathlen = pathlen + 1;
|
||||
if next_key == key {
|
||||
break;
|
||||
} else {
|
||||
|
@ -270,26 +271,26 @@ fn skiplist_get_impl<V>(
|
|||
}
|
||||
|
||||
if (*node).3 != key {
|
||||
return (None, steps);
|
||||
return (None, pathlen);
|
||||
}
|
||||
|
||||
// the value is only stored at the lowest level
|
||||
while let Some(below) = (*node).1 {
|
||||
node = below;
|
||||
}
|
||||
return (Some(unwrap::<V>((*node).4)), steps);
|
||||
return (Some(unwrap::<V>((*node).4)), pathlen);
|
||||
}
|
||||
|
||||
// Find a value in the skiplist.
|
||||
// Find a value in the skiplist. Return the value along with the path
|
||||
// length of the search.
|
||||
fn skiplist_get<V>(list: SkipList<V>, key: int) -> (Option<V>, int) {
|
||||
let steps: int = 0;
|
||||
let pathlen: int = 0;
|
||||
|
||||
while true {
|
||||
if let Some(node) = list.2 {
|
||||
steps = steps + 1;
|
||||
if (*node).3 <= key {
|
||||
let tmp: (Option<V>, int) = skiplist_get_impl::<V>(node, key);
|
||||
return (tmp.0, steps + tmp.1);
|
||||
return (tmp.0, pathlen + tmp.1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -298,7 +299,7 @@ fn skiplist_get<V>(list: SkipList<V>, key: int) -> (Option<V>, int) {
|
|||
continue;
|
||||
}
|
||||
|
||||
return (None, steps);
|
||||
return (None, pathlen);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -375,8 +376,8 @@ let _unit: () = assert_in_range(key, 0, len);
|
|||
let lookup: (Option<()>, int) = skiplist_get::<()>(list, key);
|
||||
let _unit: () = unwrap::<()>(lookup.0);
|
||||
|
||||
let steps: int = lookup.1;
|
||||
let pathlen: int = lookup.1;
|
||||
let lvl: int = skiplist_level::<()>(list);
|
||||
|
||||
output!(len);
|
||||
output!(lvl, steps);
|
||||
output!(lvl, pathlen);
|
||||
|
|
|
@ -258,10 +258,12 @@ impl Parse for Type {
|
|||
if input.peek(Paren) {
|
||||
let content;
|
||||
let paren_token = syn::parenthesized!(content in input);
|
||||
return Ok(Self::Tuple(TypeTuple {
|
||||
paren_token,
|
||||
elems: Punctuated::parse_terminated(&content)?
|
||||
}));
|
||||
let elems = Punctuated::parse_terminated(&content)?;
|
||||
return Ok(if elems.len() == 1 && !elems.trailing_punct() {
|
||||
elems.into_iter().next().unwrap()
|
||||
} else {
|
||||
Self::Tuple(TypeTuple { paren_token, elems })
|
||||
});
|
||||
}
|
||||
|
||||
let ident: Ident = input.parse()?;
|
||||
|
@ -348,8 +350,14 @@ mod tests {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn parse_tuple_1() {
|
||||
fn parse_paren_int() {
|
||||
let ty: Type = syn::parse_str("(int)").unwrap();
|
||||
assert!(matches!(ty, Type::Int(_)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_tuple_1() {
|
||||
let ty: Type = syn::parse_str("(int,)").unwrap();
|
||||
assert!(matches!(ty, Type::Tuple(_)));
|
||||
match ty {
|
||||
Type::Tuple(tuple) => {
|
||||
|
@ -376,6 +384,21 @@ mod tests {
|
|||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_tuple_2_trailing() {
|
||||
let ty: Type = syn::parse_str("(int, Option<int>,)").unwrap();
|
||||
assert!(matches!(ty, Type::Tuple(_)));
|
||||
match ty {
|
||||
Type::Tuple(tuple) => {
|
||||
let mut iter = tuple.elems.into_iter();
|
||||
assert!(matches!(iter.next(), Some(Type::Int(_))));
|
||||
assert!(matches!(iter.next(), Some(Type::Option(_))));
|
||||
assert!(iter.next().is_none());
|
||||
},
|
||||
_ => unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_rc() {
|
||||
let ty: Type = syn::parse_str("Rc<int>").unwrap();
|
||||
|
|
|
@ -101,7 +101,9 @@ impl<T> Rc<T> {
|
|||
pub fn new(inner: T) -> Self {
|
||||
Self(std::rc::Rc::new(std::cell::RefCell::new(inner)))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Rc<T> {
|
||||
pub fn into_inner(this: Rc<T>) -> T
|
||||
where
|
||||
T: Clone
|
||||
|
@ -111,7 +113,9 @@ impl<T> Rc<T> {
|
|||
Err(rc) => rc.borrow().clone()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Rc<T> {
|
||||
pub fn with_mut<F>(&mut self, callback: F)
|
||||
where
|
||||
F: FnOnce(&mut T)
|
||||
|
|
|
@ -135,6 +135,13 @@ impl OutputPrinter for BarChartPrinter {
|
|||
E: IntoIterator<Item = (&'static str, int)>,
|
||||
W: Write
|
||||
{
|
||||
writeln!(out, "<!--")?;
|
||||
writeln!(out, "Output Variable Analysis:")?;
|
||||
for (key, stats) in list.stats() {
|
||||
writeln!(out, " {key}: {stats:?}")?;
|
||||
}
|
||||
writeln!(out, "-->")?;
|
||||
|
||||
let mut yaxis = YAxis::default();
|
||||
let mut xaxis = XAxis::default();
|
||||
let mut xaxis_name = None;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use super::{OutputList, OutputPrinter, Svg};
|
||||
use crate::int;
|
||||
use indexmap::IndexMap;
|
||||
use num_integer::div_ceil;
|
||||
use std::{fmt::Write as _, io};
|
||||
use svgwriter::{
|
||||
tags::{
|
||||
|
@ -9,7 +10,6 @@ use svgwriter::{
|
|||
},
|
||||
Data, Transform
|
||||
};
|
||||
use num_integer::div_ceil;
|
||||
|
||||
/// Output printer for SVG Bar Charts. Works only with two
|
||||
/// output variables.
|
||||
|
@ -76,6 +76,13 @@ impl OutputPrinter for BubbleChartPrinter {
|
|||
E: IntoIterator<Item = (&'static str, int)>,
|
||||
W: io::Write
|
||||
{
|
||||
writeln!(out, "<!--")?;
|
||||
writeln!(out, "Output Variable Analysis:")?;
|
||||
for (key, stats) in list.stats() {
|
||||
writeln!(out, " {key}: {stats:?}")?;
|
||||
}
|
||||
writeln!(out, "-->")?;
|
||||
|
||||
let mut percentages = Vec::new();
|
||||
let mut min_percentage: f32 = 100.0;
|
||||
let mut max_percentage: f32 = 0.0;
|
||||
|
@ -103,7 +110,7 @@ impl OutputPrinter for BubbleChartPrinter {
|
|||
let bubble_min_r: f32 = 2.5;
|
||||
let bubble_max_r: f32 = 15.0;
|
||||
let axis_step_dist = 40;
|
||||
let (xaxis_step, xaxis_step_count) = xaxis.step(8);
|
||||
let (xaxis_step, xaxis_step_count) = xaxis.step(7);
|
||||
let (yaxis_step, yaxis_step_count) = yaxis.step(6);
|
||||
let chart_width = axis_step_dist * xaxis_step_count as i32;
|
||||
let chart_height = axis_step_dist * yaxis_step_count as i32;
|
||||
|
|
Reference in a new issue