11use pyo3:: prelude:: * ;
22use std:: collections:: { HashMap , HashSet } ;
3- use std:: fmt:: Error ;
43use std:: hash:: Hash ;
54use std:: collections:: hash_map:: Entry ;
6- use std:: num:: ParseIntError ;
7- use regex:: Regex ;
5+ use fancy_regex:: Regex ;
86use once_cell:: sync:: Lazy ;
97use std:: fs:: File ;
10- use std:: io:: { self , Read , BufReader } ;
8+ use std:: io:: { self , Read , Seek , SeekFrom } ;
9+ use rayon:: prelude:: * ;
1110
1211const PAT : & str = r"'(?:[sdmt]|ll|ve|re)| ?\p{L}+| ?\p{N}+| ?[^\s\p{L}\p{N}]+|\s+(?!\S)|\s+" ;
1312
@@ -83,7 +82,7 @@ fn get_pairs(
8382#[ pyfunction]
8483fn rusty_merge ( mut tok_to_count : HashMap < Vec < Vec < u8 > > , usize > , max : usize ) -> PyResult < Vec < ( Vec < u8 > , Vec < u8 > ) > > {
8584 println ! ( "we are inside rusty_merge" ) ;
86- println ! ( "{:?}" , tok_to_count) ;
85+ // println!("{:?}", tok_to_count);
8786 let mut max_pairs = vec ! [ ( vec![ 0 ; 0 ] , vec![ 0 ; 0 ] ) ; max] ;
8887 let ( mut pair_to_count, mut pair_to_toks) = get_pairs ( & tok_to_count) ;
8988 // TODO: maintain heap of max-pairs, instead of finding the max_pair on every loop.
@@ -194,18 +193,26 @@ fn rusty_merge(mut tok_to_count: HashMap<Vec<Vec<u8>>, usize>, max: usize) -> Py
194193
195194
196195 } ;
197- println ! ( "{:?}" , max_pairs) ;
196+ // println!("{:?}", max_pairs);
198197 Ok ( max_pairs)
199198}
200199
200+ #[ pyfunction]
201+ fn rusty_full_merge ( filepath : & str , boundaries : Vec < u64 > , special_tokens : Vec < String > , max : usize ) -> PyResult < Vec < ( Vec < u8 > , Vec < u8 > ) > > {
202+ let tok_to_count = rusty_get_pre_toks ( filepath, boundaries, special_tokens) ;
203+ // println!("tok_to_count {:?}", tok_to_count);
204+ return rusty_merge ( tok_to_count. unwrap ( ) , max)
205+ }
206+
207+
201208#[ pyfunction]
202209fn rusty_pre_tok ( chunk : & str , special_tokens : Vec < String > ) -> HashMap < Vec < Vec < u8 > > , usize > {
203210 let mut tok_to_count: HashMap < Vec < Vec < u8 > > , usize > = HashMap :: new ( ) ;
204211 let pat_special_toks = special_tokens. iter ( ) . map ( |x : & String | regex:: escape ( x) ) . collect :: < Vec < String > > ( ) . join ( "|" ) ;
205212 let re_special_toks: Regex = Regex :: new ( & pat_special_toks) . unwrap ( ) ;
206213
207- for regex_match in re_special_toks. split ( chunk) . flat_map ( |subchunk| RE . find_iter ( subchunk) ) {
208- let key: Vec < Vec < u8 > > = regex_match. as_str ( ) . chars ( ) . map ( |c| c. to_string ( ) . as_bytes ( ) . to_vec ( ) ) . collect ( ) ;
214+ for regex_match in re_special_toks. split ( chunk) . flat_map ( |subchunk| RE . find_iter ( subchunk. unwrap ( ) ) ) {
215+ let key: Vec < Vec < u8 > > = regex_match. unwrap ( ) . as_str ( ) . chars ( ) . map ( |c| c. to_string ( ) . as_bytes ( ) . to_vec ( ) ) . collect ( ) ;
209216
210217 // += 1
211218 * tok_to_count. entry ( key) . or_insert ( 1 ) += 1 ;
@@ -215,18 +222,56 @@ fn rusty_pre_tok(chunk:&str, special_tokens:Vec<String>) -> HashMap<Vec<Vec<u8>>
215222 tok_to_count
216223}
217224
225+ fn rusty_get_chunk_pre_toks ( filepath : & str , start : u64 , end : u64 , special_tokens : Vec < String > ) -> io:: Result < HashMap < Vec < Vec < u8 > > , usize > > {
226+ let mut tok_to_count: HashMap < Vec < Vec < u8 > > , usize > = HashMap :: new ( ) ;
227+ let pat_special_toks = special_tokens. iter ( ) . map ( |x : & String | regex:: escape ( x) ) . collect :: < Vec < String > > ( ) . join ( "|" ) ;
228+ let re_special_toks: Regex = Regex :: new ( & pat_special_toks) . unwrap ( ) ;
229+ let mut file = File :: open ( filepath) ?;
230+ file. seek ( SeekFrom :: Start ( start) ) ?;
231+ let mut buffer = vec ! [ 0u8 ; ( end - start) as usize ] ;
232+ let bytes_read = file. read ( & mut buffer) ?;
233+ let chunk = String :: from_utf8_lossy ( & buffer[ ..bytes_read] ) ;
234+ println ! ( "------ chunk ------" ) ;
235+ println ! ( "{}" , chunk) ;
236+ println ! ( "------ chunk ------" ) ;
237+ for regex_match in re_special_toks. split ( & chunk) . flat_map ( |subchunk| RE . find_iter ( subchunk. unwrap ( ) ) ) {
238+ println ! ( "match {}" , regex_match. clone( ) . unwrap( ) . as_str( ) ) ;
239+ let key: Vec < Vec < u8 > > = regex_match. unwrap ( ) . as_str ( ) . chars ( ) . map ( |c| c. to_string ( ) . as_bytes ( ) . to_vec ( ) ) . collect ( ) ;
240+
241+ // += 1
242+ * tok_to_count. entry ( key) . or_insert ( 1 ) += 1 ;
243+
244+ }
245+ Ok ( tok_to_count)
246+ }
247+
218248#[ pyfunction]
219- fn rusty_get_pre_toks ( filepath : String ) -> Result < ( ) , std:: io:: Error > {
220- let file = File :: open ( filepath) ?;
221-
222- Ok ( ( ) )
249+ fn rusty_get_pre_toks ( filepath : & str , boundaries : Vec < u64 > , special_tokens : Vec < String > ) -> io:: Result < HashMap < Vec < Vec < u8 > > , usize > > {
250+
251+ // let pat_special_toks = special_tokens.iter().map(|x: &String| regex::escape(x)).collect::<Vec<String>>().join("|");
252+ let r: Vec < ( u64 , u64 ) > = boundaries. windows ( 2 ) . map ( |x| ( x[ 0 ] , x[ 1 ] ) ) . collect ( ) ;
253+ let map = r
254+ . par_iter ( )
255+ . map ( |( start, end) | {
256+ rusty_get_chunk_pre_toks ( filepath, * start, * end, special_tokens. clone ( ) )
257+ } )
258+ . collect :: < Vec < _ > > ( )
259+ . into_iter ( )
260+ . fold ( HashMap :: new ( ) , |mut acc, chunk_map| {
261+ for ( key, value) in chunk_map. unwrap ( ) {
262+ * acc. entry ( key) . or_insert ( 0 ) += value;
263+ }
264+ acc
265+ } ) ;
266+ Ok ( map)
223267}
224268
225269/// A Python module implemented in Rust.
226270#[ pymodule]
227271fn rusty_tokey ( m : & Bound < ' _ , PyModule > ) -> PyResult < ( ) > {
228272 m. add_function ( wrap_pyfunction ! ( sum_as_string, m) ?) ?;
229273 m. add_function ( wrap_pyfunction ! ( rusty_merge, m) ?) ?;
274+ m. add_function ( wrap_pyfunction ! ( rusty_full_merge, m) ?) ?;
230275 m. add_function ( wrap_pyfunction ! ( rusty_pre_tok, m) ?) ?;
231276 m. add_function ( wrap_pyfunction ! ( rusty_get_pre_toks, m) ?) ?;
232277 m. add_function ( wrap_pyfunction ! ( simpl, m) ?) ?;
0 commit comments