1
+ use core:: num;
1
2
use core:: str;
3
+ use std:: time:: Instant ;
4
+ use memmap2:: MmapOptions ;
2
5
use std:: cmp:: min;
3
6
use std:: fs:: File ;
4
7
use std:: sync:: atomic:: AtomicUsize ;
5
8
use std:: sync:: atomic:: Ordering ;
6
9
use std:: sync:: Arc ;
7
10
use std:: thread;
8
- use memmap2:: MmapOptions ;
9
11
10
12
pub fn read_file_as_string ( file_path : & str ) -> String {
11
13
let file = File :: open ( file_path) . expect ( "Path is not valid" ) ;
@@ -19,52 +21,101 @@ pub fn count_words(text: &str) -> usize {
19
21
}
20
22
21
23
pub fn count_word_occurrences ( text : & str , word : String ) -> usize {
22
- count_in_paralell ( text, move |chunk| count_word_occurrences_in_chunk ( chunk, & word) )
24
+ count_in_paralell ( text, move |chunk| {
25
+ count_word_occurrences_in_chunk ( chunk, & word)
26
+ } )
23
27
}
24
28
25
29
fn count_in_paralell < F > ( text : & str , count_fn : F ) -> usize
26
30
where
27
- F : Fn ( & [ String ] ) -> usize + Send + Sync + ' static ,
31
+ F : Fn ( & [ & str ] ) -> usize + Send + Sync + ' static ,
28
32
{
29
33
let num_threads: usize = std:: thread:: available_parallelism ( ) . unwrap ( ) . get ( ) ;
30
- let lines: Vec < String > = text. lines ( ) . map ( |line| line . to_string ( ) ) . collect ( ) ;
34
+ let lines: Vec < & str > = text. lines ( ) . collect ( ) ;
31
35
let lines_per_thread = ( lines. len ( ) + num_threads - 1 ) / num_threads;
32
36
let total_word_count = Arc :: new ( AtomicUsize :: new ( 0 ) ) ;
33
- let mut handles = Vec :: new ( ) ;
37
+ // let mut handles = Vec::new();
34
38
let count_fn = Arc :: new ( count_fn) ;
39
+ let start = Instant :: now ( ) ;
40
+ // for i in 0..num_threads {
41
+ // let start = lines_per_thread * i;
42
+ // let end = min(start + lines_per_thread, lines.len());
43
+ // if is_valid_range(start, end, lines.len()) {
44
+ // let chunk = lines[start..end].to_vec();
45
+ // let count_fn_clone = Arc::clone(&count_fn);
46
+ // let total_word_count_clone = total_word_count.clone();
35
47
36
- for i in 0 ..num_threads {
37
- let start = lines_per_thread * i;
38
- let end = min ( start + lines_per_thread, lines. len ( ) ) ;
39
- let chunk = lines[ start..end] . to_vec ( ) ;
40
- let count_fn_clone = Arc :: clone ( & count_fn) ;
41
- let total_word_count_clone = total_word_count. clone ( ) ;
42
-
43
- let handle = thread:: spawn ( move || {
44
- let count = count_fn_clone ( & chunk) ;
45
- total_word_count_clone. fetch_add ( count, Ordering :: Relaxed ) ;
46
- } ) ;
47
- handles. push ( handle) ;
48
- }
48
+ // let handle = thread::spawn(move || {
49
+ // let count = count_fn_clone(chunk);
50
+ // total_word_count_clone.fetch_add(count, Ordering::Relaxed);
51
+ // });
52
+ // handles.push(handle);
53
+ // }
54
+ // }
49
55
50
- for handle in handles {
51
- handle. join ( ) . unwrap ( ) ;
52
- }
56
+
57
+ thread:: scope ( |s| {
58
+ for i in 0 ..num_threads {
59
+ let start = lines_per_thread * i;
60
+ let end = min ( start + lines_per_thread, lines. len ( ) ) ;
61
+
62
+ if is_valid_range ( start, end, lines. len ( ) ) {
63
+ let chunk = & lines[ start..end] ; // Borrow a slice of `&str`
64
+ let count_fn_clone = Arc :: clone ( & count_fn) ;
65
+ let total_word_count_clone = Arc :: clone ( & total_word_count) ;
66
+
67
+ s. spawn ( move || {
68
+ let count = count_fn_clone ( chunk) ; // Use the borrowed slice here
69
+ total_word_count_clone. fetch_add ( count, Ordering :: Relaxed ) ;
70
+ } ) ;
71
+ }
72
+ }
73
+ } ) ;
74
+
75
+ println ! ( "Finish loop in: {:?}" , start. elapsed( ) ) ;
76
+
77
+ // for handle in handles {
78
+ // handle.join().unwrap();
79
+ // }
53
80
total_word_count. load ( Ordering :: Relaxed )
54
81
}
55
82
83
+ fn is_valid_range ( start : usize , end : usize , len : usize ) -> bool {
84
+ start < end && end <= len
85
+ }
56
86
57
- fn count_words_in_chunk ( chunk : & [ String ] ) -> usize {
87
+ fn chunk_text ( text : & str , num_chunks : usize ) -> Vec < & str > {
88
+ let chunk_size = text. len ( ) / num_chunks;
89
+ let mut chunks = Vec :: new ( ) ;
90
+ let mut start = 0 ;
91
+
92
+ while start < text. len ( ) {
93
+ let end = min ( text. len ( ) , start + chunk_size) ;
94
+ let chunk = & text[ start..end] ;
95
+ chunks. push ( chunk) ;
96
+ start = end;
97
+ }
98
+ chunks
99
+ }
100
+
101
+
102
+ fn collect_lines_parallel ( text : & str , num_threads : usize ) -> Vec < & str > {
103
+ let mut result: Vec < & str > = Vec :: new ( ) ;
104
+ let mut handles = Vec :: new ( ) ;
105
+
106
+ }
107
+
108
+ fn count_words_in_chunk ( chunk : & [ & str ] ) -> usize {
58
109
chunk
59
110
. iter ( )
60
111
. flat_map ( |line| line. split_whitespace ( ) )
61
112
. count ( )
62
113
}
63
114
64
- fn count_word_occurrences_in_chunk ( chunk : & [ String ] , word : & str ) -> usize {
115
+ fn count_word_occurrences_in_chunk ( chunk : & [ & str ] , word : & str ) -> usize {
65
116
chunk
66
117
. iter ( )
67
118
. flat_map ( |line| line. split_whitespace ( ) )
68
119
. filter ( |& w| w == word)
69
120
. count ( )
70
- }
121
+ }
0 commit comments