Skip to content

Commit d6f40ec

Browse files
committed
Use concurrent way to load favorite icons for chromium
1 parent 0ec38fa commit d6f40ec

File tree

1 file changed

+30
-15
lines changed

1 file changed

+30
-15
lines changed

Plugins/Flow.Launcher.Plugin.BrowserBookmark/ChromiumBookmarkLoader.cs

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
using System.Collections.Generic;
1+
using System;
2+
using System.Collections.Concurrent;
3+
using System.Collections.Generic;
24
using System.IO;
35
using System.Text.Json;
4-
using System;
6+
using System.Threading.Tasks;
57
using Flow.Launcher.Plugin.BrowserBookmark.Models;
68
using Microsoft.Data.Sqlite;
79

@@ -156,19 +158,24 @@ private void LoadFaviconsFromDb(string dbPath, List<Bookmark> bookmarks)
156158

157159
try
158160
{
159-
using var connection = new SqliteConnection($"Data Source={tempDbPath}");
160-
connection.Open();
161+
// Since some bookmarks may have same favorite icon id, we need to record them to avoid duplicates
162+
var savedPaths = new ConcurrentDictionary<string, bool>();
161163

162-
foreach (var bookmark in bookmarks)
164+
// Get favicons based on bookmarks concurrently
165+
Parallel.ForEach(bookmarks.ToArray(), bookmark =>
163166
{
167+
// Use read-only connection to avoid locking issues
168+
var connection = new SqliteConnection($"Data Source={tempDbPath};Mode=ReadOnly");
169+
connection.Open();
170+
164171
try
165172
{
166173
var url = bookmark.Url;
167-
if (string.IsNullOrEmpty(url)) continue;
174+
if (string.IsNullOrEmpty(url)) return;
168175

169176
// Extract domain from URL
170177
if (!Uri.TryCreate(url, UriKind.Absolute, out Uri uri))
171-
continue;
178+
return;
172179

173180
var domain = uri.Host;
174181

@@ -186,28 +193,36 @@ ORDER BY b.width DESC
186193

187194
using var reader = cmd.ExecuteReader();
188195
if (!reader.Read() || reader.IsDBNull(1))
189-
continue;
196+
return;
190197

191198
var iconId = reader.GetInt64(0).ToString();
192199
var imageData = (byte[])reader["image_data"];
193200

194201
if (imageData is not { Length: > 0 })
195-
continue;
202+
return;
196203

197204
var faviconPath = Path.Combine(_faviconCacheDir, $"chromium_{domain}_{iconId}.png");
198-
SaveBitmapData(imageData, faviconPath);
205+
206+
// Filter out duplicate favorite icons
207+
if (savedPaths.TryAdd(faviconPath, true))
208+
{
209+
SaveBitmapData(imageData, faviconPath);
210+
}
199211

200212
bookmark.FaviconPath = faviconPath;
201213
}
202214
catch (Exception ex)
203215
{
204216
Main._context.API.LogException(ClassName, $"Failed to extract bookmark favicon: {bookmark.Url}", ex);
205217
}
206-
}
207-
208-
// https://github.com/dotnet/efcore/issues/26580
209-
SqliteConnection.ClearPool(connection);
210-
connection.Close();
218+
finally
219+
{
220+
// https://github.com/dotnet/efcore/issues/26580
221+
SqliteConnection.ClearPool(connection);
222+
connection.Close();
223+
connection.Dispose();
224+
}
225+
});
211226
}
212227
catch (Exception ex)
213228
{

0 commit comments

Comments
 (0)