@@ -33,6 +33,8 @@ public SearchClient(SearchConfig config)
3333 Results = new List < SearchResult > ( ) ;
3434 FilteredResults = new List < SearchResult > ( ) ;
3535 DirectResults = new List < ImageResult > ( ) ;
36+ DetailedResults = new List < ImageResult > ( ) ;
37+
3638 Reload ( ) ;
3739 }
3840
@@ -58,11 +60,16 @@ public SearchClient(SearchConfig config)
5860
5961 public List < ImageResult > DirectResults { get ; }
6062
63+ public List < ImageResult > DetailedResults { get ; }
64+
65+
6166 /// <summary>
6267 /// Contains filtered search results
6368 /// </summary>
6469 public List < SearchResult > FilteredResults { get ; }
6570
71+
72+
6673 public int Pending { get ; private set ; }
6774
6875 /// <summary>
@@ -89,6 +96,7 @@ public void Reset()
8996 Results . Clear ( ) ;
9097 DirectResults . Clear ( ) ;
9198 FilteredResults . Clear ( ) ;
99+ DetailedResults . Clear ( ) ;
92100 IsComplete = false ;
93101 Reload ( ) ;
94102 }
@@ -159,8 +167,13 @@ public async Task RunSearchAsync()
159167 isFiltered = null ;
160168 }
161169
162- ThreadPool . QueueUserWorkItem ( ( c ) => FindDirectResults ( c , value ) ) ;
163170
171+ if ( DetailPredicate ( value ) ) {
172+ DetailedResults . Add ( value . PrimaryResult ) ;
173+ }
174+
175+ ThreadPool . QueueUserWorkItem ( ( c ) => FindDirectResults ( c , value ) ) ;
176+
164177 // Call event
165178 ResultCompleted ? . Invoke ( null , new ResultCompletedEventArgs ( value )
166179 {
@@ -173,34 +186,38 @@ public async Task RunSearchAsync()
173186
174187 Trace . WriteLine ( $ "{ nameof ( SearchClient ) } : Search complete", C_SUCCESS ) ;
175188
176-
177189 var args = new SearchCompletedEventArgs
178190 {
179- Results = Results ,
180- FirstDetailed = RefineFilter ( DetailPredicate ) . FirstOrDefault ( ) ,
181- /*Direct = new Lazy<ImageResult[]>(() =>
182- {
183- Debug.WriteLine($"{nameof(SearchClient)}: Finding direct results", C_DEBUG);
184- ImageResult[] direct = GetDirectImageResults();
185-
186- return direct;
187- }),
188- FirstDirect = new Lazy<ImageResult>(GetDirectImageResult)*/
189- Direct = DirectResults ,
190- FirstDirect = DirectResults . FirstOrDefault ( )
191+ Results = Results ,
192+ Detailed = PredicateFilter ( Results , DetailPredicate ) ,
193+ Direct = DirectResults ,
194+ Filtered = FilteredResults
191195 } ;
192196
193197 SearchCompleted ? . Invoke ( null , args ) ;
194-
198+ }
199+
200+ public Task < List < ImageResult > > WaitForDirect ( )
201+ {
202+ return Task . Run ( ( ) =>
203+ {
204+ while ( Results . Any ( ) && ! DirectResults . Any ( ) ) {
205+
206+ }
195207
208+ return DirectResults ;
209+ } ) ;
196210 }
197211
198212 private void FindDirectResults ( object state , SearchResult value , int count = 5 , int i = 10 )
199213 {
200- var u = value . OtherResults . Union ( new [ ] { value . PrimaryResult } ) . ToList ( ) ;
201- var u2 = RefineFilter ( u , DirectFilterPredicate ) . ToList ( ) ;
214+ // var u = value.OtherResults.Union(new[] { value.PrimaryResult }).ToList();
215+ // var u2 = RefineFilter(u, DetailPredicate).ToList();
216+
217+ var u2 = value . OtherResults . Union ( new [ ] { value . PrimaryResult } ) . ToList ( ) ;
202218
203- Debug . WriteLine ( $ "*{ nameof ( SearchClient ) } : Found { u2 . Count } best results", C_DEBUG ) ;
219+
220+ Debug . WriteLine ( $ "*{ nameof ( SearchClient ) } : Found { u2 . Count } detailed results", C_DEBUG ) ;
204221
205222 var query = u2 . Where ( x => x . CheckDirect ( DirectImageCriterion . Regex ) )
206223 . Take ( i )
@@ -214,36 +231,26 @@ private void FindDirectResults(object state, SearchResult value, int count = 5,
214231 Debug . WriteLine ( $ "*{ nameof ( SearchClient ) } : Found { images . Count } direct results", C_DEBUG ) ;
215232 DirectResults . AddRange ( images ) ;
216233
217- DirectFound ? . Invoke ( null , new DirectFoundEventArgs ( )
234+ DirectFound ? . Invoke ( null , new DirectResultsFoundEventArgs ( )
218235 {
219- Direct = images ,
236+ DirectResultsSubset = images ,
220237 } ) ;
221238 }
222239 }
223240
224241
225- public static IEnumerable < ImageResult > RefineFilter ( List < ImageResult > results ,
226- Predicate < SearchResult > predicate )
242+ public List < ImageResult > PredicateFilter ( List < SearchResult > results , Predicate < SearchResult > predicate )
227243 {
228- var query = results . AsParallel ( )
229- . OrderByDescending ( r => r . Similarity )
230- . ThenByDescending ( r => r . PixelResolution )
231- . ThenByDescending ( r => r . DetailScore ) ;
244+ var vb = results . Where ( ( r ) => predicate ( r ) ) . SelectMany ( r =>
245+ {
246+ return r . OtherResults . Union ( new [ ] { r . PrimaryResult } ) ;
247+ } ) ;
232248
233- return query ;
234- }
249+ var query = vb . OrderByDescending ( r => r . Similarity )
250+ . ThenByDescending ( r => r . PixelResolution )
251+ . ThenByDescending ( r => r . DetailScore ) . ToList ( ) ;
235252
236- public IEnumerable < ImageResult > RefineFilter ( Predicate < SearchResult > predicate )
237- {
238- var query = Results . Where ( r => predicate ( r ) )
239- . SelectMany ( r =>
240- {
241- List < ImageResult > otherResults = r . OtherResults ;
242- otherResults . Insert ( 0 , r . PrimaryResult ) ;
243- return otherResults ;
244- } ) . ToList ( ) ;
245-
246- return RefineFilter ( query , predicate ) ;
253+ return query ;
247254 }
248255
249256 /// <summary>
@@ -255,12 +262,12 @@ public async Task RefineSearchAsync()
255262 throw SearchException ;
256263 }
257264
258- Debug . WriteLine ( $ "{ nameof ( SearchClient ) } : Finding best result", C_DEBUG ) ;
265+ Debug . WriteLine ( $ "{ nameof ( SearchClient ) } : Finding direct result", C_DEBUG ) ;
259266
260267 var directResult = DirectResults . FirstOrDefault ( ) ;
261268
262269 if ( directResult == null ) {
263- throw new SmartImageException ( "Could not find best result" ) ;
270+ throw new SmartImageException ( "Could not find direct result" ) ;
264271 }
265272
266273 var uri = directResult . Direct ;
@@ -319,35 +326,36 @@ public static BaseSearchEngine[] GetAllSearchEngines()
319326 /// </summary>
320327 public event EventHandler < SearchCompletedEventArgs > SearchCompleted ;
321328
322- public event EventHandler < DirectFoundEventArgs > DirectFound ;
329+ public event EventHandler < DirectResultsFoundEventArgs > DirectFound ;
323330
324331 private static readonly Predicate < SearchResult > DetailPredicate = r => r . IsNonPrimitive ;
325332
326333 private static readonly SmartImageException SearchException = new ( "Search must be completed" ) ;
327-
328- private static readonly Predicate < SearchResult > DirectFilterPredicate = r => DetailPredicate ( r )
329- && r . Engine . SearchType . HasFlag ( EngineSearchType . Image ) ;
330334 }
331335
332- public sealed class DirectFoundEventArgs : EventArgs
336+
337+ public sealed class DirectResultsFoundEventArgs : EventArgs
333338 {
334- public List < ImageResult > Direct { get ; init ; }
339+ /// <remarks>
340+ /// This field will always be a subset of <see cref="SearchClient.DirectResults"/>
341+ /// <para/>
342+ /// <see cref="DirectResultsSubset"/> ⊂ <see cref="SearchClient.DirectResults"/>
343+ /// </remarks>
344+ public List < ImageResult > DirectResultsSubset { get ; init ; }
335345 }
336346
337347 public sealed class SearchCompletedEventArgs : EventArgs
338348 {
339349 public List < SearchResult > Results { get ; init ; }
340-
341- [ CanBeNull ]
350+
342351 public List < ImageResult > Direct { get ; internal set ; }
352+
353+ public List < ImageResult > Detailed { get ; internal set ; }
354+
355+ public List < SearchResult > Filtered { get ; internal set ; }
343356
344- [ CanBeNull ]
345- public ImageResult FirstDirect { get ; internal set ; }
346357
347358
348- [ CanBeNull ]
349- public ImageResult FirstDetailed { get ; internal set ; }
350-
351359 }
352360
353361 public sealed class ResultCompletedEventArgs : EventArgs
0 commit comments