diff --git a/Plugins/Wox.Plugin.FindFile/Main.cs b/Plugins/Wox.Plugin.FindFile/Main.cs index 5cad15015b..f53522f852 100644 --- a/Plugins/Wox.Plugin.FindFile/Main.cs +++ b/Plugins/Wox.Plugin.FindFile/Main.cs @@ -36,7 +36,7 @@ namespace Wox.Plugin.FindFile MFTSearcher.IndexAllVolumes(); initial = true; var searchtimeend = DateTime.Now; - Debug.WriteLine(string.Format("{0} file, indexed, {1}ms has spent.", MFTSearcher.IndexedRecordsCount, searchtimeend.Subtract(searchtimestart).TotalMilliseconds)); + Debug.WriteLine(string.Format("{0} file, indexed, {1}ms has spent.", MFTSearcher.IndexedFileCount, searchtimeend.Subtract(searchtimestart).TotalMilliseconds)); } private Result ConvertMFTSearch(MFTSearchRecord record, string query) diff --git a/Wox.Infrastructure/MFTSearch/MFTSearcher.cs b/Wox.Infrastructure/MFTSearch/MFTSearcher.cs index 7d4b603e86..dbc31fdee6 100644 --- a/Wox.Infrastructure/MFTSearch/MFTSearcher.cs +++ b/Wox.Infrastructure/MFTSearch/MFTSearcher.cs @@ -22,8 +22,8 @@ namespace Wox.Infrastructure.MFTSearch List files; List folders; EnumerateVolume(volume, out files, out folders); - //cache.AddRecord(files); - //cache.AddRecord(folders); + cache.AddRecord(volume, files, USNRecordType.File); + cache.AddRecord(volume, folders, USNRecordType.Folder); } public static void IndexAllVolumes() @@ -34,9 +34,13 @@ namespace Wox.Infrastructure.MFTSearch } } - public static long IndexedRecordsCount + public static long IndexedFileCount { - get { return cache.RecordsCount; } + get { return cache.FileCount; } + } + public static long IndexedFolderCount + { + get { return cache.FolderCount; } } public static List Search(string item) @@ -44,7 +48,7 @@ namespace Wox.Infrastructure.MFTSearch if (string.IsNullOrEmpty(item)) return new List(); List found = cache.FindByName(item); - found.ForEach(x => FillPath(x, cache)); + found.ForEach(x => FillPath(x.VolumeName, x, cache)); return found.ConvertAll(o => new MFTSearchRecord(o)); } @@ -250,16 +254,14 @@ namespace Wox.Infrastructure.MFTSearch } Marshal.FreeHGlobal(pData); } - - internal static void FillPath(USNRecord record, MFTSearcherCache db) + internal static void FillPath(string volume, USNRecord record, MFTSearcherCache db) { if (record == null) return; - var fdSource = db.GetAllRecords(); + var fdSource = db.GetFolderSource(volume); string fullpath = record.Name; FindRecordPath(record, ref fullpath, fdSource); record.FullPath = fullpath; } - private static void FindRecordPath(USNRecord curRecord, ref string fullpath, Dictionary fdSource) { if (curRecord.IsVolumeRoot) return; diff --git a/Wox.Infrastructure/MFTSearch/MFTSearcherCache.cs b/Wox.Infrastructure/MFTSearch/MFTSearcherCache.cs index 1ea9335a6e..72fce782e1 100644 --- a/Wox.Infrastructure/MFTSearch/MFTSearcherCache.cs +++ b/Wox.Infrastructure/MFTSearch/MFTSearcherCache.cs @@ -6,55 +6,127 @@ namespace Wox.Infrastructure.MFTSearch { internal class MFTSearcherCache { - private Dictionary records = new Dictionary(100000); - private Lookup recordsLookup; + private Dictionary> _volumes_files = new Dictionary>(); + private Dictionary> _volumes_folders = new Dictionary>(); public MFTSearcherCache() { } - public void AddRecord(List record) + public bool ContainsVolume(string volume) { - record.ForEach(AddRecord); + return _volumes_files.ContainsKey(volume) && _volumes_folders.ContainsKey(volume); } - - public void AddRecord(USNRecord record) + public void AddRecord(string volume, List r, USNRecordType type) { - if(!records.ContainsKey(record.FRN)) records.Add(record.FRN, record); - } - - public bool DeleteRecord(ulong frn) - { - return records.Remove(frn); - } - - public void UpdateRecord(USNRecord record) - { - USNRecord firstOrDefault = records[record.FRN]; - if (firstOrDefault != null) + if (type == USNRecordType.File) { - firstOrDefault.Name = record.Name; - firstOrDefault.FullPath = record.FullPath; - firstOrDefault.VolumeName = record.VolumeName; + CheckHashTableKey(_volumes_files, volume); + r.ForEach(x => _volumes_files[volume].Add(x.FRN, x)); + } + else + { + CheckHashTableKey(_volumes_folders, volume); + r.ForEach(x => _volumes_folders[volume].Add(x.FRN, x)); + } + } + public void AddRecord(string volume, USNRecord record, USNRecordType type) + { + if (type == USNRecordType.File) + { + CheckHashTableKey(_volumes_files, volume); + _volumes_files[volume].Add(record.FRN, record); + } + else + { + CheckHashTableKey(_volumes_folders, volume); + _volumes_folders[volume].Add(record.FRN, record); + } + } + private void CheckHashTableKey(Dictionary> hashtable, string key) + { + if (!hashtable.ContainsKey(key)) + hashtable.Add(key, new Dictionary()); + } + public bool DeleteRecord(string volume, ulong frn) + { + bool result = false; + result = DeleteRecordHashTableItem(_volumes_files, volume, frn); + if (!result) result = DeleteRecordHashTableItem(_volumes_folders, volume, frn); + return result; + } + private bool DeleteRecordHashTableItem(Dictionary> hashtable, string volume, ulong frn) + { + if (hashtable.ContainsKey(volume) && hashtable[volume].ContainsKey(frn)) + { + hashtable[volume].Remove(frn); + return true; + } + else + { + return false; + } + } + public void UpdateRecord(string volume, USNRecord record, USNRecordType type) + { + if (type == USNRecordType.File) + RealUpdateRecord(volume, _volumes_files, record); + else + RealUpdateRecord(volume, _volumes_folders, record); + } + private bool RealUpdateRecord(string volume, Dictionary> source, USNRecord record) + { + if (source.ContainsKey(volume) && source[volume].ContainsKey(record.FRN)) + { + source[volume][record.FRN] = record; + return true; + } + else + { + return false; } } - - public List FindByName(string filename) { filename = filename.ToLower(); - var query = from file in records.Values - where file.Name.ToLower().Contains(filename) - select file; - return query.ToList(); - } + var fileQuery = from filesInVolumeDic in _volumes_files.Values + from eachFilePair in filesInVolumeDic + where eachFilePair.Value.Name.ToLower().Contains(filename) + select eachFilePair.Value; - public long RecordsCount - { - get { return records.Count; } + var folderQuery = from fldsInVolumeDic in _volumes_folders.Values + from eachFldPair in fldsInVolumeDic + where eachFldPair.Value.Name.ToLower().Contains(filename) + select eachFldPair.Value; + + List result = new List(); + + result.AddRange(fileQuery); + result.AddRange(folderQuery); + + return result; } - - public Dictionary GetAllRecords() + public USNRecord FindByFrn(string volume, ulong frn) { - return records; + if ((!_volumes_files.ContainsKey(volume)) || (!_volumes_folders.ContainsKey(volume))) + throw new Exception(string.Format("DB not contain the volume: {0}", volume)); + USNRecord result = null; + _volumes_files[volume].TryGetValue(frn, out result); + if (result != null) return result; + _volumes_folders[volume].TryGetValue(frn, out result); + return result; + } + public long FileCount + { + get { return _volumes_files.Sum(x => x.Value.Count); } + } + public long FolderCount + { + get { return _volumes_folders.Sum(x => x.Value.Count); } + } + public Dictionary GetFolderSource(string volume) + { + Dictionary result = null; + _volumes_folders.TryGetValue(volume, out result); + return result; } } } diff --git a/Wox.Test/MFTSearcherTest.cs b/Wox.Test/MFTSearcherTest.cs index c7a9ec5841..a496a18ce2 100644 --- a/Wox.Test/MFTSearcherTest.cs +++ b/Wox.Test/MFTSearcherTest.cs @@ -16,7 +16,7 @@ namespace Wox.Test var searchtimestart = DateTime.Now; MFTSearcher.IndexAllVolumes(); var searchtimeend = DateTime.Now; - Console.WriteLine(string.Format("{0} file indexed, {1}ms has spent.", MFTSearcher.IndexedRecordsCount, searchtimeend.Subtract(searchtimestart).TotalMilliseconds)); + Console.WriteLine(string.Format("{0} file indexed, {1}ms has spent.", MFTSearcher.IndexedFileCount, searchtimeend.Subtract(searchtimestart).TotalMilliseconds)); searchtimestart = DateTime.Now; List mftSearchRecords = MFTSearcher.Search("q");