cleaning...\ncleaning out my work computer
This commit is contained in:
parent
2953b18df7
commit
4302adad55
103
src/main.rs
103
src/main.rs
@ -1,13 +1,17 @@
|
|||||||
|
use std::hint::black_box;
|
||||||
use std::io::{stderr, Write};
|
use std::io::{stderr, Write};
|
||||||
|
use std::sync::{Arc, RwLock};
|
||||||
use std::thread::{self, sleep};
|
use std::thread::{self, sleep};
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
|
|
||||||
use num_format::{Locale, ToFormattedString};
|
use num_format::{Locale, ToFormattedString};
|
||||||
|
|
||||||
const ALL_CHARS: &'static str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789,.<>/?;':\"[]{}\\|-=_+`~!@#$%^&*()";
|
const ALL_CHARS_95: &'static str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789,.<>/?;':\"[]{}\\|-=_+`~!@#$%^&*() ";
|
||||||
const LEN: usize = 4;
|
// const ALL_ALPHA: &'static str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||||
|
// const ALL_ALPHA_NUM: &'static str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||||
|
|
||||||
|
const LEN: usize = 8;
|
||||||
|
|
||||||
static mut SOFAR: u128 = 0;
|
|
||||||
static mut TOTAL: usize = 0;
|
static mut TOTAL: usize = 0;
|
||||||
|
|
||||||
/// Pseudo main
|
/// Pseudo main
|
||||||
@ -19,8 +23,29 @@ fn start(char_list: &str, output_len: usize) {
|
|||||||
/// Flag to communicate between main (combination crunching) and
|
/// Flag to communicate between main (combination crunching) and
|
||||||
/// timer threads.
|
/// timer threads.
|
||||||
static mut IS_DONE: bool = false;
|
static mut IS_DONE: bool = false;
|
||||||
|
/// Seconds between the calculating p/s and percentage done.
|
||||||
|
const CHECK_IN_DELAY: u64 = 1;
|
||||||
|
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
|
// Try multithreading...
|
||||||
|
let mut tasks = Vec::new();
|
||||||
|
let mut counters = Vec::new();
|
||||||
|
let mut buffers = Vec::new();
|
||||||
|
|
||||||
|
// Start threads
|
||||||
|
for i in char_list.chars() {
|
||||||
|
let counter = Arc::new(RwLock::new(0u128));
|
||||||
|
let buffer = Arc::new(RwLock::new(Vec::new()));
|
||||||
|
|
||||||
|
counters.push(counter.clone());
|
||||||
|
buffers.push(buffer.clone());
|
||||||
|
|
||||||
|
let copy = char_list.to_owned();
|
||||||
|
let worker = thread::spawn(move || {
|
||||||
|
calc(©, &i.to_string(), output_len, counter, buffer);
|
||||||
|
});
|
||||||
|
tasks.push(worker);
|
||||||
|
}
|
||||||
|
|
||||||
// Just to report stats
|
// Just to report stats
|
||||||
let timer = thread::spawn(move || {
|
let timer = thread::spawn(move || {
|
||||||
@ -31,40 +56,36 @@ fn start(char_list: &str, output_len: usize) {
|
|||||||
// prevent div by zero err
|
// prevent div by zero err
|
||||||
if elapsed == 0 { elapsed = 1; }
|
if elapsed == 0 { elapsed = 1; }
|
||||||
|
|
||||||
let sofar = unsafe {SOFAR};
|
let mut sofar =0;
|
||||||
|
for ele in &counters {
|
||||||
|
sofar += *ele.read().unwrap();
|
||||||
|
};
|
||||||
|
|
||||||
|
// This doesn't free the memory fast enough! // FIXME
|
||||||
|
for i in &buffers {
|
||||||
|
for j in &*i.read().unwrap() {
|
||||||
|
let x = j;
|
||||||
|
black_box(x);
|
||||||
|
}
|
||||||
|
// prevent memory footprint from getting too big
|
||||||
|
i.write().unwrap().clear();
|
||||||
|
println!("clear")
|
||||||
|
}
|
||||||
|
|
||||||
// output P/s
|
// output P/s
|
||||||
let _ = out.write(
|
let _ = out.write(
|
||||||
format!("\rCalculated {} possibilities thus far, at {} p/s",
|
format!("\rCalculated {}, at {}p/s, {:.5}%",
|
||||||
sofar.to_formatted_string(&Locale::en_NA),
|
sofar.to_formatted_string(&Locale::en_NA),
|
||||||
(sofar / elapsed).to_formatted_string(&Locale::en_NA),
|
(sofar / elapsed).to_formatted_string(&Locale::en_NA),
|
||||||
|
sofar as f64 / unsafe { TOTAL as f64 } * 100f64,
|
||||||
).as_bytes());
|
).as_bytes());
|
||||||
let _ = out.flush();
|
let _ = out.flush();
|
||||||
sleep(Duration::from_secs(1));
|
sleep(Duration::from_secs(CHECK_IN_DELAY));
|
||||||
|
};
|
||||||
/*
|
|
||||||
// output remaining time
|
|
||||||
// I haven't tested to see if this timer is somewhat accurate...
|
|
||||||
// This is code I stole of reddit... what am I doing?
|
|
||||||
let remaining = unsafe { TOTAL as u128 / (sofar / elapsed) };
|
|
||||||
let sec = remaining % 60;
|
|
||||||
let min = (remaining / 60) % 60;
|
|
||||||
let hrs = (remaining / 60) / 60;
|
|
||||||
|
|
||||||
let _ = out.write(
|
|
||||||
// TODO clear the whole line, don't just put cursor to the begining...
|
|
||||||
format!("\r{}%, {}h:{}m:{}s remaining ",
|
|
||||||
unsafe { sofar / TOTAL as u128 },
|
|
||||||
hrs, min, sec
|
|
||||||
).as_bytes());
|
|
||||||
let _ = out.flush();
|
|
||||||
sleep(Duration::from_secs(1));
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// starting with the blank string is important
|
// Block waiting for all the tasks to finish
|
||||||
calc(char_list, &"", output_len);
|
for i in tasks {i.join().unwrap();}
|
||||||
|
|
||||||
unsafe { IS_DONE = true; }
|
unsafe { IS_DONE = true; }
|
||||||
timer.join().unwrap();
|
timer.join().unwrap();
|
||||||
|
|
||||||
@ -75,17 +96,17 @@ fn main() {
|
|||||||
// All the status messages are printed on stderr
|
// All the status messages are printed on stderr
|
||||||
// This way you can pipe the actual permutations into
|
// This way you can pipe the actual permutations into
|
||||||
// a file whilst still getting debug messages.
|
// a file whilst still getting debug messages.
|
||||||
let t = (ALL_CHARS.len() as u128).pow(LEN.try_into().unwrap());
|
let t = (ALL_CHARS_95.len() as u128).pow(LEN.try_into().unwrap());
|
||||||
unsafe { TOTAL = t as usize };
|
unsafe { TOTAL = t as usize };
|
||||||
eprintln!(
|
eprintln!(
|
||||||
"Calculating {} combinations...\n(Number may be trunkated if too large)\n",
|
"Calculating {} combinations...\n(Number may be truncated if too large)\n",
|
||||||
unsafe { TOTAL }.to_formatted_string(&Locale::en_NA)
|
unsafe { TOTAL }.to_formatted_string(&Locale::en_NA)
|
||||||
);
|
);
|
||||||
|
|
||||||
start(ALL_CHARS, LEN);
|
start(ALL_CHARS_95, LEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Recurseively create and print every combination of
|
/// Recursively create and print every combination of
|
||||||
/// `choices` chars inside a string of `len` length.
|
/// `choices` chars inside a string of `len` length.
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
@ -94,23 +115,29 @@ fn main() {
|
|||||||
///
|
///
|
||||||
/// * `prefix` should be a blank string `""` unless you
|
/// * `prefix` should be a blank string `""` unless you
|
||||||
/// actually want a prefix on every output. This variable is
|
/// actually want a prefix on every output. This variable is
|
||||||
/// mainly used within the recursive nature of the funciton.
|
/// mainly used within the recursive nature of the function.
|
||||||
///
|
///
|
||||||
/// * `len` the size that all the output strings wil be.
|
/// * `len` the size that all the output strings wil be.
|
||||||
fn calc(choices: &str, prefix: &str, len: usize) {
|
///
|
||||||
|
/// * `counter` what to count into
|
||||||
|
fn calc(choices: &str, prefix: &str, len: usize, counter: Arc<RwLock<u128>>, buffer: Arc<RwLock<Vec<String>>>) {
|
||||||
let need_to_fill = len - prefix.len();
|
let need_to_fill = len - prefix.len();
|
||||||
match need_to_fill {
|
match need_to_fill {
|
||||||
// the last char in the sequence, time to print
|
// the last char in the sequence, time to print
|
||||||
1 => {
|
1 => {
|
||||||
for i in choices.chars() {
|
for i in choices.chars() {
|
||||||
println!("{}{}", prefix, i);
|
// This line causes a 10x slowdown
|
||||||
unsafe { SOFAR = SOFAR + 1 };
|
buffer.write().unwrap().push(format!("{}{}", prefix, i));
|
||||||
|
|
||||||
|
// Needs to be in two lines like this, otherwise the write blocks on the read.
|
||||||
|
let temp = *counter.read().unwrap();
|
||||||
|
*counter.write().unwrap() = temp+1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// need to recurse farther into the sequence
|
// need to recurse farther into the sequence
|
||||||
_ => {
|
_ => {
|
||||||
for i in choices.chars() {
|
for i in choices.chars() {
|
||||||
calc(choices, &(prefix.to_string() + &i.to_string()), len);
|
calc(choices, &(prefix.to_string() + &i.to_string()), len, counter.clone(), buffer.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user