瀏覽代碼

Moved everthing to functions in lib.rs. Tests working.

themultiplexer 7 年之前
父節點
當前提交
74b26f3304
共有 3 個檔案被更改,包括 173 行新增148 行删除
  1. 146
    1
      hw8/task1/src/lib.rs
  2. 10
    142
      hw8/task1/src/main.rs
  3. 17
    5
      hw8/task1/src/tests/mod.rs

+ 146
- 1
hw8/task1/src/lib.rs 查看文件

@@ -1,6 +1,17 @@
1 1
 extern crate sha2;
2
+extern crate time;
3
+
4
+mod tests;
5
+
2 6
 #[cfg(feature = "SHA2")]
3 7
 use self::sha2::Sha256;
8
+use std::thread;
9
+use std::sync::Arc;
10
+use std::sync::atomic::AtomicBool;
11
+use std::sync::atomic::Ordering::Relaxed;
12
+use std::sync::mpsc::{Sender, channel};
13
+use time::{Duration, get_time};
14
+
4 15
 
5 16
 pub struct Sha256;
6 17
 
@@ -94,7 +105,7 @@ impl HashResult for [u8; 32] {
94 105
     }
95 106
 }
96 107
 
97
-
108
+#[derive(Debug,PartialEq)]
98 109
 pub struct Solution {
99 110
     pub number: usize,
100 111
     pub hash: String,
@@ -116,3 +127,137 @@ pub fn verify_product(base: usize, number: usize, difficulty: &String) -> Option
116 127
 
117 128
     None
118 129
 }
130
+
131
+
132
+pub fn search_with_threads(threads:usize, diff_string:String, with_base:usize, time_measurement:bool, verbosity:u64, sync:Option<usize>, wait:bool){
133
+    let total_start = get_time();
134
+    let diff = Arc::new(diff_string);
135
+    let mut children = vec![];
136
+
137
+    let (solution_tx, solution_rx) = channel();
138
+    let (timing_tx, timing_rx) = channel();
139
+
140
+    let found = Arc::new(AtomicBool::new(false));
141
+    let m = time_measurement && verbosity > 0;
142
+
143
+    if threads > 1 {
144
+
145
+        for i in 0..threads {
146
+            let diff = diff.clone();
147
+            let solution_tx = solution_tx.clone();
148
+            let timing_tx = timing_tx.clone();
149
+            let found = found.clone();
150
+
151
+            children.push(thread::spawn(move || {
152
+
153
+                search_hash(
154
+                    &diff,
155
+                    with_base,
156
+                    i,
157
+                    threads,
158
+                    sync.is_some(),
159
+                    found,
160
+                    sync.unwrap_or(1),
161
+                    solution_tx,
162
+                    timing_tx,
163
+                    m,
164
+                )
165
+            }));
166
+        }
167
+    } else {
168
+        search_hash(
169
+            &diff,
170
+            with_base,
171
+            0,
172
+            1,
173
+            sync.is_some(),
174
+            found,
175
+            sync.unwrap_or(1),
176
+            solution_tx,
177
+            timing_tx,
178
+            m,
179
+        )
180
+    }
181
+
182
+    match solution_rx.recv() {
183
+        Ok(sol) => {
184
+            let total_end = get_time();
185
+            println!("Number: {} --> hash: {}", sol.number, sol.hash);
186
+            if time_measurement && verbosity == 0 {
187
+                let diff = total_end - total_start;
188
+                let s = diff.num_seconds();
189
+                let ms = diff.num_milliseconds();
190
+                let us = diff.num_microseconds().unwrap_or(ms * 1000);
191
+                println!("(Duration {}s / {}ms / {}us)", s, ms, us);
192
+            }
193
+        }
194
+        Err(_) => {}
195
+    }
196
+
197
+    let mut sum_loops = 0usize;
198
+    let mut sum_time: Duration = Duration::zero();
199
+
200
+    for child in children {
201
+
202
+        if time_measurement && verbosity > 0 {
203
+            match timing_rx.recv() {
204
+                Ok(stats) => {
205
+                    sum_time = sum_time + stats.0;
206
+                    sum_loops += stats.1;
207
+                }
208
+                Err(_) => {}
209
+            }
210
+        }
211
+
212
+        if wait {
213
+            let _ = child.join();
214
+        }
215
+    }
216
+
217
+    if time_measurement && verbosity > 0 {
218
+        println!("Sum Loops in Producers:       {}", sum_loops);
219
+        let s = sum_time.num_seconds();
220
+        let ms = sum_time.num_milliseconds();
221
+        let us = sum_time.num_microseconds().unwrap_or(ms * 1000);
222
+        println!("Sum Duration in Producers:    {}s / {}ms / {}us", s, ms, us);
223
+    }
224
+}
225
+
226
+fn search_hash(
227
+    hash: &String,
228
+    base: usize,
229
+    current: usize,
230
+    total: usize,
231
+    sync: bool,
232
+    found: Arc<AtomicBool>,
233
+    special: usize,
234
+    solution_tx: Sender<Solution>,
235
+    timing_tx: Sender<(Duration, usize)>,
236
+    measure: bool,
237
+) {
238
+    let max = <usize>::max_value();
239
+    let mut n = current;
240
+
241
+    let thread_start = get_time();
242
+    while n < max {
243
+
244
+        if n % special == 0 && found.load(Relaxed) {
245
+            break;
246
+        }
247
+
248
+        if let Some(solution) = verify_product(base, n, hash) {
249
+            if sync {
250
+                found.store(true, Relaxed);
251
+            }
252
+
253
+            let _ = solution_tx.send(solution);
254
+            break;
255
+        }
256
+        n += total;
257
+    }
258
+
259
+    if measure {
260
+        let thread_end = get_time();
261
+        let _ = timing_tx.send((thread_end - thread_start, n));
262
+    }
263
+}

+ 10
- 142
hw8/task1/src/main.rs 查看文件

@@ -1,20 +1,11 @@
1 1
 #[macro_use]
2 2
 extern crate clap;
3
-extern crate time;
4 3
 extern crate task1;
5 4
 extern crate sys_info;
6 5
 
7
-mod tests;
8
-
9
-use std::sync::mpsc::{Sender, channel};
10
-use time::get_time;
11 6
 use clap::App;
12
-use time::Duration;
13
-use std::sync::Arc;
14
-use std::sync::atomic::AtomicBool;
15
-use std::sync::atomic::Ordering::Relaxed;
16
-use std::{process, thread};
17
-use task1::{Solution, verify_product};
7
+use std::process;
8
+use task1::search_with_threads;
18 9
 
19 10
 
20 11
 pub fn main() {
@@ -25,7 +16,7 @@ pub fn main() {
25 16
     // Speichere alle Argumente in Variablen
26 17
     // Falls ein Wert für ein Argument nicht existiert, lade einen default-Wert
27 18
     let base = matches.value_of("base").unwrap_or("1");
28
-    let diff = Arc::new(String::from(matches.value_of("difficulty").unwrap_or("1")));
19
+    let diff = String::from(matches.value_of("difficulty").unwrap_or("1"));
29 20
     let cpus = sys_info::cpu_num().unwrap_or(1).to_string();
30 21
     let threads = matches.value_of("threads").unwrap_or(&cpus);
31 22
     let sync = matches.is_present("sync");
@@ -33,7 +24,7 @@ pub fn main() {
33 24
     let wait = matches.is_present("wait");
34 25
     let verbosity = matches.occurrences_of("verbose");
35 26
 
36
-    let mut time_measurement = false;
27
+    let mut time = false;
37 28
 
38 29
     // Falls irgendein Zeichen nicht hexadezimal ist, breche ab.
39 30
     if diff.chars().any(|c| !c.is_digit(16)) {
@@ -44,7 +35,7 @@ pub fn main() {
44 35
     // Falls das Unterkommando timings angegeben wurde aktiviere die Zeitmessung.
45 36
     if let Some(ref sub_command) = matches.subcommand {
46 37
         if sub_command.name.eq("timings") {
47
-            time_measurement = true;
38
+            time = true;
48 39
         }
49 40
     }
50 41
 
@@ -64,7 +55,7 @@ pub fn main() {
64 55
     }
65 56
 
66 57
     // Versuche Strings der Basis und Threadanzahl zu usize zu parsen
67
-    // Anderenfalls
58
+    // Anderenfalls gebe den fehlerhaften Paramter aus.
68 59
     match (base.parse::<usize>(), threads.parse::<usize>()) {
69 60
         (Ok(b), Ok(t)) => {
70 61
             println!("Please wait...");
@@ -73,97 +64,12 @@ pub fn main() {
73 64
                 println!("Searching with {} threads", t);
74 65
             }
75 66
 
76
-            let total_start = get_time();
77
-
78
-            let mut children = vec![];
79
-
80
-            let (solution_tx, solution_rx) = channel();
81
-            let (timing_tx, timing_rx) = channel();
82
-
83
-            let found = Arc::new(AtomicBool::new(false));
84
-            let m = time_measurement && verbosity > 0;
85
-
86
-            if t > 1 {
87
-
88
-                for i in 0..t {
89
-                    let diff = diff.clone();
90
-                    let solution_tx = solution_tx.clone();
91
-                    let timing_tx = timing_tx.clone();
92
-                    let found = found.clone();
93
-
94
-                    children.push(thread::spawn(move || {
95
-
96
-                        search_hash(
97
-                            &diff,
98
-                            b,
99
-                            i,
100
-                            t,
101
-                            sync,
102
-                            found,
103
-                            special,
104
-                            solution_tx,
105
-                            timing_tx,
106
-                            m,
107
-                        )
108
-                    }));
109
-                }
110
-            } else {
111
-                search_hash(
112
-                    &diff,
113
-                    b,
114
-                    0,
115
-                    1,
116
-                    sync,
117
-                    found,
118
-                    special,
119
-                    solution_tx,
120
-                    timing_tx,
121
-                    m,
122
-                )
123
-            }
124
-
125
-            match solution_rx.recv() {
126
-                Ok(sol) => {
127
-                    let total_end = get_time();
128
-                    println!("Number: {} --> hash: {}", sol.number, sol.hash);
129
-                    if time_measurement && verbosity == 0 {
130
-                        let diff = total_end - total_start;
131
-                        let s = diff.num_seconds();
132
-                        let ms = diff.num_milliseconds();
133
-                        let us = diff.num_microseconds().unwrap_or(ms * 1000);
134
-                        println!("(Duration {}s / {}ms / {}us)", s, ms, us);
135
-                    }
136
-                }
137
-                Err(_) => {}
138
-            }
139
-
140
-            let mut sum_loops = 0usize;
141
-            let mut sum_time: Duration = Duration::zero();
142
-
143
-            for child in children {
144
-
145
-                if time_measurement && verbosity > 0 {
146
-                    match timing_rx.recv() {
147
-                        Ok(stats) => {
148
-                            sum_time = sum_time + stats.0;
149
-                            sum_loops += stats.1;
150
-                        }
151
-                        Err(_) => {}
152
-                    }
153
-                }
154
-
155
-                if wait {
156
-                    let _ = child.join();
157
-                }
67
+            let mut sync_opt = None;
68
+            if sync {
69
+                sync_opt = Some(special);
158 70
             }
159 71
 
160
-            if time_measurement && verbosity > 0 {
161
-                println!("Sum Loops in Producers:       {}", sum_loops);
162
-                let s = sum_time.num_seconds();
163
-                let ms = sum_time.num_milliseconds();
164
-                let us = sum_time.num_microseconds().unwrap_or(ms * 1000);
165
-                println!("Sum Duration in Producers:    {}s / {}ms / {}us", s, ms, us);
166
-            }
72
+            search_with_threads(t,diff,b,time, verbosity,sync_opt,wait);
167 73
 
168 74
         }
169 75
         (_, Err(_)) => {
@@ -177,41 +83,3 @@ pub fn main() {
177 83
     };
178 84
 }
179 85
 
180
-pub fn search_hash(
181
-    hash: &String,
182
-    base: usize,
183
-    current: usize,
184
-    total: usize,
185
-    sync: bool,
186
-    found: Arc<AtomicBool>,
187
-    special: usize,
188
-    solution_tx: Sender<Solution>,
189
-    timing_tx: Sender<(Duration, usize)>,
190
-    measure: bool,
191
-) {
192
-    let max = <usize>::max_value();
193
-    let mut n = current;
194
-
195
-    let thread_start = get_time();
196
-    while n < max {
197
-
198
-        if n % special == 0 && found.load(Relaxed) {
199
-            break;
200
-        }
201
-
202
-        if let Some(solution) = verify_product(base, n, hash) {
203
-            if sync {
204
-                found.store(true, Relaxed);
205
-            }
206
-
207
-            let _ = solution_tx.send(solution);
208
-            break;
209
-        }
210
-        n += total;
211
-    }
212
-
213
-    if measure {
214
-        let thread_end = get_time();
215
-        let _ = timing_tx.send((thread_end - thread_start, n));
216
-    }
217
-}

+ 17
- 5
hw8/task1/src/tests/mod.rs 查看文件

@@ -1,16 +1,28 @@
1 1
 #[cfg(test)]
2 2
 mod tests {
3
-    use search_hash;
3
+    use *;
4 4
 
5 5
     #[test]
6
-    fn test_faulty_diff() {
7
-        search_hash()
6
+    fn test_correct_diff() {
7
+        let hash = String::from("b6bea2a40ed1bd6d9999b2232072092f3df0e02c4b507aa3ad947367b9712345");
8
+        assert_eq!(
9
+            verify_product(42,567621, &String::from("12345")),
10
+            Some(Solution{number:567621, hash:hash})
11
+        )
8 12
     }
9 13
 
14
+    #[test]
15
+    fn test_wrong_diff() {
16
+        assert_eq!(
17
+            verify_product(42,13253224, &String::from("12345")),
18
+            None
19
+        )
20
+    }
10 21
 
11
-    fn test_hash() {
22
+    #[test]
23
+    fn test_hashing() {
12 24
         assert_eq!(
13
-            hash("test".as_bytes()).hex(),
25
+            Sha256::hash("test".as_bytes()).hex(),
14 26
             "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08"
15 27
         );
16 28
     }

Loading…
取消
儲存