From e37217c878a2d2b90359e1c36602e676695db96f Mon Sep 17 00:00:00 2001 From: Alekhya Reddy Date: Wed, 5 Aug 2020 19:30:45 +1000 Subject: [PATCH 01/11] From alekhyareddy28:memoryIssue on Jun 27, 2020 --- .../Image/ImageCache.cs | 40 +++++++++++++++---- .../Image/ImageLoader.cs | 26 ++++++------ 2 files changed, 47 insertions(+), 19 deletions(-) diff --git a/Flow.Launcher.Infrastructure/Image/ImageCache.cs b/Flow.Launcher.Infrastructure/Image/ImageCache.cs index 5d7224c5b3d..67f00897210 100644 --- a/Flow.Launcher.Infrastructure/Image/ImageCache.cs +++ b/Flow.Launcher.Infrastructure/Image/ImageCache.cs @@ -2,17 +2,18 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using System.Windows.Media; -namespace Flow.Launcher.Infrastructure.Image +namespace Wox.Infrastructure.Image { [Serializable] public class ImageCache { - private const int MaxCached = 5000; + private const int MaxCached = 50; public ConcurrentDictionary Usage = new ConcurrentDictionary(); private readonly ConcurrentDictionary _data = new ConcurrentDictionary(); - + private const int permissibleFactor = 2; public ImageSource this[string path] { @@ -22,14 +23,39 @@ public ImageSource this[string path] var i = _data[path]; return i; } - set { _data[path] = value; } + set + { + _data[path] = value; + + // To prevent the dictionary from drastically increasing in size by caching images, the dictionary size is not allowed to grow more than the permissibleFactor * maxCached size + // This is done so that we don't constantly perform this resizing operation and also maintain the image cache size at the same time + if (_data.Count > permissibleFactor * MaxCached) + { + // This function resizes the Usage dictionary, taking the top 'maxCached' number of items and filtering the image icons that are not accessed frequently. + Cleanup(); + + // To delete the images from the data dictionary based on the resizing of the Usage Dictionary. + foreach (var key in _data.Keys) + { + int dictValue; + if (!Usage.TryGetValue(key, out dictValue)) + { + ImageSource imgSource; + _data.TryRemove(key, out imgSource); + } + } + } + } } - public Dictionary CleanupAndToDictionary() - => Usage + public void Cleanup() + { + var images = Usage .OrderByDescending(o => o.Value) .Take(MaxCached) .ToDictionary(i => i.Key, i => i.Value); + Usage = new ConcurrentDictionary(images); + } public bool ContainsKey(string key) { @@ -51,4 +77,4 @@ public int UniqueImagesInCache() } } -} +} \ No newline at end of file diff --git a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs index 0bf575337c7..e03ee709a2a 100644 --- a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs +++ b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs @@ -9,7 +9,7 @@ using Flow.Launcher.Infrastructure.Logger; using Flow.Launcher.Infrastructure.Storage; -namespace Flow.Launcher.Infrastructure.Image +namespace Wox.Infrastructure.Image { public static class ImageLoader { @@ -218,27 +218,29 @@ public static ImageSource Load(string path, bool loadFullImage = false) var img = imageResult.ImageSource; if (imageResult.ImageType != ImageType.Error && imageResult.ImageType != ImageType.Cache) - { - // we need to get image hash - string hash = _enableHashImage ? _hashGenerator.GetHashFromImage(img) : null; + { // we need to get image hash + string hash = EnableImageHash ? _hashGenerator.GetHashFromImage(img) : null; if (hash != null) { - if (_guidToKey.TryGetValue(hash, out string key)) - { - // image already exists - img = _imageCache[key]; + int ImageCacheValue; + if (GuidToKey.TryGetValue(hash, out string key)) + { // image already exists + if (ImageCache.Usage.TryGetValue(path, out ImageCacheValue)) + { + img = ImageCache[key]; + } } else - { - // new guid - _guidToKey[hash] = path; + { // new guid + GuidToKey[hash] = path; } } // update cache - _imageCache[path] = img; + ImageCache[path] = img; } + return img; } From 086c5d05e75ae556dd2ffabf6c1269dcddb57211 Mon Sep 17 00:00:00 2001 From: Jeremy Wu Date: Wed, 5 Aug 2020 19:57:23 +1000 Subject: [PATCH 02/11] update to Flow --- .../Image/ImageCache.cs | 2 +- .../Image/ImageLoader.cs | 28 +++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Flow.Launcher.Infrastructure/Image/ImageCache.cs b/Flow.Launcher.Infrastructure/Image/ImageCache.cs index 67f00897210..15090919d98 100644 --- a/Flow.Launcher.Infrastructure/Image/ImageCache.cs +++ b/Flow.Launcher.Infrastructure/Image/ImageCache.cs @@ -5,7 +5,7 @@ using System.Threading.Tasks; using System.Windows.Media; -namespace Wox.Infrastructure.Image +namespace Flow.Launcher.Infrastructure.Image { [Serializable] public class ImageCache diff --git a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs index e03ee709a2a..10f827c409c 100644 --- a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs +++ b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs @@ -9,16 +9,16 @@ using Flow.Launcher.Infrastructure.Logger; using Flow.Launcher.Infrastructure.Storage; -namespace Wox.Infrastructure.Image +namespace Flow.Launcher.Infrastructure.Image { public static class ImageLoader { - private static readonly ImageCache _imageCache = new ImageCache(); + private static readonly ImageCache ImageCache = new ImageCache(); private static readonly ConcurrentDictionary _guidToKey = new ConcurrentDictionary(); - private static readonly bool _enableHashImage = true; - + private static readonly ConcurrentDictionary GuidToKey = new ConcurrentDictionary(); private static BinaryStorage> _storage; private static IImageHashGenerator _hashGenerator; + private static bool EnableImageHash = true; private static readonly string[] ImageExtensions = { @@ -36,25 +36,25 @@ public static void Initialize() _storage = new BinaryStorage>("Image"); _hashGenerator = new ImageHashGenerator(); - _imageCache.Usage = LoadStorageToConcurrentDictionary(); + ImageCache.Usage = LoadStorageToConcurrentDictionary(); foreach (var icon in new[] { Constant.DefaultIcon, Constant.ErrorIcon }) { ImageSource img = new BitmapImage(new Uri(icon)); img.Freeze(); - _imageCache[icon] = img; + ImageCache[icon] = img; } Task.Run(() => { Stopwatch.Normal("|ImageLoader.Initialize|Preload images cost", () => { - _imageCache.Usage.AsParallel().ForAll(x => + ImageCache.Usage.AsParallel().ForAll(x => { Load(x.Key); }); }); - Log.Info($"|ImageLoader.Initialize|Number of preload images is <{_imageCache.Usage.Count}>, Images Number: {_imageCache.CacheSize()}, Unique Items {_imageCache.UniqueImagesInCache()}"); + Log.Info($"|ImageLoader.Initialize|Number of preload images is <{ImageCache.Usage.Count}>, Images Number: {ImageCache.CacheSize()}, Unique Items {ImageCache.UniqueImagesInCache()}"); }); } @@ -106,11 +106,11 @@ private static ImageResult LoadInternal(string path, bool loadFullImage = false) { if (string.IsNullOrEmpty(path)) { - return new ImageResult(_imageCache[Constant.ErrorIcon], ImageType.Error); + return new ImageResult(ImageCache[Constant.ErrorIcon], ImageType.Error); } - if (_imageCache.ContainsKey(path)) + if (ImageCache.ContainsKey(path)) { - return new ImageResult(_imageCache[path], ImageType.Cache); + return new ImageResult(ImageCache[path], ImageType.Cache); } if (path.StartsWith("data:", StringComparison.OrdinalIgnoreCase)) @@ -139,8 +139,8 @@ private static ImageResult LoadInternal(string path, bool loadFullImage = false) Log.Exception($"|ImageLoader.Load|Failed to get thumbnail for {path} on first try", e); Log.Exception($"|ImageLoader.Load|Failed to get thumbnail for {path} on second try", e2); - ImageSource image = _imageCache[Constant.ErrorIcon]; - _imageCache[path] = image; + ImageSource image = ImageCache[Constant.ErrorIcon]; + ImageCache[path] = image; imageResult = new ImageResult(image, ImageType.Error); } } @@ -191,7 +191,7 @@ private static ImageResult GetThumbnailResult(ref string path, bool loadFullImag } else { - image = _imageCache[Constant.ErrorIcon]; + image = ImageCache[Constant.ErrorIcon]; path = Constant.ErrorIcon; } From 86f6f9921e58c1d29f5d6f9d960990c6dd564778 Mon Sep 17 00:00:00 2001 From: Jeremy Wu Date: Wed, 5 Aug 2020 19:57:53 +1000 Subject: [PATCH 03/11] update to use concurrent dictionary --- Flow.Launcher.Infrastructure/Image/ImageLoader.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs index 10f827c409c..573857c4323 100644 --- a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs +++ b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs @@ -14,9 +14,8 @@ namespace Flow.Launcher.Infrastructure.Image public static class ImageLoader { private static readonly ImageCache ImageCache = new ImageCache(); - private static readonly ConcurrentDictionary _guidToKey = new ConcurrentDictionary(); + private static BinaryStorage> _storage; private static readonly ConcurrentDictionary GuidToKey = new ConcurrentDictionary(); - private static BinaryStorage> _storage; private static IImageHashGenerator _hashGenerator; private static bool EnableImageHash = true; @@ -33,7 +32,7 @@ public static class ImageLoader public static void Initialize() { - _storage = new BinaryStorage>("Image"); + _storage = new BinaryStorage>("Image"); _hashGenerator = new ImageHashGenerator(); ImageCache.Usage = LoadStorageToConcurrentDictionary(); @@ -70,7 +69,7 @@ private static ConcurrentDictionary LoadStorageToConcurrentDictiona { lock(_storage) { - var loaded = _storage.TryLoad(new Dictionary()); + var loaded = _storage.TryLoad(new ConcurrentDictionary()); return new ConcurrentDictionary(loaded); } From ffa68a5a7b25d8d9d2d0fe82cb5e6b04bea257cb Mon Sep 17 00:00:00 2001 From: Jeremy Wu Date: Wed, 5 Aug 2020 19:58:48 +1000 Subject: [PATCH 04/11] use updated method from ImageCache class to save images to cache --- Flow.Launcher.Infrastructure/Image/ImageLoader.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs index 573857c4323..caff69fcf36 100644 --- a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs +++ b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs @@ -61,7 +61,8 @@ public static void Save() { lock (_storage) { - _storage.Save(_imageCache.CleanupAndToDictionary()); + ImageCache.Cleanup(); + _storage.Save(ImageCache.Usage); } } From ca08e603087601493526a0c716e7c57f0064b134 Mon Sep 17 00:00:00 2001 From: Jeremy Wu Date: Mon, 10 Aug 2020 07:17:22 +1000 Subject: [PATCH 05/11] revert-image cache as dictionary, concurrent not serializable --- Flow.Launcher.Infrastructure/Image/ImageLoader.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs index caff69fcf36..29e13a2de7c 100644 --- a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs +++ b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs @@ -14,7 +14,7 @@ namespace Flow.Launcher.Infrastructure.Image public static class ImageLoader { private static readonly ImageCache ImageCache = new ImageCache(); - private static BinaryStorage> _storage; + private static BinaryStorage> _storage; private static readonly ConcurrentDictionary GuidToKey = new ConcurrentDictionary(); private static IImageHashGenerator _hashGenerator; private static bool EnableImageHash = true; @@ -32,7 +32,7 @@ public static class ImageLoader public static void Initialize() { - _storage = new BinaryStorage>("Image"); + _storage = new BinaryStorage>("Image"); _hashGenerator = new ImageHashGenerator(); ImageCache.Usage = LoadStorageToConcurrentDictionary(); @@ -62,7 +62,7 @@ public static void Save() lock (_storage) { ImageCache.Cleanup(); - _storage.Save(ImageCache.Usage); + _storage.Save(new Dictionary(ImageCache.Usage)); } } @@ -70,7 +70,7 @@ private static ConcurrentDictionary LoadStorageToConcurrentDictiona { lock(_storage) { - var loaded = _storage.TryLoad(new ConcurrentDictionary()); + var loaded = _storage.TryLoad(new Dictionary()); return new ConcurrentDictionary(loaded); } From 4e534b56aca700207b547527449797583e5c2130 Mon Sep 17 00:00:00 2001 From: Arjun Balgovind <32061677+arjunbalgovind@users.noreply.github.com> Date: Mon, 10 Aug 2020 21:47:46 +1000 Subject: [PATCH 06/11] Skip ErrorIcon and DefaultIcon while resizing the dictionary. From arjunbalgovind:user/arbalgov/apperrorFix --- Flow.Launcher.Infrastructure/Image/ImageCache.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Flow.Launcher.Infrastructure/Image/ImageCache.cs b/Flow.Launcher.Infrastructure/Image/ImageCache.cs index 15090919d98..60a191a9ceb 100644 --- a/Flow.Launcher.Infrastructure/Image/ImageCache.cs +++ b/Flow.Launcher.Infrastructure/Image/ImageCache.cs @@ -38,7 +38,7 @@ public ImageSource this[string path] foreach (var key in _data.Keys) { int dictValue; - if (!Usage.TryGetValue(key, out dictValue)) + if (!Usage.TryGetValue(key, out dictValue) && !(key.Equals(Constant.ErrorIcon) || key.Equals(Constant.DefaultIcon))) { ImageSource imgSource; _data.TryRemove(key, out imgSource); From d3d69be9c275b14ce90786e7f58700979bb2ae18 Mon Sep 17 00:00:00 2001 From: Jeremy Wu Date: Wed, 11 Nov 2020 08:30:34 +1100 Subject: [PATCH 07/11] fix merge error --- Flow.Launcher.Infrastructure/Image/ImageLoader.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs index 4ae62dacd46..a1b677a1665 100644 --- a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs +++ b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs @@ -106,7 +106,7 @@ private static ImageResult LoadInternal(string path, bool loadFullImage = false) { if (string.IsNullOrEmpty(path)) { - return new ImageResult(_imageCache[Constant.MissingImgIcon], ImageType.Error); + return new ImageResult(ImageCache[Constant.MissingImgIcon], ImageType.Error); } if (ImageCache.ContainsKey(path)) { @@ -139,8 +139,8 @@ private static ImageResult LoadInternal(string path, bool loadFullImage = false) Log.Exception($"|ImageLoader.Load|Failed to get thumbnail for {path} on first try", e); Log.Exception($"|ImageLoader.Load|Failed to get thumbnail for {path} on second try", e2); - ImageSource image = _imageCache[Constant.MissingImgIcon]; - _imageCache[path] = image; + ImageSource image = ImageCache[Constant.MissingImgIcon]; + ImageCache[path] = image; imageResult = new ImageResult(image, ImageType.Error); } } @@ -191,7 +191,7 @@ private static ImageResult GetThumbnailResult(ref string path, bool loadFullImag } else { - image = _imageCache[Constant.MissingImgIcon]; + image = ImageCache[Constant.MissingImgIcon]; path = Constant.MissingImgIcon; } From bf271b9da7d8ea873268968caef10a40b865243a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=98=E9=9F=AC=20=E5=BC=A0?= Date: Sun, 8 Nov 2020 00:01:33 +0800 Subject: [PATCH 08/11] refactor Image Cache to single dictionary --- .../Image/ImageCache.cs | 56 ++++++++++--------- .../Image/ImageLoader.cs | 18 +++--- 2 files changed, 37 insertions(+), 37 deletions(-) diff --git a/Flow.Launcher.Infrastructure/Image/ImageCache.cs b/Flow.Launcher.Infrastructure/Image/ImageCache.cs index 60a191a9ceb..8f57928cb06 100644 --- a/Flow.Launcher.Infrastructure/Image/ImageCache.cs +++ b/Flow.Launcher.Infrastructure/Image/ImageCache.cs @@ -11,61 +11,65 @@ namespace Flow.Launcher.Infrastructure.Image public class ImageCache { private const int MaxCached = 50; - public ConcurrentDictionary Usage = new ConcurrentDictionary(); - private readonly ConcurrentDictionary _data = new ConcurrentDictionary(); + public ConcurrentDictionary Data { get; private set; } = new ConcurrentDictionary(); private const int permissibleFactor = 2; + public void Initialization(Dictionary usage) + { + foreach (var key in usage.Keys) + { + Data[key] = (usage[key], null); + } + } + public ImageSource this[string path] { get { - Usage.AddOrUpdate(path, 1, (k, v) => v + 1); - var i = _data[path]; - return i; + if (Data.TryGetValue(path, out var value)) + { + value.usage++; + return value.imageSource; + } + else return null; } set { - _data[path] = value; + Data.AddOrUpdate(path, (1, value), (k, v) => + { + v.imageSource = value; + v.usage++; + return v; + }); // To prevent the dictionary from drastically increasing in size by caching images, the dictionary size is not allowed to grow more than the permissibleFactor * maxCached size // This is done so that we don't constantly perform this resizing operation and also maintain the image cache size at the same time - if (_data.Count > permissibleFactor * MaxCached) + if (Data.Count > permissibleFactor * MaxCached) { - // This function resizes the Usage dictionary, taking the top 'maxCached' number of items and filtering the image icons that are not accessed frequently. - Cleanup(); - // To delete the images from the data dictionary based on the resizing of the Usage Dictionary. - foreach (var key in _data.Keys) + + + foreach (var key in Data.OrderBy(x => x.Value.usage).Take(Data.Count - MaxCached).Select(x => x.Key)) { - int dictValue; - if (!Usage.TryGetValue(key, out dictValue) && !(key.Equals(Constant.ErrorIcon) || key.Equals(Constant.DefaultIcon))) + if (!(key.Equals(Constant.ErrorIcon) || key.Equals(Constant.DefaultIcon))) { - ImageSource imgSource; - _data.TryRemove(key, out imgSource); + Data.TryRemove(key, out _); } } } } } - public void Cleanup() - { - var images = Usage - .OrderByDescending(o => o.Value) - .Take(MaxCached) - .ToDictionary(i => i.Key, i => i.Value); - Usage = new ConcurrentDictionary(images); - } public bool ContainsKey(string key) { - var contains = _data.ContainsKey(key); + var contains = Data.ContainsKey(key); return contains; } public int CacheSize() { - return _data.Count; + return Data.Count; } /// @@ -73,7 +77,7 @@ public int CacheSize() /// public int UniqueImagesInCache() { - return _data.Values.Distinct().Count(); + return Data.Values.Select(x => x.imageSource).Distinct().Count(); } } diff --git a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs index a1b677a1665..edfb88cbfe6 100644 --- a/Flow.Launcher.Infrastructure/Image/ImageLoader.cs +++ b/Flow.Launcher.Infrastructure/Image/ImageLoader.cs @@ -35,7 +35,7 @@ public static void Initialize() _storage = new BinaryStorage>("Image"); _hashGenerator = new ImageHashGenerator(); - ImageCache.Usage = LoadStorageToConcurrentDictionary(); + var usage = LoadStorageToConcurrentDictionary(); foreach (var icon in new[] { Constant.DefaultIcon, Constant.MissingImgIcon }) { @@ -48,12 +48,12 @@ public static void Initialize() { Stopwatch.Normal("|ImageLoader.Initialize|Preload images cost", () => { - ImageCache.Usage.AsParallel().ForAll(x => + ImageCache.Data.AsParallel().ForAll(x => { Load(x.Key); }); }); - Log.Info($"|ImageLoader.Initialize|Number of preload images is <{ImageCache.Usage.Count}>, Images Number: {ImageCache.CacheSize()}, Unique Items {ImageCache.UniqueImagesInCache()}"); + Log.Info($"|ImageLoader.Initialize|Number of preload images is <{ImageCache.CacheSize()}>, Images Number: {ImageCache.CacheSize()}, Unique Items {ImageCache.UniqueImagesInCache()}"); }); } @@ -61,14 +61,13 @@ public static void Save() { lock (_storage) { - ImageCache.Cleanup(); - _storage.Save(new Dictionary(ImageCache.Usage)); + _storage.Save(ImageCache.Data.Select(x => (x.Key, x.Value.usage)).ToDictionary(x => x.Key, y => y.usage)); } } private static ConcurrentDictionary LoadStorageToConcurrentDictionary() { - lock(_storage) + lock (_storage) { var loaded = _storage.TryLoad(new Dictionary()); @@ -222,13 +221,10 @@ public static ImageSource Load(string path, bool loadFullImage = false) string hash = EnableImageHash ? _hashGenerator.GetHashFromImage(img) : null; if (hash != null) { - int ImageCacheValue; + if (GuidToKey.TryGetValue(hash, out string key)) { // image already exists - if (ImageCache.Usage.TryGetValue(path, out ImageCacheValue)) - { - img = ImageCache[key]; - } + img = ImageCache[key] ?? img; } else { // new guid From 55fb5536bd04332b639f3f87c601d85a429aaccf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=98=E9=9F=AC=20=E5=BC=A0?= Date: Wed, 11 Nov 2020 10:56:53 +0800 Subject: [PATCH 09/11] change struct to class to use reference type --- .../Image/ImageCache.cs | 31 +++++++++++++------ 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/Flow.Launcher.Infrastructure/Image/ImageCache.cs b/Flow.Launcher.Infrastructure/Image/ImageCache.cs index 8f57928cb06..328e508286d 100644 --- a/Flow.Launcher.Infrastructure/Image/ImageCache.cs +++ b/Flow.Launcher.Infrastructure/Image/ImageCache.cs @@ -8,17 +8,30 @@ namespace Flow.Launcher.Infrastructure.Image { [Serializable] + public class ImageUsage + { + + public int usage; + public ImageSource imageSource; + + public ImageUsage(int usage, ImageSource image) + { + this.usage = usage; + imageSource = image; + } + } + public class ImageCache { private const int MaxCached = 50; - public ConcurrentDictionary Data { get; private set; } = new ConcurrentDictionary(); + public ConcurrentDictionary Data { get; private set; } = new ConcurrentDictionary(); private const int permissibleFactor = 2; public void Initialization(Dictionary usage) { foreach (var key in usage.Keys) { - Data[key] = (usage[key], null); + Data[key] = new ImageUsage(usage[key], null); } } @@ -35,12 +48,12 @@ public ImageSource this[string path] } set { - Data.AddOrUpdate(path, (1, value), (k, v) => - { - v.imageSource = value; - v.usage++; - return v; - }); + Data.AddOrUpdate(path, new ImageUsage(0, value), (k, v) => + { + v.imageSource = value; + v.usage++; + return v; + }); // To prevent the dictionary from drastically increasing in size by caching images, the dictionary size is not allowed to grow more than the permissibleFactor * maxCached size // This is done so that we don't constantly perform this resizing operation and also maintain the image cache size at the same time @@ -48,7 +61,7 @@ public ImageSource this[string path] { // To delete the images from the data dictionary based on the resizing of the Usage Dictionary. - + foreach (var key in Data.OrderBy(x => x.Value.usage).Take(Data.Count - MaxCached).Select(x => x.Key)) { if (!(key.Equals(Constant.ErrorIcon) || key.Equals(Constant.DefaultIcon))) From 822621dd3ba24401b9d93b89a403c0098f132168 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=98=E9=9F=AC=20=E5=BC=A0?= Date: Wed, 11 Nov 2020 18:53:48 +0800 Subject: [PATCH 10/11] remove unintended module --- Plugins/Flow.Launcher.Plugin.Everything | 1 - 1 file changed, 1 deletion(-) delete mode 160000 Plugins/Flow.Launcher.Plugin.Everything diff --git a/Plugins/Flow.Launcher.Plugin.Everything b/Plugins/Flow.Launcher.Plugin.Everything deleted file mode 160000 index 6d5b687e240..00000000000 --- a/Plugins/Flow.Launcher.Plugin.Everything +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 6d5b687e240a6abdc5623d8a8e09501f3994b0d3 From 26285abfd745d32d66d724e74f7a0356b4706c81 Mon Sep 17 00:00:00 2001 From: Jeremy Wu Date: Thu, 12 Nov 2020 13:34:23 +1100 Subject: [PATCH 11/11] fix formatting --- .../Image/ImageCache.cs | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/Flow.Launcher.Infrastructure/Image/ImageCache.cs b/Flow.Launcher.Infrastructure/Image/ImageCache.cs index 328e508286d..80c6684f55c 100644 --- a/Flow.Launcher.Infrastructure/Image/ImageCache.cs +++ b/Flow.Launcher.Infrastructure/Image/ImageCache.cs @@ -44,16 +44,21 @@ public ImageSource this[string path] value.usage++; return value.imageSource; } - else return null; + + return null; } set { - Data.AddOrUpdate(path, new ImageUsage(0, value), (k, v) => - { - v.imageSource = value; - v.usage++; - return v; - }); + Data.AddOrUpdate( + path, + new ImageUsage(0, value), + (k, v) => + { + v.imageSource = value; + v.usage++; + return v; + } + ); // To prevent the dictionary from drastically increasing in size by caching images, the dictionary size is not allowed to grow more than the permissibleFactor * maxCached size // This is done so that we don't constantly perform this resizing operation and also maintain the image cache size at the same time @@ -73,7 +78,6 @@ public ImageSource this[string path] } } - public bool ContainsKey(string key) { var contains = Data.ContainsKey(key);