Skip to content

Commit

Permalink
Merge pull request #2954 from Wox-launcher/bao
Browse files Browse the repository at this point in the history
huge query performance improvement
  • Loading branch information
bao-qian authored May 18, 2020
2 parents 6be4475 + f379949 commit 9a0ee17
Show file tree
Hide file tree
Showing 9 changed files with 241 additions and 250 deletions.
129 changes: 60 additions & 69 deletions Plugins/Wox.Plugin.Everything/Everything/EverythingAPI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ namespace Wox.Plugin.Everything.Everything
public sealed class EverythingApi
{

private readonly object _syncObject = new object();

public enum StateCode
{
OK,
Expand Down Expand Up @@ -111,17 +109,6 @@ public bool EnableRegex
}
}

/// <summary>
/// Resets this instance.
/// </summary>
public void Reset()
{
lock (_syncObject)
{
EverythingApiDllImport.Everything_Reset();
}
}

/// <summary>
/// Searches the specified key word and reset the everything API afterwards
/// </summary>
Expand All @@ -132,77 +119,79 @@ public void Reset()
/// <returns></returns>
public List<SearchResult> Search(string keyWord, CancellationToken token, int maxCount)
{
var results = new List<SearchResult>();

if (string.IsNullOrEmpty(keyWord))
throw new ArgumentNullException(nameof(keyWord));
if (maxCount < 0)
throw new ArgumentOutOfRangeException(nameof(maxCount));
lock (_syncObject)
{

if (keyWord.StartsWith("@"))
{
EverythingApiDllImport.Everything_SetRegex(true);
keyWord = keyWord.Substring(1);
}
else
{
EverythingApiDllImport.Everything_SetRegex(false);
}
if (token.IsCancellationRequested) { return results; }
if (keyWord.StartsWith("@"))
{
EverythingApiDllImport.Everything_SetRegex(true);
keyWord = keyWord.Substring(1);
}
else
{
EverythingApiDllImport.Everything_SetRegex(false);
}

EverythingApiDllImport.Everything_SetRequestFlags(RequestFlag.HighlightedFileName | RequestFlag.HighlightedFullPathAndFileName);
EverythingApiDllImport.Everything_SetOffset(0);
EverythingApiDllImport.Everything_SetMax(maxCount);
EverythingApiDllImport.Everything_SetSearchW(keyWord);
if (token.IsCancellationRequested) { return results; }
EverythingApiDllImport.Everything_SetRequestFlags(RequestFlag.HighlightedFileName | RequestFlag.HighlightedFullPathAndFileName);
if (token.IsCancellationRequested) { return results; }
EverythingApiDllImport.Everything_SetOffset(0);
if (token.IsCancellationRequested) { return results; }
EverythingApiDllImport.Everything_SetMax(maxCount);
if (token.IsCancellationRequested) { return results; }
EverythingApiDllImport.Everything_SetSearchW(keyWord);

if (token.IsCancellationRequested) { return results; }
if (!EverythingApiDllImport.Everything_QueryW(true))
{
CheckAndThrowExceptionOnError();
return results;
}

if (token.IsCancellationRequested)
if (token.IsCancellationRequested) { return results; }
int count = EverythingApiDllImport.Everything_GetNumResults();
for (int idx = 0; idx < count; ++idx)
{
if (token.IsCancellationRequested) { return results; }
// https://www.voidtools.com/forum/viewtopic.php?t=8169
string fileNameHighted = Marshal.PtrToStringUni(EverythingApiDllImport.Everything_GetResultHighlightedFileNameW(idx));
string fullPathHighted = Marshal.PtrToStringUni(EverythingApiDllImport.Everything_GetResultHighlightedFullPathAndFileNameW(idx));
if (fileNameHighted == null | fullPathHighted == null)
{
return null;
CheckAndThrowExceptionOnError();
}
if (token.IsCancellationRequested) { return results; }
ConvertHightlightFormat(fileNameHighted, out List<int> fileNameHightlightData, out string fileName);
if (token.IsCancellationRequested) { return results; }
ConvertHightlightFormat(fullPathHighted, out List<int> fullPathHightlightData, out string fullPath);


if (!EverythingApiDllImport.Everything_QueryW(true))
var result = new SearchResult
{
CheckAndThrowExceptionOnError();
return null;
FileName = fileName,
FileNameHightData = fileNameHightlightData,
FullPath = fullPath,
FullPathHightData = fullPathHightlightData,
};

if (token.IsCancellationRequested) { return results; }
if (EverythingApiDllImport.Everything_IsFolderResult(idx))
{
result.Type = ResultType.Folder;
}

var results = new List<SearchResult>();
int count = EverythingApiDllImport.Everything_GetNumResults();
for (int idx = 0; idx < count; ++idx)
else
{
if (token.IsCancellationRequested)
{
return null;
}
// https://www.voidtools.com/forum/viewtopic.php?t=8169
string fileNameHighted = Marshal.PtrToStringUni(EverythingApiDllImport.Everything_GetResultHighlightedFileNameW(idx));
string fullPathHighted = Marshal.PtrToStringUni(EverythingApiDllImport.Everything_GetResultHighlightedFullPathAndFileNameW(idx));
if (fileNameHighted == null | fullPathHighted == null)
{
CheckAndThrowExceptionOnError();
}
ConvertHightlightFormat(fileNameHighted, out List<int> fileNameHightlightData, out string fileName);
ConvertHightlightFormat(fullPathHighted, out List<int> fullPathHightlightData, out string fullPath);

var result = new SearchResult
{
FileName = fileName,
FileNameHightData = fileNameHightlightData,
FullPath = fullPath,
FullPathHightData = fullPathHightlightData,
};
if (EverythingApiDllImport.Everything_IsFolderResult(idx))
result.Type = ResultType.Folder;
else if (EverythingApiDllImport.Everything_IsFileResult(idx))
result.Type = ResultType.File;

results.Add(result);
result.Type = ResultType.File;
}

Reset();

return results;
results.Add(result);
}

return results;
}

private static void ConvertHightlightFormat(string contentHightlighted, out List<int> hightlightData, out string fn)
Expand All @@ -211,18 +200,20 @@ private static void ConvertHightlightFormat(string contentHightlighted, out List
StringBuilder content = new StringBuilder();
bool flag = false;
char[] contentArray = contentHightlighted.ToCharArray();
int count = 0;
for (int i = 0; i < contentArray.Length; i++)
{
char current = contentHightlighted[i];
if (current == '*')
{
flag = !flag;
count = count + 1;
}
else
{
if (flag)
{
hightlightData.Add(i);
hightlightData.Add(i - count);
}
content.Append(current);
}
Expand Down
24 changes: 15 additions & 9 deletions Plugins/Wox.Plugin.Everything/Main.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public class Main : IPlugin, ISettingProvider, IPluginI18n, IContextMenu, ISavab

private Settings _settings;
private PluginJsonStorage<Settings> _storage;
private CancellationTokenSource _cancellationTokenSource;
private CancellationTokenSource _updateSource;
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();

public void Save()
Expand All @@ -38,23 +38,29 @@ public void Save()

public List<Result> Query(Query query)
{
_cancellationTokenSource?.Cancel(); // cancel if already exist
var cts = _cancellationTokenSource = new CancellationTokenSource();
if (_updateSource != null && !_updateSource.IsCancellationRequested)
{
_updateSource.Cancel();
Logger.WoxDebug($"cancel init {_updateSource.Token.GetHashCode()} {Thread.CurrentThread.ManagedThreadId} {query.RawQuery}");
_updateSource.Dispose();
}
var source = new CancellationTokenSource();
_updateSource = source;
var token = source.Token;

var results = new List<Result>();
if (!string.IsNullOrEmpty(query.Search))
{
var keyword = query.Search;

try
{
var searchList = _api.Search(keyword, cts.Token, _settings.MaxSearchCount);
if (searchList == null)
{
return results;
}

if (token.IsCancellationRequested) { return results; }
var searchList = _api.Search(keyword, token, _settings.MaxSearchCount);
if (token.IsCancellationRequested) { return results; }
for (int i = 0; i < searchList.Count; i++)
{
if (token.IsCancellationRequested) { return results; }
SearchResult searchResult = searchList[i];
var r = CreateResult(keyword, searchResult, i);
results.Add(r);
Expand Down
88 changes: 64 additions & 24 deletions Plugins/Wox.Plugin.Program/Main.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
Expand All @@ -13,6 +14,7 @@
using Wox.Plugin.Program.Views;
using Stopwatch = Wox.Infrastructure.Stopwatch;
using System.Threading;
using Windows.ApplicationModel.Background;

namespace Wox.Plugin.Program
{
Expand All @@ -24,6 +26,7 @@ public class Main : ISettingProvider, IPlugin, IPluginI18n, IContextMenu, ISavab
internal static Settings _settings { get; set; }

private static PluginInitContext _context;
private CancellationTokenSource _updateSource;

private static BinaryStorage<Win32[]> _win32Storage;
private static BinaryStorage<UWP.Application[]> _uwpStorage;
Expand Down Expand Up @@ -53,35 +56,72 @@ public void Save()

public List<Result> Query(Query query)
{
Win32[] win32;
UWP.Application[] uwps;
win32 = _win32s;
uwps = _uwps;

var results1 = win32.AsParallel()
.Where(p => p.Enabled)
.Select(p => p.Result(query.Search, _context.API));

var results2 = uwps.AsParallel()
.Where(p => p.Enabled)
.Select(p => p.Result(query.Search, _context.API));

var result = results1.Concat(results2)
.Where(r => r != null && r.Score > 0)
.Where(p => !_settings.IgnoredSequence.Any(entry =>
if (_updateSource != null && !_updateSource.IsCancellationRequested)
{
if (entry.IsRegex)
_updateSource.Cancel();
Logger.WoxDebug($"cancel init {_updateSource.Token.GetHashCode()} {Thread.CurrentThread.ManagedThreadId} {query.RawQuery}");
_updateSource.Dispose();
}
var source = new CancellationTokenSource();
_updateSource = source;
var token = source.Token;

ConcurrentBag<Result> resultRaw = new ConcurrentBag<Result>();

if (token.IsCancellationRequested) { return new List<Result>(); }
Parallel.ForEach(_win32s, (program, state) =>
{
if (token.IsCancellationRequested) { state.Break(); }
if (program.Enabled)
{
return Regex.Match(p.Title, entry.EntryString).Success;
var r = program.Result(query.Search, _context.API);
if (r != null && r.Score > 0)
{
resultRaw.Add(r);
}
}
else
});
if (token.IsCancellationRequested) { return new List<Result>(); }
Parallel.ForEach(_uwps, (program, state) =>
{
if (token.IsCancellationRequested) { state.Break(); }
if (program.Enabled)
{
return p.Title.ToLower().Contains(entry.EntryString);
var r = program.Result(query.Search, _context.API);
if (token.IsCancellationRequested) { state.Break(); }
if (r != null && r.Score > 0)
{
resultRaw.Add(r);
}
}
})).Take(30);

});

return result.ToList();
if (token.IsCancellationRequested) { return new List<Result>(); }
OrderedParallelQuery<Result> sorted = resultRaw.AsParallel().OrderByDescending(r => r.Score);
List<Result> results = new List<Result>();
foreach (Result r in sorted) {
if (token.IsCancellationRequested) { return new List<Result>(); }
var ignored = _settings.IgnoredSequence.Any(entry =>
{
if (entry.IsRegex)
{
return Regex.Match(r.Title, entry.EntryString).Success;
}
else
{
return r.Title.ToLower().Contains(entry.EntryString);
}
});
if (!ignored)
{
results.Add(r);
}
if (results.Count == 30)
{
break;
}
}
return results;
}

public void Init(PluginInitContext context)
Expand Down Expand Up @@ -192,4 +232,4 @@ public void ReloadData()
IndexPrograms();
}
}
}
}
Loading

0 comments on commit 9a0ee17

Please sign in to comment.