diff --git a/Plugins/Flow.Launcher.Plugin.Program/Main.cs b/Plugins/Flow.Launcher.Plugin.Program/Main.cs index 5175970fd41..b7fe1373f61 100644 --- a/Plugins/Flow.Launcher.Plugin.Program/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.Program/Main.cs @@ -1,5 +1,7 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; +using System.Collections.Specialized; using System.Diagnostics; using System.Linq; using System.Threading; @@ -9,6 +11,9 @@ using Flow.Launcher.Infrastructure.Storage; using Flow.Launcher.Plugin.Program.Programs; using Flow.Launcher.Plugin.Program.Views; +using Microsoft.Extensions.Caching.Memory; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Primitives; using Stopwatch = Flow.Launcher.Infrastructure.Stopwatch; namespace Flow.Launcher.Plugin.Program @@ -26,9 +31,16 @@ public class Main : ISettingProvider, IAsyncPlugin, IPluginI18n, IContextMenu, I private static BinaryStorage _win32Storage; private static BinaryStorage _uwpStorage; - public Main() + private static readonly List emptyResults = new(); + + private static readonly MemoryCacheOptions cacheOptions = new() + { + SizeLimit = 1560 + }; + private static MemoryCache cache = new(cacheOptions); + + static Main() { - } public void Save() @@ -39,28 +51,29 @@ public void Save() public async Task> QueryAsync(Query query, CancellationToken token) { + if (IsStartupIndexProgramsRequired) _ = IndexPrograms(); - Win32[] win32; - UWP.Application[] uwps; + var result = await cache.GetOrCreateAsync(query.Search, async entry => + { + var resultList = await Task.Run(() => + _win32s.Cast() + .Concat(_uwps) + .AsParallel() + .WithCancellation(token) + .Where(p => p.Enabled) + .Select(p => p.Result(query.Search, _context.API)) + .Where(r => r?.Score > 0) + .ToList()); - win32 = _win32s; - uwps = _uwps; + resultList = resultList.Any() ? resultList : emptyResults; - var result = await Task.Run(delegate - { - return win32.Cast() - .Concat(uwps) - .AsParallel() - .WithCancellation(token) - .Where(p => p.Enabled) - .Select(p => p.Result(query.Search, _context.API)) - .Where(r => r?.Score > 0) - .ToList(); - }, token).ConfigureAwait(false); - - token.ThrowIfCancellationRequested(); + entry.SetSize(resultList.Count); + entry.SetSlidingExpiration(TimeSpan.FromHours(8)); + + return resultList; + }); return result; } @@ -110,7 +123,7 @@ public async Task InitAsync(PluginInitContext context) if (indexedWinApps && indexedUWPApps) _settings.LastIndexTime = DateTime.Today; }); - + if (!(_win32s.Any() && _uwps.Any())) await indexTask; } @@ -134,6 +147,9 @@ public static async Task IndexPrograms() var t1 = Task.Run(IndexWin32Programs); var t2 = Task.Run(IndexUwpPrograms); await Task.WhenAll(t1, t2).ConfigureAwait(false); + var oldCache = cache; + cache = new MemoryCache(cacheOptions); + oldCache.Dispose(); _settings.LastIndexTime = DateTime.Today; }