From 6f3cdeda70d6ddc4ab411b23b1cdfa2b88c6c009 Mon Sep 17 00:00:00 2001 From: bao-qian Date: Fri, 22 Apr 2016 23:03:32 +0100 Subject: [PATCH] Refactoring Program plugin to use parallel linq much master when use parallel --- Plugins/Wox.Plugin.Program/IProgramSource.cs | 5 +- .../ProgramSources/AppPathsProgramSource.cs | 1 + .../ProgramSources/FileSystemProgramSource.cs | 1 + Plugins/Wox.Plugin.Program/Programs.cs | 118 ++++++++---------- 4 files changed, 57 insertions(+), 68 deletions(-) diff --git a/Plugins/Wox.Plugin.Program/IProgramSource.cs b/Plugins/Wox.Plugin.Program/IProgramSource.cs index 2e8929a73..ad0a3da2b 100644 --- a/Plugins/Wox.Plugin.Program/IProgramSource.cs +++ b/Plugins/Wox.Plugin.Program/IProgramSource.cs @@ -16,10 +16,7 @@ namespace Wox.Plugin.Program { public abstract List LoadPrograms(); - public int BonusPoints - { - get; set; - } + public int BonusPoints { get; set; } protected Program CreateEntry(string file) { diff --git a/Plugins/Wox.Plugin.Program/ProgramSources/AppPathsProgramSource.cs b/Plugins/Wox.Plugin.Program/ProgramSources/AppPathsProgramSource.cs index 17cc37fd8..de2b2c52f 100644 --- a/Plugins/Wox.Plugin.Program/ProgramSources/AppPathsProgramSource.cs +++ b/Plugins/Wox.Plugin.Program/ProgramSources/AppPathsProgramSource.cs @@ -55,6 +55,7 @@ namespace Wox.Plugin.Program.ProgramSources if (!File.Exists(path)) continue; var entry = CreateEntry(path); entry.ExecuteName = item; + entry.Source = this; list.Add(entry); } } diff --git a/Plugins/Wox.Plugin.Program/ProgramSources/FileSystemProgramSource.cs b/Plugins/Wox.Plugin.Program/ProgramSources/FileSystemProgramSource.cs index eb3bc6967..f408ae7a8 100644 --- a/Plugins/Wox.Plugin.Program/ProgramSources/FileSystemProgramSource.cs +++ b/Plugins/Wox.Plugin.Program/ProgramSources/FileSystemProgramSource.cs @@ -59,6 +59,7 @@ namespace Wox.Plugin.Program.ProgramSources if (_suffixes.Any(o => file.EndsWith("." + o))) { Program p = CreateEntry(file); + p.Source = this; list.Add(p); } } diff --git a/Plugins/Wox.Plugin.Program/Programs.cs b/Plugins/Wox.Plugin.Program/Programs.cs index 45e4cd348..f9adf622a 100644 --- a/Plugins/Wox.Plugin.Program/Programs.cs +++ b/Plugins/Wox.Plugin.Program/Programs.cs @@ -17,20 +17,21 @@ namespace Wox.Plugin.Program public class Programs : ISettingProvider, IPlugin, IPluginI18n, IContextMenu { private static object lockObject = new object(); - private static List programs = new List(); - private static List sources = new List(); - private static Dictionary SourceTypes = new Dictionary + private static List _programs = new List(); + private static List _sources = new List(); + private static readonly Dictionary SourceTypes = new Dictionary { {"FileSystemProgramSource", typeof(FileSystemProgramSource)}, {"CommonStartMenuProgramSource", typeof(CommonStartMenuProgramSource)}, {"UserStartMenuProgramSource", typeof(UserStartMenuProgramSource)}, {"AppPathsProgramSource", typeof(AppPathsProgramSource)} }; + private PluginInitContext _context; private static ProgramIndexCache _cache; private static BinaryStorage _cacheStorage; - private static Settings _settings ; + private static Settings _settings; private readonly PluginSettingsStorage _settingsStorage; public Programs() @@ -51,9 +52,10 @@ namespace Wox.Plugin.Program { var fuzzyMather = FuzzyMatcher.Create(query.Search); - var results = programs.Where(p => MatchProgram(p, fuzzyMather)). - Select(ScoreFilter). - OrderByDescending(p => p.Score) + var results = _programs.AsParallel() + .Where(p => MatchProgram(p, fuzzyMather)) + .Select(ScoreFilter) + .OrderByDescending(p => p.Score) .Select(c => new Result { Title = c.Title, @@ -82,86 +84,74 @@ namespace Wox.Plugin.Program _context = context; Stopwatch.Debug("Preload programs", () => { - programs = _cache.Programs; + _programs = _cache.Programs; }); - Log.Info($"Preload {programs.Count} programs from cache"); + Log.Info($"Preload {_programs.Count} programs from cache"); Stopwatch.Debug("Program Index", IndexPrograms); } public static void IndexPrograms() { + // todo why there is a lock?? lock (lockObject) { - List programSources = new List(); - programSources.AddRange(LoadDeaultProgramSources()); + var sources = DefaultProgramSources(); if (_settings.ProgramSources != null && _settings.ProgramSources.Count(o => o.Enabled) > 0) { - programSources.AddRange(_settings.ProgramSources); + sources.AddRange(_settings.ProgramSources); } + // happlebao todo: temp hack for program suffixes + sources.AsParallel().ForAll(s => { s.Suffixes = _settings.ProgramSuffixes; }); - sources.Clear(); - foreach (var source in programSources.Where(o => o.Enabled)) - { - // happlebao todo: temp hack for program suffixes - source.Suffixes = _settings.ProgramSuffixes; + _sources = sources.AsParallel() + .Where(s => s.Enabled && SourceTypes.ContainsKey(s.Type)) + .Select(s => + { + var sourceClass = SourceTypes[s.Type]; + var constructorInfo = sourceClass.GetConstructor(new[] { typeof(ProgramSource) }); + var programSource = constructorInfo?.Invoke(new object[] { s }) as IProgramSource; + return programSource; + }) + .Where(s => s != null).ToList(); - Type sourceClass; - if (SourceTypes.TryGetValue(source.Type, out sourceClass)) - { - ConstructorInfo constructorInfo = sourceClass.GetConstructor(new[] { typeof(ProgramSource) }); - if (constructorInfo != null) - { - IProgramSource programSource = - constructorInfo.Invoke(new object[] { source }) as IProgramSource; - sources.Add(programSource); - } - } - } + _programs = _sources.AsParallel() + .SelectMany(s => s.LoadPrograms()) + // filter duplicate program + .GroupBy(x => new { x.ExecutePath, x.ExecuteName }) + .Select(g => g.First()) + .ToList(); - var tempPrograms = new List(); - foreach (var source in sources) - { - var list = source.LoadPrograms(); - list.ForEach(o => - { - o.Source = source; - }); - tempPrograms.AddRange(list); - } - - // filter duplicate program - programs = tempPrograms.GroupBy(x => new { x.ExecutePath, x.ExecuteName }) - .Select(g => g.First()).ToList(); - - _cache.Programs = programs; + _cache.Programs = _programs; } } /// /// Load program sources that wox always provide /// - private static List LoadDeaultProgramSources() + private static List DefaultProgramSources() { - var list = new List(); - list.Add(new ProgramSource + var list = new List { - BonusPoints = 0, - Enabled = _settings.EnableStartMenuSource, - Type = "CommonStartMenuProgramSource" - }); - list.Add(new ProgramSource - { - BonusPoints = 0, - Enabled = _settings.EnableStartMenuSource, - Type = "UserStartMenuProgramSource" - }); - list.Add(new ProgramSource - { - BonusPoints = -10, - Enabled = _settings.EnableRegistrySource, - Type = "AppPathsProgramSource" - }); + new ProgramSource + { + BonusPoints = 0, + Enabled = _settings.EnableStartMenuSource, + Type = "CommonStartMenuProgramSource" + }, + new ProgramSource + { + BonusPoints = 0, + Enabled = _settings.EnableStartMenuSource, + Type = "UserStartMenuProgramSource" + }, + new ProgramSource + { + BonusPoints = -10, + Enabled = _settings.EnableRegistrySource, + Type = "AppPathsProgramSource" + } + }; return list; }