From b98ead7d67d4779f4e70b47bdc08a72eb666cf9f Mon Sep 17 00:00:00 2001 From: "Tim \"S.D.Eagle\" Zeitz" Date: Tue, 3 Dec 2019 11:17:38 +0100 Subject: [PATCH 1/7] backport some nice things from routing engine and cleanup a bit --- README.md | 14 ++++++------- src/bin/example.rs | 27 +++++++++++++------------ src/cli.rs | 2 +- src/index_heap.rs | 27 ++++++++++++------------- src/io.rs | 50 ++++++++++++++++++++++++++-------------------- 5 files changed, 62 insertions(+), 58 deletions(-) diff --git a/README.md b/README.md index 7239043..59210f9 100644 --- a/README.md +++ b/README.md @@ -53,12 +53,11 @@ Die entsprechenden Funktionen sind über Traits definiert und können so direkt Das kann z.B. so aussehen: ```Rust -extern crate stud_rust_base; use stud_rust_base::io::*; -let head = Vec::::load_from("head_file_name").expect("could not read head"); -let lat = Vec::::load_from("node_latitude_file_name").expect("could not read lat"); -head.write_to("output_file").expect("could not write head"); +let head = Vec::::load_from("head_file_name")?; +let lat = Vec::::load_from("node_latitude_file_name")?; +head.write_to(&"output_file")?; ``` Die Dateien in `src/bin/` sind einmal ein Beispielprogramm sowieso Hilfsprogramme. @@ -79,12 +78,11 @@ Diese heißen `first_out`, `head` und `weight`. Um über die ausgehenden Kanten eines Knoten zu iterieren können Sie den folgenden Code verwenden: ```Rust -extern crate stud_rust_base; use stud_rust_base::{types::*, io::*}; -let first_out = Vec::::load_from("first_out_file_name").expect("could not read first_out"); -let head = Vec::::load_from("head_file_name").expect("could not read head"); -let travel_time = Vec::::load_from("weight_file_name").expect("could not read travel_time"); +let first_out = Vec::::load_from("first_out_file_name")?; +let head = Vec::::load_from("head_file_name")?; +let travel_time = Vec::::load_from("weight_file_name")?; let node_id = 42; for edge_id in first_out[node_id] .. first_out[node_id + 1] { diff --git a/src/bin/example.rs b/src/bin/example.rs index f8e9434..68056b8 100644 --- a/src/bin/example.rs +++ b/src/bin/example.rs @@ -1,28 +1,29 @@ -use stud_rust_base::{ - types::*, - io::*, - time::report_time, -}; +use stud_rust_base::{io::*, time::report_time, types::*}; -use std::{env, path::Path}; +use std::{env, error::Error, path::Path}; -fn main() { +fn main() -> Result<(), Box> { let mut args = env::args(); args.next(); let arg = &args.next().expect("No directory arg given"); let path = Path::new(arg); - let first_out = Vec::::load_from(path.join("first_out").to_str().unwrap()).expect("could not read first_out"); - let head = Vec::::load_from(path.join("head").to_str().unwrap()).expect("could not read head"); - let travel_time = Vec::::load_from(path.join("travel_time").to_str().unwrap()).expect("could not read travel_time"); + let first_out = Vec::::load_from(path.join("first_out"))?; + let head = Vec::::load_from(path.join("head"))?; + let travel_time = Vec::::load_from(path.join("travel_time"))?; report_time("iterating over arcs of some node", || { let node_id = 42; - for edge_id in first_out[node_id] .. first_out[node_id + 1] { - println!("There is an arc from {} to {} with weight {}", node_id, head[edge_id as usize], travel_time[edge_id as usize]); + for edge_id in first_out[node_id]..first_out[node_id + 1] { + println!( + "There is an arc from {} to {} with weight {}", + node_id, head[edge_id as usize], travel_time[edge_id as usize] + ); } }); - vec![42; 42].write_to(path.join("distances").to_str().unwrap()).expect("could not write distances"); + vec![42; 42].write_to(&path.join("distances"))?; + + Ok(()) } diff --git a/src/cli.rs b/src/cli.rs index e66421d..fc083d1 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -1,6 +1,6 @@ //! Utility module for command line interfaces -use std::{fmt, fmt::Display, error::Error}; +use std::{error::Error, fmt, fmt::Display}; /// An error struct to wrap simple static error messages #[derive(Debug)] diff --git a/src/index_heap.rs b/src/index_heap.rs index a7af9ca..477dc87 100644 --- a/src/index_heap.rs +++ b/src/index_heap.rs @@ -23,15 +23,13 @@ //! } //! } //! -//! fn main() { -//! let mut heap = IndexdMinHeap::new(3); -//! heap.push(State { node: 0, distance: 42 }); -//! heap.push(State { node: 1, distance: 23 }); -//! heap.push(State { node: 2, distance: 50000 }); -//! assert_eq!(heap.peek().cloned(), Some(State { node: 1, distance: 23 })); -//! heap.decrease_key(State { node: 0, distance: 1 }); -//! assert_eq!(heap.pop(), Some(State { node: 0, distance: 1 })); -//! } +//! let mut heap = IndexdMinHeap::new(3); +//! heap.push(State { node: 0, distance: 42 }); +//! heap.push(State { node: 1, distance: 23 }); +//! heap.push(State { node: 2, distance: 50000 }); +//! assert_eq!(heap.peek().cloned(), Some(State { node: 1, distance: 23 })); +//! heap.decrease_key(State { node: 0, distance: 1 }); +//! assert_eq!(heap.pop(), Some(State { node: 0, distance: 1 })); //! //! ``` @@ -55,7 +53,7 @@ pub trait Indexing { #[derive(Debug)] pub struct IndexdMinHeap { positions: Vec, - data: Vec + data: Vec, } const TREE_ARITY: usize = 4; @@ -68,7 +66,7 @@ impl IndexdMinHeap { pub fn new(max_index: usize) -> IndexdMinHeap { IndexdMinHeap { positions: vec![INVALID_POSITION; max_index], - data: Vec::new() + data: Vec::new(), } } @@ -170,7 +168,10 @@ 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 @@ -194,12 +195,10 @@ impl IndexdMinHeap { } } - // This is an optimization copied straight from the rust stdlib binary heap // it allows to avoid always swapping elements pairwise and rather // move each element only once. - /// Hole represents a hole in a slice i.e. an index without valid value /// (because it was moved from or duplicated). /// In drop, `Hole` will restore the slice by filling the hole diff --git a/src/io.rs b/src/io.rs index 419fa45..52057af 100644 --- a/src/io.rs +++ b/src/io.rs @@ -1,26 +1,26 @@ //! This module contains a few traits and blanket implementations -//! for (de)serializing and writing/reading numeric data to/from the disc. +//! for (de)serializing and writing/reading data to/from the disc. //! To use it you should import the `Load` and `Store` traits and use the //! `load_from` and `write_to` methods. //! //! # Example //! -//! ``` -//! use stud_rust_base::io::*; +//! ```no_run +//! # use stud_rust_base::io::*; //! -//! fn test() { -//! let head = Vec::::load_from("head_file_name").expect("could not read head"); -//! let lat = Vec::::load_from("node_latitude_file_name").expect("could not read lat"); -//! head.write_to("output_file").expect("could not write head"); -//! } +//! let head = Vec::::load_from("head_file_name")?; +//! let lat = Vec::::load_from("node_latitude_file_name")?; +//! head.write_to(&"output_file")?; +//! # Ok::<(), Box>(()) //! ``` -use std::fs; -use std::fs::File; -use std::io::prelude::*; -use std::io::Result; -use std::mem; -use std::slice; +use std::{ + fs::{metadata, File}, + io::{prelude::*, Result}, + mem, + path::Path, + slice, +}; /// A trait which allows accessing the data of an object as a slice of bytes. /// The bytes should represent a serialization of the object and allow @@ -49,6 +49,12 @@ impl DataBytes for [T] { } } +impl DataBytes for Vec { + fn data_bytes(&self) -> &[u8] { + &self[..].data_bytes() + } +} + impl DataBytesMut for [T] { fn data_bytes_mut(&mut self) -> &mut [u8] { let num_bytes = self.len() * mem::size_of::(); @@ -64,10 +70,10 @@ impl DataBytesMut for Vec { } /// A trait which extends the `DataBytes` trait and exposes a method to write objects to disk. -pub trait Store : DataBytes { - /// Writes the serialized object to the file with the given filename - fn write_to(&self, filename: &str) -> Result<()> { - File::create(filename)?.write_all(self.data_bytes()) +pub trait Store: DataBytes { + /// Writes the serialized object to the file with the given path + fn write_to(&self, path: &dyn AsRef) -> Result<()> { + File::create(path)?.write_all(self.data_bytes()) } } @@ -75,16 +81,16 @@ impl Store for T {} impl Store for [T] where [T]: DataBytes {} /// A trait to load serialized data back into objects. -pub trait Load : DataBytesMut + Sized { +pub trait Load: DataBytesMut + Sized { /// This method must create an object of the correct size for serialized data with the given number of bytes. /// It should not be necessary to call this method directly. fn new_with_bytes(num_bytes: usize) -> Self; /// This method will load serialized data from the disk, create an object of the appropriate size, /// deserialize the bytes into the object and return the object. - fn load_from(filename: &str) -> Result { - let metadata = fs::metadata(filename)?; - let mut file = File::open(filename)?; + fn load_from>(path: P) -> Result { + let metadata = metadata(path.as_ref())?; + let mut file = File::open(path)?; let mut object = Self::new_with_bytes(metadata.len() as usize); assert_eq!(metadata.len() as usize, object.data_bytes_mut().len()); -- 2.34.1 From 00434ae3ce1778ea5709d9267dcd37e52c2f4fa0 Mon Sep 17 00:00:00 2001 From: "Tim \"S.D.Eagle\" Zeitz" Date: Wed, 4 Nov 2020 10:17:31 +0100 Subject: [PATCH 2/7] update crates --- Cargo.lock | 42 ++++++++++++++++++++---------------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 52822a5..2d33e1d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,54 +2,52 @@ # It is not intended for manual editing. [[package]] name = "libc" -version = "0.2.62" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "redox_syscall" -version = "0.1.56" +version = "0.2.80" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58d1b70b004888f764dfbf6a26a3b0342a1632d33968e4a179d8011c760614" [[package]] name = "stud-rust-base" version = "0.1.0" dependencies = [ - "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", + "time", ] [[package]] name = "time" -version = "0.1.42" +version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" dependencies = [ - "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "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.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" dependencies = [ - "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "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" - -[metadata] -"checksum libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)" = "34fcd2c08d2f832f376f4173a231990fa5aef4e99fb569867318a227ef4c06ba" -"checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" -"checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" -"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" -"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -- 2.34.1 From 7e14e0703289af36efa95d687c71116a7a53a450 Mon Sep 17 00:00:00 2001 From: "Tim \"S.D.Eagle\" Zeitz" Date: Tue, 6 Jul 2021 11:13:48 +0200 Subject: [PATCH 3/7] refactor --- src/bin/compare_vector.rs | 5 +---- src/bin/decode_vector.rs | 5 +---- src/bin/encode_vector.rs | 5 +---- src/bin/example.rs | 5 +---- 4 files changed, 4 insertions(+), 16 deletions(-) diff --git a/src/bin/compare_vector.rs b/src/bin/compare_vector.rs index 2f566ed..0a18492 100644 --- a/src/bin/compare_vector.rs +++ b/src/bin/compare_vector.rs @@ -2,10 +2,7 @@ use stud_rust_base::{io::*, cli::CliErr}; use std::{env, fmt::Display, error::Error}; fn main() -> Result<(), Box> { - let mut args = env::args(); - args.next(); - - match &args.collect::>()[..] { + match &env::args().skip(1).collect::>()[..] { [data_type, input1, input2] => { match data_type.as_ref() { "i8" => { compare_values(&Vec::::load_from(input1)?, &Vec::::load_from(input2)?); Ok(()) }, diff --git a/src/bin/decode_vector.rs b/src/bin/decode_vector.rs index 4dca2e7..68d5bb2 100644 --- a/src/bin/decode_vector.rs +++ b/src/bin/decode_vector.rs @@ -2,10 +2,7 @@ use stud_rust_base::{io::*, cli::CliErr}; use std::{env, error::Error}; fn main() -> Result<(), Box> { - let mut args = env::args(); - args.next(); - - match &args.collect::>()[..] { + match &env::args().skip(1).collect::>()[..] { [data_type, input] => { match data_type.as_ref() { "i8" => { print_values(Vec::::load_from(input)?); Ok(()) }, diff --git a/src/bin/encode_vector.rs b/src/bin/encode_vector.rs index a51a63a..d8235bd 100644 --- a/src/bin/encode_vector.rs +++ b/src/bin/encode_vector.rs @@ -2,10 +2,7 @@ use stud_rust_base::{io::*, cli::CliErr}; use std::{env, error::Error}; fn main() -> Result<(), Box> { - let mut args = env::args(); - args.next(); - - match &args.collect::>()[..] { + match &env::args().skip(1).collect::>()[..] { [data_type, output] => { match data_type.as_ref() { "i8" => { parse_input::()?.write_to(output)?; Ok(()) }, diff --git a/src/bin/example.rs b/src/bin/example.rs index 68056b8..667bff3 100644 --- a/src/bin/example.rs +++ b/src/bin/example.rs @@ -3,10 +3,7 @@ use stud_rust_base::{io::*, time::report_time, types::*}; use std::{env, error::Error, path::Path}; fn main() -> Result<(), Box> { - let mut args = env::args(); - args.next(); - - let arg = &args.next().expect("No directory arg given"); + let arg = &env::args().skip(1).next().expect("No directory arg given"); let path = Path::new(arg); let first_out = Vec::::load_from(path.join("first_out"))?; -- 2.34.1 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 4/7] 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 5/7] 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 6/7] 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 7/7] 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