Skip to content

Commit b25777b

Browse files
committed
Use ConcurrentQueue to storage the data sequence & Put latter record topper
1 parent 7103c8d commit b25777b

File tree

2 files changed

+59
-27
lines changed

2 files changed

+59
-27
lines changed

Flow.Launcher/Storage/TopMostRecord.cs

Lines changed: 56 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,11 @@ public FlowLauncherJsonStorageTopMostRecord()
4949
if (oldTopMostRecord == null || oldTopMostRecord.records.IsEmpty) return;
5050
foreach (var record in oldTopMostRecord.records)
5151
{
52-
_topMostRecord.records.AddOrUpdate(record.Key, new ConcurrentBag<Record> { record.Value }, (key, oldValue) =>
52+
var newValue = new ConcurrentQueue<Record>();
53+
newValue.Enqueue(record.Value);
54+
_topMostRecord.records.AddOrUpdate(record.Key, newValue, (key, oldValue) =>
5355
{
54-
oldValue.Add(record.Value);
56+
oldValue.Enqueue(record.Value);
5557
return oldValue;
5658
});
5759
}
@@ -84,6 +86,11 @@ public bool IsTopMost(Result result)
8486
return _topMostRecord.IsTopMost(result);
8587
}
8688

89+
public int GetTopMostIndex(Result result)
90+
{
91+
return _topMostRecord.GetTopMostIndex(result);
92+
}
93+
8794
public void Remove(Result result)
8895
{
8996
_topMostRecord.Remove(result);
@@ -156,8 +163,8 @@ internal void AddOrUpdate(Result result)
156163
internal class MultipleTopMostRecord
157164
{
158165
[JsonInclude]
159-
[JsonConverter(typeof(ConcurrentDictionaryConcurrentBagConverter))]
160-
public ConcurrentDictionary<string, ConcurrentBag<Record>> records { get; private set; } = new();
166+
[JsonConverter(typeof(ConcurrentDictionaryConcurrentQueueConverter))]
167+
public ConcurrentDictionary<string, ConcurrentQueue<Record>> records { get; private set; } = new();
161168

162169
internal bool IsTopMost(Result result)
163170
{
@@ -173,6 +180,32 @@ internal bool IsTopMost(Result result)
173180
return value.Any(record => record.Equals(result));
174181
}
175182

183+
internal int GetTopMostIndex(Result result)
184+
{
185+
// origin query is null when user select the context menu item directly of one item from query list
186+
// in this case, we do not need to check if the result is top most
187+
if (records.IsEmpty || result.OriginQuery == null ||
188+
!records.TryGetValue(result.OriginQuery.RawQuery, out var value))
189+
{
190+
return -1;
191+
}
192+
193+
// since this dictionary should be very small (or empty) going over it should be pretty fast.
194+
// since the latter items should be more recent, we should return the smaller index for score to subtract
195+
// which can make them more topmost
196+
// A, B, C => 2, 1, 0 => (max - 2), (max - 1), (max - 0)
197+
var index = 0;
198+
foreach (var record in value)
199+
{
200+
if (record.Equals(result))
201+
{
202+
return value.Count - 1 - index;
203+
}
204+
index++;
205+
}
206+
return -1;
207+
}
208+
176209
internal void Remove(Result result)
177210
{
178211
// origin query is null when user select the context menu item directly of one item from query list
@@ -183,17 +216,17 @@ internal void Remove(Result result)
183216
return;
184217
}
185218

186-
// remove the record from the bag
187-
var bag = new ConcurrentQueue<Record>(value.Where(r => !r.Equals(result)));
188-
if (bag.IsEmpty)
219+
// remove the record from the queue
220+
var queue = new ConcurrentQueue<Record>(value.Where(r => !r.Equals(result)));
221+
if (queue.IsEmpty)
189222
{
190-
// if the bag is empty, remove the bag from the dictionary
223+
// if the queue is empty, remove the queue from the dictionary
191224
records.TryRemove(result.OriginQuery.RawQuery, out _);
192225
}
193226
else
194227
{
195-
// change the bag in the dictionary
196-
records[result.OriginQuery.RawQuery] = new ConcurrentBag<Record>(bag);
228+
// change the queue in the dictionary
229+
records[result.OriginQuery.RawQuery] = queue;
197230
}
198231
}
199232

@@ -215,40 +248,38 @@ internal void AddOrUpdate(Result result)
215248
};
216249
if (!records.TryGetValue(result.OriginQuery.RawQuery, out var value))
217250
{
218-
// create a new bag if it does not exist
219-
value = new ConcurrentBag<Record>()
220-
{
221-
record
222-
};
251+
// create a new queue if it does not exist
252+
value = new ConcurrentQueue<Record>();
253+
value.Enqueue(record);
223254
records.TryAdd(result.OriginQuery.RawQuery, value);
224255
}
225256
else
226257
{
227-
// add or update the record in the bag
228-
var bag = new ConcurrentQueue<Record>(value.Where(r => !r.Equals(result))); // make sure we don't have duplicates
229-
bag.Enqueue(record);
230-
records[result.OriginQuery.RawQuery] = new ConcurrentBag<Record>(bag);
258+
// add or update the record in the queue
259+
var queue = new ConcurrentQueue<Record>(value.Where(r => !r.Equals(result))); // make sure we don't have duplicates
260+
queue.Enqueue(record);
261+
records[result.OriginQuery.RawQuery] = queue;
231262
}
232263
}
233264
}
234265

235266
/// <summary>
236-
/// Because ConcurrentBag does not support serialization, we need to convert it to a List
267+
/// Because ConcurrentQueue does not support serialization, we need to convert it to a List
237268
/// </summary>
238-
internal class ConcurrentDictionaryConcurrentBagConverter : JsonConverter<ConcurrentDictionary<string, ConcurrentBag<Record>>>
269+
internal class ConcurrentDictionaryConcurrentQueueConverter : JsonConverter<ConcurrentDictionary<string, ConcurrentQueue<Record>>>
239270
{
240-
public override ConcurrentDictionary<string, ConcurrentBag<Record>> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
271+
public override ConcurrentDictionary<string, ConcurrentQueue<Record>> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
241272
{
242273
var dictionary = JsonSerializer.Deserialize<Dictionary<string, List<Record>>>(ref reader, options);
243-
var concurrentDictionary = new ConcurrentDictionary<string, ConcurrentBag<Record>>();
274+
var concurrentDictionary = new ConcurrentDictionary<string, ConcurrentQueue<Record>>();
244275
foreach (var kvp in dictionary)
245276
{
246-
concurrentDictionary.TryAdd(kvp.Key, new ConcurrentBag<Record>(kvp.Value));
277+
concurrentDictionary.TryAdd(kvp.Key, new ConcurrentQueue<Record>(kvp.Value));
247278
}
248279
return concurrentDictionary;
249280
}
250281

251-
public override void Write(Utf8JsonWriter writer, ConcurrentDictionary<string, ConcurrentBag<Record>> value, JsonSerializerOptions options)
282+
public override void Write(Utf8JsonWriter writer, ConcurrentDictionary<string, ConcurrentQueue<Record>> value, JsonSerializerOptions options)
252283
{
253284
var dict = new Dictionary<string, List<Record>>();
254285
foreach (var kvp in value)

Flow.Launcher/ViewModel/MainViewModel.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1643,9 +1643,10 @@ public void UpdateResultView(ICollection<ResultsForUpdate> resultsForUpdates)
16431643
{
16441644
foreach (var result in metaResults.Results)
16451645
{
1646-
if (_topMostRecord.IsTopMost(result))
1646+
var deviationIndex = _topMostRecord.GetTopMostIndex(result);
1647+
if (deviationIndex != -1)
16471648
{
1648-
result.Score = Result.MaxScore;
1649+
result.Score = Result.MaxScore - deviationIndex;
16491650
}
16501651
else
16511652
{

0 commit comments

Comments
 (0)