66using Nabu . Sources ;
77using Napa ;
88using Newtonsoft . Json . Linq ;
9+ using System ;
910using System . Collections . Concurrent ;
1011using System . Data ;
1112using System . Reactive . Linq ;
@@ -59,7 +60,7 @@ IOptions<CacheOptions> cacheOptions
5960 }
6061
6162 private static ConcurrentDictionary < ( AdaptorSettings , ProgramSource , int ) , Memory < byte > > PakCache { get ; } = new ( ) ;
62- private static ConcurrentDictionary < ProgramSource , IEnumerable < NabuProgram > > SourceCache { get ; } = new ( ) ;
63+ private static DataDictionary < IEnumerable < NabuProgram > > SourceCache { get ; } = new ( ) ;
6364 private IFileCache FileCache { get ; set ; }
6465 private HttpCache Http { get ; }
6566 private IPackageManager Packages { get ; }
@@ -89,7 +90,7 @@ public IEnumerable<NabuProgram> Programs(ProgramSource? source)
8990 {
9091 if ( source is null )
9192 return [ ] ;
92- if ( SourceCache . TryGetValue ( source , out IEnumerable < NabuProgram > ? value ) )
93+ if ( SourceCache . TryGetValue ( source . Name , out IEnumerable < NabuProgram > ? value ) )
9394 return value ;
9495
9596 return Array . Empty < NabuProgram > ( ) ;
@@ -107,7 +108,7 @@ public IEnumerable<NabuProgram> Programs(ProgramSource? source)
107108 if ( source is null )
108109 return ( ImageType . None , Array . Empty < byte > ( ) ) ;
109110
110- if ( SourceCache . ContainsKey ( source ) is false )
111+ if ( SourceCache . ContainsKey ( source . Name ) is false )
111112 return ( ImageType . None , Array . Empty < byte > ( ) ) ;
112113
113114 if ( PakCache . TryGetValue ( ( settings , source , pak ) , out var value ) )
@@ -133,7 +134,7 @@ 1 when Empty(settings.Program) || source.EnableExploitLoader => FormatTriple(1),
133134 if ( targetProgram == null )
134135 return ( ImageType . None , Array . Empty < byte > ( ) ) ;
135136
136- var program = SourceCache [ source ] . FirstOrDefault ( p => p . Name == targetProgram ) ;
137+ var program = SourceCache [ source . Name ] . FirstOrDefault ( p => p . Name == targetProgram ) ;
137138
138139 //BECAUSE: A package using the exploit loader should not have to bundle a menu.
139140 if ( program is null /* && pak > Constants.CycleMenuNumber */ )
@@ -267,9 +268,9 @@ public void UnCachePak(AdaptorSettings settings, int pak)
267268
268269 foreach ( var task in tasks )
269270 {
270- var ( isList , programs ) = await task ;
271- if ( isList ) return ( isList , programs ) ;
272- }
271+ var ( isList , programs ) = await task ;
272+ if ( isList ) return ( isList , ListCache [ source . Path ] = programs ) ;
273+ } if ( ListCache . TryGetValue ( source . Path , out var progs ) ) return ( true , progs ) ;
273274 return ( false , Array . Empty < NabuProgram > ( ) ) ;
274275 }
275276
@@ -291,7 +292,7 @@ private async Task CacheSource(ProgramSource source)
291292 {
292293 if ( source is null ||
293294 source . SourceType is not SourceType . Remote ||
294- ! SourceCache . TryGetValue ( source , out IEnumerable < NabuProgram > ? programs )
295+ ! SourceCache . TryGetValue ( source . Name , out IEnumerable < NabuProgram > ? programs )
295296 ) return ;
296297
297298 foreach ( var program in from p in programs where ! p . IsPakMenu select p )
@@ -384,7 +385,7 @@ await Task.Run(async () =>
384385 ) ) ;
385386 }
386387
387- SourceCache [ source ] = programs ;
388+ SourceCache [ source . Name ] = programs ;
388389
389390 }
390391 else if ( checkLocal && source . SourceType is SourceType . Local )
@@ -439,7 +440,7 @@ await Task.Run(async () =>
439440 ) ) ;
440441 }
441442
442- SourceCache [ source ] = programs ;
443+ SourceCache [ source . Name ] = programs ;
443444 }
444445 else if ( checkLocal && source . SourceType is SourceType . Package )
445446 {
@@ -473,7 +474,7 @@ from program in from p in package.Programs select p with { }
473474
474475 if ( programs . Count != 0 )
475476 {
476- SourceCache [ source ] = programs ;
477+ SourceCache [ source . Name ] = programs ;
477478 }
478479 }
479480 } ) ;
@@ -518,19 +519,17 @@ from program in from p in package.Programs select p with { }
518519 public static string BlankIconPtrnStr { get ; } = Convert . ToBase64String ( BlankIconPattern ) ;
519520
520521 const string Empty = " " ;
521-
522+ DataDictionary < NabuProgram [ ] > ListCache = new ( ) ;
522523 protected async Task < ( bool , NabuProgram [ ] ) > IsNabuCaJson ( ProgramSource source )
523524 {
524525 var uri = source . Path ;
525526 if ( ! ( uri . EndsWith ( ".json" ) && uri . Contains ( "nabu.ca" ) ) ) { return ( false , Array . Empty < NabuProgram > ( ) ) ; }
526527 var ( _, found , cached , _, _, _, _) = await Http . GetPathStatus ( uri ) ;
527- if ( ! found && ! cached ) { return ( false , [ ] ) ; }
528+ if ( ! found && ! cached ) { return ( false , [ ] ) ; }
528529
529-
530530 try
531531 { var json = await Http . GetString ( uri ) ;
532- var progs = new List < NabuProgram > ( ) ;
533- var sections = JObject . Parse ( json ) [ "Items" ] ;
532+ var progs = new List < NabuProgram > ( ) ; JToken ? sections = null ; while ( sections == null ) try { sections = JObject . Parse ( json ) [ "Items" ] ; } catch { }
534533 if ( sections is null ) { return ( false , [ ] ) ; }
535534
536535 string [ ] skipSections = [ "NABU Cycles" , "Demos" , "Utilities" ] ;
@@ -576,9 +575,9 @@ from program in from p in package.Programs select p with { }
576575 ) ) ;
577576 }
578577 }
579- return ( true , progs . ToArray ( ) ) ;
578+ return ( true , ListCache [ uri ] = progs . ToArray ( ) ) ;
580579 }
581- catch { return ( false , [ ] ) ; }
580+ catch { return ( false , [ ] ) ; }
582581 }
583582
584583 protected async Task < ( bool , NabuProgram [ ] ) > IsNabuNetworkList ( ProgramSource source )
0 commit comments