From 9d00f05f1c38e9588b50c2241c912e5209c759bc Mon Sep 17 00:00:00 2001 From: "Tim \"S.D.Eagle\" Zeitz" Date: Tue, 6 Jul 2021 11:31:22 +0200 Subject: [PATCH 1/4] more refactoring --- rustfmt.toml | 1 + src/bin/compare_vector.rs | 79 ++++++++++++++++++++------------------- src/bin/decode_vector.rs | 63 ++++++++++++++----------------- src/bin/encode_vector.rs | 53 ++++++++++++-------------- 4 files changed, 93 insertions(+), 103 deletions(-) create mode 100644 rustfmt.toml diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 0000000..b28d8cf --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1 @@ +max_width = 160 diff --git a/src/bin/compare_vector.rs b/src/bin/compare_vector.rs index 0a18492..9aab030 100644 --- a/src/bin/compare_vector.rs +++ b/src/bin/compare_vector.rs @@ -1,45 +1,38 @@ -use stud_rust_base::{io::*, cli::CliErr}; -use std::{env, fmt::Display, error::Error}; +use std::{env, error::Error, fmt::Display}; +use stud_rust_base::{cli::CliErr, io::*}; fn main() -> Result<(), Box> { - match &env::args().skip(1).collect::>()[..] { - [data_type, input1, input2] => { + let mut args = env::args().skip(1); + match &(args.next(), args.next(), args.next()) { + (Some(data_type), Some(input1), Some(input2)) => { match data_type.as_ref() { - "i8" => { compare_values(&Vec::::load_from(input1)?, &Vec::::load_from(input2)?); Ok(()) }, - "u8" => { compare_values(&Vec::::load_from(input1)?, &Vec::::load_from(input2)?); Ok(()) }, - "i16" => { compare_values(&Vec::::load_from(input1)?, &Vec::::load_from(input2)?); Ok(()) }, - "u16" => { compare_values(&Vec::::load_from(input1)?, &Vec::::load_from(input2)?); Ok(()) }, - "i32" => { compare_values(&Vec::::load_from(input1)?, &Vec::::load_from(input2)?); Ok(()) }, - "u32" => { compare_values(&Vec::::load_from(input1)?, &Vec::::load_from(input2)?); Ok(()) }, - "i64" => { compare_values(&Vec::::load_from(input1)?, &Vec::::load_from(input2)?); Ok(()) }, - "u64" => { compare_values(&Vec::::load_from(input1)?, &Vec::::load_from(input2)?); Ok(()) }, - "f32" => { compare_values(&Vec::::load_from(input1)?, &Vec::::load_from(input2)?); Ok(()) }, - "f64" => { compare_values(&Vec::::load_from(input1)?, &Vec::::load_from(input2)?); Ok(()) }, - "int8" => { compare_values(&Vec::::load_from(input1)?, &Vec::::load_from(input2)?); Ok(()) }, - "uint8" => { compare_values(&Vec::::load_from(input1)?, &Vec::::load_from(input2)?); Ok(()) }, - "int16" => { compare_values(&Vec::::load_from(input1)?, &Vec::::load_from(input2)?); Ok(()) }, - "uint16" => { compare_values(&Vec::::load_from(input1)?, &Vec::::load_from(input2)?); Ok(()) }, - "int32" => { compare_values(&Vec::::load_from(input1)?, &Vec::::load_from(input2)?); Ok(()) }, - "uint32" => { compare_values(&Vec::::load_from(input1)?, &Vec::::load_from(input2)?); Ok(()) }, - "int64" => { compare_values(&Vec::::load_from(input1)?, &Vec::::load_from(input2)?); Ok(()) }, - "uint64" => { compare_values(&Vec::::load_from(input1)?, &Vec::::load_from(input2)?); Ok(()) }, - "float32" => { compare_values(&Vec::::load_from(input1)?, &Vec::::load_from(input2)?); Ok(()) }, - "float64" => { compare_values(&Vec::::load_from(input1)?, &Vec::::load_from(input2)?); Ok(()) }, + "i8" | "int8" => compare_values::(&Vec::load_from(input1)?, &Vec::load_from(input2)?), + "u8" | "uint8" => compare_values::(&Vec::load_from(input1)?, &Vec::load_from(input2)?), + "i16" | "int16" => compare_values::(&Vec::load_from(input1)?, &Vec::load_from(input2)?), + "u16" | "uint16" => compare_values::(&Vec::load_from(input1)?, &Vec::load_from(input2)?), + "i32" | "int32" => compare_values::(&Vec::load_from(input1)?, &Vec::load_from(input2)?), + "u32" | "uint32" => compare_values::(&Vec::load_from(input1)?, &Vec::load_from(input2)?), + "i64" | "int64" => compare_values::(&Vec::load_from(input1)?, &Vec::load_from(input2)?), + "u64" | "uint64" => compare_values::(&Vec::load_from(input1)?, &Vec::load_from(input2)?), + "f32" | "float32" => compare_values::(&Vec::load_from(input1)?, &Vec::load_from(input2)?), + "f64" | "float64" => compare_values::(&Vec::load_from(input1)?, &Vec::load_from(input2)?), _ => { print_usage(); - Err(Box::new(CliErr("Invalid data type"))) + return Err(Box::new(CliErr("Invalid data type"))); } - } - }, + }; + Ok(()) + } _ => { print_usage(); Err(Box::new(CliErr("Invalid arguments"))) - }, + } } } fn print_usage() { - eprintln!("Usage: decode_vector data_type vector1_file vector2_file + eprintln!( + "Usage: decode_vector data_type vector1_file vector2_file Compares two vectors of elements in binary format. data_type can be one of * i8 @@ -53,17 +46,23 @@ Compares two vectors of elements in binary format. data_type can be one of * f32 * f64 -"); +" + ); } -fn compare_values(values1: &[T], values2: &[T]) where +fn compare_values(values1: &[T], values2: &[T]) +where T: Display, - T: PartialOrd + T: PartialOrd, { if values1.len() != values2.len() { println!("0"); - eprintln!("Can only compare vectors of equal size. The first vector has {} elements. The second vector has {} elements.", values1.len(), values2.len()); - return + eprintln!( + "Can only compare vectors of equal size. The first vector has {} elements. The second vector has {} elements.", + values1.len(), + values2.len() + ); + return; } let mut v1_smaller_count = 0; @@ -71,8 +70,12 @@ fn compare_values(values1: &[T], values2: &[T]) where let mut first_diff = None; for (i, (v1, v2)) in values1.iter().zip(values2.iter()).enumerate() { - if v1 < v2 { v1_smaller_count += 1; } - if v2 < v1 { v2_smaller_count += 1; } + if v1 < v2 { + v1_smaller_count += 1; + } + if v2 < v1 { + v2_smaller_count += 1; + } if first_diff.is_none() && v1 != v2 { first_diff = Some(i) @@ -89,10 +92,10 @@ fn compare_values(values1: &[T], values2: &[T]) where eprintln!("{} elements are different.", v1_smaller_count + v2_smaller_count); eprintln!("The vectors have {} elements.", values1.len()); eprintln!("The first element that differs is at index {}.", index); - }, + } None => { println!("{}", values1.len()); eprintln!("The vectors are the same and have {} elements.", values1.len()); - }, + } } } diff --git a/src/bin/decode_vector.rs b/src/bin/decode_vector.rs index 68d5bb2..6169732 100644 --- a/src/bin/decode_vector.rs +++ b/src/bin/decode_vector.rs @@ -1,45 +1,36 @@ -use stud_rust_base::{io::*, cli::CliErr}; use std::{env, error::Error}; +use stud_rust_base::{cli::CliErr, io::*}; fn main() -> Result<(), Box> { - match &env::args().skip(1).collect::>()[..] { - [data_type, input] => { - match data_type.as_ref() { - "i8" => { print_values(Vec::::load_from(input)?); Ok(()) }, - "u8" => { print_values(Vec::::load_from(input)?); Ok(()) }, - "i16" => { print_values(Vec::::load_from(input)?); Ok(()) }, - "u16" => { print_values(Vec::::load_from(input)?); Ok(()) }, - "i32" => { print_values(Vec::::load_from(input)?); Ok(()) }, - "u32" => { print_values(Vec::::load_from(input)?); Ok(()) }, - "i64" => { print_values(Vec::::load_from(input)?); Ok(()) }, - "u64" => { print_values(Vec::::load_from(input)?); Ok(()) }, - "f32" => { print_values(Vec::::load_from(input)?); Ok(()) }, - "f64" => { print_values(Vec::::load_from(input)?); Ok(()) }, - "int8" => { print_values(Vec::::load_from(input)?); Ok(()) }, - "uint8" => { print_values(Vec::::load_from(input)?); Ok(()) }, - "int16" => { print_values(Vec::::load_from(input)?); Ok(()) }, - "uint16" => { print_values(Vec::::load_from(input)?); Ok(()) }, - "int32" => { print_values(Vec::::load_from(input)?); Ok(()) }, - "uint32" => { print_values(Vec::::load_from(input)?); Ok(()) }, - "int64" => { print_values(Vec::::load_from(input)?); Ok(()) }, - "uint64" => { print_values(Vec::::load_from(input)?); Ok(()) }, - "float32" => { print_values(Vec::::load_from(input)?); Ok(()) }, - "float64" => { print_values(Vec::::load_from(input)?); Ok(()) }, - _ => { - print_usage(); - Err(Box::new(CliErr("Invalid data type"))) - } + let mut args = env::args().skip(1); + match (args.next(), args.next()) { + (Some(data_type), Some(ref input)) => match data_type.as_ref() { + "i8" | "int8" => print_values(Vec::::load_from(input)?), + "u8" | "uint8" => print_values(Vec::::load_from(input)?), + "i16" | "int16" => print_values(Vec::::load_from(input)?), + "u16" | "uint16" => print_values(Vec::::load_from(input)?), + "i32" | "int32" => print_values(Vec::::load_from(input)?), + "u32" | "uint32" => print_values(Vec::::load_from(input)?), + "i64" | "int64" => print_values(Vec::::load_from(input)?), + "u64" | "uint64" => print_values(Vec::::load_from(input)?), + "f32" | "float32" => print_values(Vec::::load_from(input)?), + "f64" | "float64" => print_values(Vec::::load_from(input)?), + _ => { + print_usage(); + return Err(Box::new(CliErr("Invalid data type"))); } }, _ => { print_usage(); - Err(Box::new(CliErr("Invalid arguments"))) - }, - } + return Err(Box::new(CliErr("Invalid arguments"))); + } + }; + Ok(()) } fn print_usage() { - eprintln!("Usage: decode_vector data_type input_vector_file + eprintln!( + "Usage: decode_vector data_type input_vector_file Reads binary data from input_vector_file and writes the data to the standard output. data_type can be one of * i8 @@ -53,13 +44,15 @@ Reads binary data from input_vector_file and writes the data to the standard out * f32 * f64 -"); +" + ); } use std::fmt::Display; -fn print_values(values: Vec) where - T: Display +fn print_values(values: Vec) +where + T: Display, { for v in values { println!("{}", v); diff --git a/src/bin/encode_vector.rs b/src/bin/encode_vector.rs index d8235bd..a56eb82 100644 --- a/src/bin/encode_vector.rs +++ b/src/bin/encode_vector.rs @@ -1,40 +1,32 @@ -use stud_rust_base::{io::*, cli::CliErr}; use std::{env, error::Error}; +use stud_rust_base::{cli::CliErr, io::*}; fn main() -> Result<(), Box> { - match &env::args().skip(1).collect::>()[..] { - [data_type, output] => { + let mut args = env::args().skip(1); + match (args.next(), args.next()) { + (Some(data_type), Some(ref output)) => { match data_type.as_ref() { - "i8" => { parse_input::()?.write_to(output)?; Ok(()) }, - "u8" => { parse_input::()?.write_to(output)?; Ok(()) }, - "i16" => { parse_input::()?.write_to(output)?; Ok(()) }, - "u16" => { parse_input::()?.write_to(output)?; Ok(()) }, - "i32" => { parse_input::()?.write_to(output)?; Ok(()) }, - "u32" => { parse_input::()?.write_to(output)?; Ok(()) }, - "i64" => { parse_input::()?.write_to(output)?; Ok(()) }, - "u64" => { parse_input::()?.write_to(output)?; Ok(()) }, - "f32" => { parse_input::()?.write_to(output)?; Ok(()) }, - "f64" => { parse_input::()?.write_to(output)?; Ok(()) }, - "int8" => { parse_input::()?.write_to(output)?; Ok(()) }, - "uint8" => { parse_input::()?.write_to(output)?; Ok(()) }, - "int16" => { parse_input::()?.write_to(output)?; Ok(()) }, - "uint16" => { parse_input::()?.write_to(output)?; Ok(()) }, - "int32" => { parse_input::()?.write_to(output)?; Ok(()) }, - "uint32" => { parse_input::()?.write_to(output)?; Ok(()) }, - "int64" => { parse_input::()?.write_to(output)?; Ok(()) }, - "uint64" => { parse_input::()?.write_to(output)?; Ok(()) }, - "float32" => { parse_input::()?.write_to(output)?; Ok(()) }, - "float64" => { parse_input::()?.write_to(output)?; Ok(()) }, + "i8" | "int8" => parse_input::()?.write_to(output)?, + "u8" | "uint8" => parse_input::()?.write_to(output)?, + "i16" | "int16" => parse_input::()?.write_to(output)?, + "u16" | "uint16" => parse_input::()?.write_to(output)?, + "i32" | "int32" => parse_input::()?.write_to(output)?, + "u32" | "uint32" => parse_input::()?.write_to(output)?, + "i64" | "int64" => parse_input::()?.write_to(output)?, + "u64" | "uint64" => parse_input::()?.write_to(output)?, + "f32" | "float32" => parse_input::()?.write_to(output)?, + "f64" | "float64" => parse_input::()?.write_to(output)?, _ => { print_usage(); - Err(Box::new(CliErr("Invalid data type"))) + return Err(Box::new(CliErr("Invalid data type"))); } - } - }, + }; + Ok(()) + } _ => { print_usage(); Err(Box::new(CliErr("Invalid arguments"))) - }, + } } } @@ -58,11 +50,12 @@ Reads textual data from the standard input and writes it in a binary format to o use std::str::FromStr; -fn parse_input() -> Result, Box> where +fn parse_input() -> Result, Box> +where T: FromStr, - ::Err: Error + 'static + ::Err: Error + 'static, { - use std::io::{BufRead, stdin}; + use std::io::{stdin, BufRead}; let mut values = Vec::new(); -- 2.34.1 From 0cce9e796127fea9c3387e05ce2c68a1eeb0a83c Mon Sep 17 00:00:00 2001 From: "Tim \"tim3z\" Zeitz" Date: Thu, 16 Dec 2021 10:46:05 +0100 Subject: [PATCH 2/4] remove time crate and use std lib --- src/time.rs | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/src/time.rs b/src/time.rs index 687f3e4..33c720c 100644 --- a/src/time.rs +++ b/src/time.rs @@ -1,28 +1,29 @@ //! This module contains a few utilities to measure how long executing algorithms takes. -//! It utilizes the `time` crate. + +use std::time::*; /// This function will measure how long it takes to execute the given lambda, /// print the time and return the result of the lambda. pub fn report_time Out>(name: &str, f: F) -> Out { - let start = time::now(); + let start = Instant::now(); eprintln!("starting {}", name); let res = f(); - eprintln!("done {} - took: {}", name, (time::now() - start)); + eprintln!("done {} - took: {}s", name, start.elapsed().as_secs_f64()); res } /// This function will measure how long it takes to execute the given lambda /// and return a tuple of the result of the lambda and a duration object. -pub fn measure Out>(f: F) -> (Out, time::Duration) { - let start = time::now(); +pub fn measure Out>(f: F) -> (Out, Duration) { + let start = Instant::now(); let res = f(); - (res, time::now() - start) + (res, start.elapsed()) } /// A struct to repeatedly measure the time passed since the timer was started #[derive(Debug)] pub struct Timer { - start: time::Tm + start: Instant, } impl Default for Timer { @@ -34,21 +35,26 @@ impl Default for Timer { impl Timer { /// Create and start a new `Timer` pub fn new() -> Timer { - Timer { start: time::now() } + Timer { start: Instant::now() } } /// Reset the `Timer` pub fn restart(&mut self) { - self.start = time::now(); + self.start = Instant::now(); } /// Print the passed time in ms since the timer was started pub fn report_passed_ms(&self) { - eprintln!("{}ms", (time::now() - self.start).num_milliseconds()); + eprintln!("{}ms", self.start.elapsed().as_secs_f64() * 1000.0); } /// Return the number of ms passed since the timer was started as a `i64` - pub fn get_passed_ms(&self) -> i64 { - (time::now() - self.start).num_milliseconds() + pub fn get_passed_ms(&self) -> f64 { + self.start.elapsed().as_secs_f64() * 1000.0 + } + + /// Return the number of ms passed since the timer was started as a `std::time::Duration` + pub fn get_passed(&self) -> Duration { + self.start.elapsed() } } -- 2.34.1 From 06c34a2e9b80e195c51932f62a99cce4f0110000 Mon Sep 17 00:00:00 2001 From: "Tim \"tim3z\" Zeitz" Date: Thu, 16 Dec 2021 10:46:28 +0100 Subject: [PATCH 3/4] make heap api more robust --- src/index_heap.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/index_heap.rs b/src/index_heap.rs index 477dc87..5850ae8 100644 --- a/src/index_heap.rs +++ b/src/index_heap.rs @@ -123,19 +123,19 @@ impl IndexdMinHeap { } /// Updates the key of an element if the new key is smaller than the old key. - /// Does nothing if the new key is larger. - /// Panics if the element is not part of the queue. + /// Panics if the element is not part of the queue or if the new key is larger. pub fn decrease_key(&mut self, element: T) { let position = self.positions[element.as_index()]; + assert!(element <= self.data[position]); self.data[position] = element; self.move_up_in_tree(position); } /// Updates the key of an element if the new key is larger than the old key. - /// Does nothing if the new key is smaller. - /// Panics if the element is not part of the queue. + /// Panics if the element is not part of the queue or if the new key is smaller. pub fn increase_key(&mut self, element: T) { let position = self.positions[element.as_index()]; + assert!(element >= self.data[position]); self.data[position] = element; self.move_down_in_tree(position); } -- 2.34.1 From 3f62b84a17b4e656eba2156ebf30f6f2eeef5c55 Mon Sep 17 00:00:00 2001 From: "Tim \"tim3z\" Zeitz" Date: Thu, 16 Dec 2021 10:47:11 +0100 Subject: [PATCH 4/4] updates, clippy, formatting --- Cargo.lock | 48 +--------------------------------------------- Cargo.toml | 5 +---- src/bin/example.rs | 2 +- src/index_heap.rs | 11 ++--------- src/io.rs | 2 +- 5 files changed, 6 insertions(+), 62 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2d33e1d..b98a97a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,53 +1,7 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -[[package]] -name = "libc" -version = "0.2.80" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d58d1b70b004888f764dfbf6a26a3b0342a1632d33968e4a179d8011c760614" +version = 3 [[package]] name = "stud-rust-base" version = "0.1.0" -dependencies = [ - "time", -] - -[[package]] -name = "time" -version = "0.1.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" -dependencies = [ - "libc", - "wasi", - "winapi", -] - -[[package]] -name = "wasi" -version = "0.10.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/Cargo.toml b/Cargo.toml index 344beb8..42ddd25 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,4 @@ name = "stud-rust-base" version = "0.1.0" authors = ["Tim Zeitz "] -edition = '2018' - -[dependencies] -time = "^0.1.40" +edition = '2021' diff --git a/src/bin/example.rs b/src/bin/example.rs index 667bff3..e1eb51f 100644 --- a/src/bin/example.rs +++ b/src/bin/example.rs @@ -3,7 +3,7 @@ use stud_rust_base::{io::*, time::report_time, types::*}; use std::{env, error::Error, path::Path}; fn main() -> Result<(), Box> { - let arg = &env::args().skip(1).next().expect("No directory arg given"); + let arg = &env::args().nth(1).expect("No directory arg given"); let path = Path::new(arg); let first_out = Vec::::load_from(path.join("first_out"))?; diff --git a/src/index_heap.rs b/src/index_heap.rs index 5850ae8..2c6f613 100644 --- a/src/index_heap.rs +++ b/src/index_heap.rs @@ -168,10 +168,7 @@ impl IndexdMinHeap { let mut hole = Hole::new(&mut self.data, position); loop { - if let Some(smallest_child) = - IndexdMinHeap::::children_index_range(position, heap_size) - .min_by_key(|&child_index| hole.get(child_index)) - { + if let Some(smallest_child) = IndexdMinHeap::::children_index_range(position, heap_size).min_by_key(|&child_index| hole.get(child_index)) { if hole.get(smallest_child) >= hole.element() { self.positions[hole.element().as_index()] = position; return; // no child is smaller @@ -218,11 +215,7 @@ impl<'a, T> Hole<'a, T> { unsafe fn new(data: &'a mut [T], pos: usize) -> Self { debug_assert!(pos < data.len()); let elt = ptr::read(&data[pos]); - Hole { - data, - elt: Some(elt), - pos, - } + Hole { data, elt: Some(elt), pos } } /// Returns a reference to the element removed. diff --git a/src/io.rs b/src/io.rs index 52057af..3c4d732 100644 --- a/src/io.rs +++ b/src/io.rs @@ -51,7 +51,7 @@ impl DataBytes for [T] { impl DataBytes for Vec { fn data_bytes(&self) -> &[u8] { - &self[..].data_bytes() + self[..].data_bytes() } } -- 2.34.1