1- use std:: {
2- collections:: { BTreeMap , btree_map:: Entry } ,
3- iter,
4- } ;
1+ use std:: collections:: { BTreeMap , btree_map:: Entry } ;
52
63use log:: error;
74
85use super :: { Dictionary , DictionaryInfo , Entries , LookupStrategy , Phrase , UpdateDictionaryError } ;
9- use crate :: zhuyin:: Syllable ;
6+ use crate :: {
7+ dictionary:: { DictionaryUsage , TrieBuf } ,
8+ zhuyin:: Syllable ,
9+ } ;
1010
1111/// A collection of dictionaries that returns the union of the lookup results.
1212/// # Examples
@@ -29,7 +29,7 @@ use crate::zhuyin::Syllable;
2929/// vec![("策", 100), ("冊", 100)]
3030/// )]);
3131///
32- /// let dict = Layered::new(vec![Box::new(sys_dict)] , Box::new(user_dict));
32+ /// let dict = Layered::new(vec![Box::new(sys_dict), Box::new(user_dict)] );
3333/// assert_eq!(
3434/// [
3535/// ("側", 1, 0).into(),
@@ -48,20 +48,31 @@ use crate::zhuyin::Syllable;
4848/// ```
4949#[ derive( Debug ) ]
5050pub struct Layered {
51- sys_dict : Vec < Box < dyn Dictionary > > ,
52- user_dict : Box < dyn Dictionary > ,
51+ dicts : Vec < Box < dyn Dictionary > > ,
52+ user_dict_index : usize ,
5353}
5454
5555impl Layered {
5656 /// Creates a new `Layered` with the list of dictionaries.
57- pub fn new ( sys_dict : Vec < Box < dyn Dictionary > > , user_dict : Box < dyn Dictionary > ) -> Layered {
57+ pub fn new ( mut dicts : Vec < Box < dyn Dictionary > > ) -> Layered {
58+ let user_dict_index = dicts. iter ( ) . enumerate ( ) . find_map ( |d| {
59+ if d. 1 . about ( ) . usage == DictionaryUsage :: User {
60+ Some ( d. 0 )
61+ } else {
62+ None
63+ }
64+ } ) ;
65+ if user_dict_index. is_none ( ) {
66+ dicts. push ( Box :: new ( TrieBuf :: new_in_memory ( ) ) ) ;
67+ }
68+ let user_dict_index = user_dict_index. unwrap_or ( dicts. len ( ) - 1 ) ;
5869 Layered {
59- sys_dict ,
60- user_dict ,
70+ dicts ,
71+ user_dict_index ,
6172 }
6273 }
6374 pub fn user_dict ( & mut self ) -> & mut dyn Dictionary {
64- self . user_dict . as_mut ( )
75+ self . dicts [ self . user_dict_index ] . as_mut ( )
6576 }
6677}
6778
@@ -89,44 +100,36 @@ impl Dictionary for Layered {
89100 let mut sort_map: BTreeMap < String , usize > = BTreeMap :: new ( ) ;
90101 let mut phrases: Vec < Phrase > = Vec :: new ( ) ;
91102
92- self . sys_dict
93- . iter ( )
94- . chain ( iter:: once ( & self . user_dict ) )
95- . for_each ( |d| {
96- for phrase in d. lookup ( syllables, strategy) {
97- debug_assert ! ( !phrase. as_str( ) . is_empty( ) ) ;
98- match sort_map. entry ( phrase. to_string ( ) ) {
99- Entry :: Occupied ( entry) => {
100- let index = * entry. get ( ) ;
101- phrases[ index] . freq += phrase. freq ;
102- phrases[ index] . last_used =
103- match ( phrases[ index] . last_used , phrase. last_used ) {
104- ( Some ( orig) , Some ( new) ) => Some ( u64:: max ( orig, new) ) ,
105- ( Some ( orig) , None ) => Some ( orig) ,
106- ( None , Some ( new) ) => Some ( new) ,
107- ( None , None ) => None ,
108- } ;
109- }
110- Entry :: Vacant ( entry) => {
111- entry. insert ( phrases. len ( ) ) ;
112- phrases. push ( phrase) ;
113- }
103+ self . dicts . iter ( ) . for_each ( |d| {
104+ for phrase in d. lookup ( syllables, strategy) {
105+ debug_assert ! ( !phrase. as_str( ) . is_empty( ) ) ;
106+ match sort_map. entry ( phrase. to_string ( ) ) {
107+ Entry :: Occupied ( entry) => {
108+ let index = * entry. get ( ) ;
109+ phrases[ index] . freq += phrase. freq ;
110+ phrases[ index] . last_used =
111+ match ( phrases[ index] . last_used , phrase. last_used ) {
112+ ( Some ( orig) , Some ( new) ) => Some ( u64:: max ( orig, new) ) ,
113+ ( Some ( orig) , None ) => Some ( orig) ,
114+ ( None , Some ( new) ) => Some ( new) ,
115+ ( None , None ) => None ,
116+ } ;
117+ }
118+ Entry :: Vacant ( entry) => {
119+ entry. insert ( phrases. len ( ) ) ;
120+ phrases. push ( phrase) ;
114121 }
115122 }
116- } ) ;
123+ }
124+ } ) ;
117125 phrases
118126 }
119127
120128 /// Returns all entries from all dictionaries.
121129 ///
122130 /// **NOTE**: Duplicate entries are not removed.
123131 fn entries ( & self ) -> Entries < ' _ > {
124- Box :: new (
125- self . sys_dict
126- . iter ( )
127- . chain ( iter:: once ( & self . user_dict ) )
128- . flat_map ( |dict| dict. entries ( ) ) ,
129- )
132+ Box :: new ( self . dicts . iter ( ) . flat_map ( |dict| dict. entries ( ) ) )
130133 }
131134
132135 fn about ( & self ) -> DictionaryInfo {
@@ -140,12 +143,14 @@ impl Dictionary for Layered {
140143 None
141144 }
142145
146+ fn set_usage ( & mut self , _usage : DictionaryUsage ) { }
147+
143148 fn reopen ( & mut self ) -> Result < ( ) , UpdateDictionaryError > {
144- self . user_dict . reopen ( )
149+ self . user_dict ( ) . reopen ( )
145150 }
146151
147152 fn flush ( & mut self ) -> Result < ( ) , UpdateDictionaryError > {
148- self . user_dict . flush ( )
153+ self . user_dict ( ) . flush ( )
149154 }
150155
151156 fn add_phrase (
@@ -157,7 +162,7 @@ impl Dictionary for Layered {
157162 error ! ( "BUG! added phrase is empty" ) ;
158163 return Ok ( ( ) ) ;
159164 }
160- self . user_dict . add_phrase ( syllables, phrase)
165+ self . user_dict ( ) . add_phrase ( syllables, phrase)
161166 }
162167
163168 fn update_phrase (
@@ -171,7 +176,7 @@ impl Dictionary for Layered {
171176 error ! ( "BUG! added phrase is empty" ) ;
172177 return Ok ( ( ) ) ;
173178 }
174- self . user_dict
179+ self . user_dict ( )
175180 . update_phrase ( syllables, phrase, user_freq, time)
176181 }
177182
@@ -180,7 +185,8 @@ impl Dictionary for Layered {
180185 syllables : & [ Syllable ] ,
181186 phrase_str : & str ,
182187 ) -> Result < ( ) , UpdateDictionaryError > {
183- self . user_dict . remove_phrase ( syllables, phrase_str)
188+ // TODO use exclude list
189+ self . user_dict ( ) . remove_phrase ( syllables, phrase_str)
184190 }
185191}
186192
@@ -194,7 +200,8 @@ mod tests {
194200 use super :: Layered ;
195201 use crate :: {
196202 dictionary:: {
197- Dictionary , DictionaryBuilder , LookupStrategy , Phrase , Trie , TrieBuf , TrieBuilder ,
203+ Dictionary , DictionaryBuilder , DictionaryUsage , LookupStrategy , Phrase , Trie , TrieBuf ,
204+ TrieBuilder ,
198205 } ,
199206 syl,
200207 zhuyin:: Bopomofo ,
@@ -211,7 +218,7 @@ mod tests {
211218 vec ! [ ( "策" , 100 ) , ( "冊" , 100 ) ] ,
212219 ) ] ) ;
213220
214- let dict = Layered :: new ( vec ! [ Box :: new( sys_dict) ] , Box :: new ( user_dict) ) ;
221+ let dict = Layered :: new ( vec ! [ Box :: new( sys_dict) , Box :: new( user_dict) ] ) ;
215222 assert_eq ! (
216223 [
217224 (
@@ -253,7 +260,7 @@ mod tests {
253260 vec ! [ ( "策" , 100 ) , ( "冊" , 100 ) ] ,
254261 ) ] ) ;
255262
256- let dict = Layered :: new ( vec ! [ Box :: new( sys_dict) ] , Box :: new ( user_dict) ) ;
263+ let dict = Layered :: new ( vec ! [ Box :: new( sys_dict) , Box :: new( user_dict) ] ) ;
257264 assert_eq ! (
258265 Some ( ( "側" , 1 , 0 ) . into( ) ) ,
259266 dict. lookup(
@@ -287,6 +294,7 @@ mod tests {
287294 vec ! [ ( "測" , 1 ) , ( "冊" , 1 ) , ( "側" , 1 ) ] ,
288295 ) ] ) ;
289296 let mut builder = TrieBuilder :: new ( ) ;
297+ builder. set_usage ( DictionaryUsage :: User ) ;
290298 builder. insert (
291299 & [ syl ! [ Bopomofo :: C , Bopomofo :: E , Bopomofo :: TONE4 ] ] ,
292300 ( "策" , 100 , 0 ) . into ( ) ,
@@ -298,9 +306,10 @@ mod tests {
298306 let mut cursor = Cursor :: new ( vec ! [ ] ) ;
299307 builder. write ( & mut cursor) ?;
300308 cursor. rewind ( ) ?;
301- let user_dict = Trie :: new ( & mut cursor) ?;
309+ let mut user_dict = Trie :: new ( & mut cursor) ?;
310+ user_dict. set_usage ( DictionaryUsage :: User ) ;
302311
303- let mut dict = Layered :: new ( vec ! [ Box :: new( sys_dict) ] , Box :: new ( user_dict) ) ;
312+ let mut dict = Layered :: new ( vec ! [ Box :: new( sys_dict) , Box :: new( user_dict) ] ) ;
304313 assert_eq ! (
305314 Some ( ( "側" , 1 , 0 ) . into( ) ) ,
306315 dict. lookup(
0 commit comments