@@ -49,9 +49,11 @@ public FlowLauncherJsonStorageTopMostRecord()
49
49
if ( oldTopMostRecord == null || oldTopMostRecord . records . IsEmpty ) return ;
50
50
foreach ( var record in oldTopMostRecord . records )
51
51
{
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 ) =>
53
55
{
54
- oldValue . Add ( record . Value ) ;
56
+ oldValue . Enqueue ( record . Value ) ;
55
57
return oldValue ;
56
58
} ) ;
57
59
}
@@ -84,6 +86,11 @@ public bool IsTopMost(Result result)
84
86
return _topMostRecord . IsTopMost ( result ) ;
85
87
}
86
88
89
+ public int GetTopMostIndex ( Result result )
90
+ {
91
+ return _topMostRecord . GetTopMostIndex ( result ) ;
92
+ }
93
+
87
94
public void Remove ( Result result )
88
95
{
89
96
_topMostRecord . Remove ( result ) ;
@@ -156,8 +163,8 @@ internal void AddOrUpdate(Result result)
156
163
internal class MultipleTopMostRecord
157
164
{
158
165
[ 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 ( ) ;
161
168
162
169
internal bool IsTopMost ( Result result )
163
170
{
@@ -173,6 +180,32 @@ internal bool IsTopMost(Result result)
173
180
return value . Any ( record => record . Equals ( result ) ) ;
174
181
}
175
182
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
+
176
209
internal void Remove ( Result result )
177
210
{
178
211
// 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)
183
216
return ;
184
217
}
185
218
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 )
189
222
{
190
- // if the bag is empty, remove the bag from the dictionary
223
+ // if the queue is empty, remove the queue from the dictionary
191
224
records . TryRemove ( result . OriginQuery . RawQuery , out _ ) ;
192
225
}
193
226
else
194
227
{
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 ;
197
230
}
198
231
}
199
232
@@ -215,40 +248,38 @@ internal void AddOrUpdate(Result result)
215
248
} ;
216
249
if ( ! records . TryGetValue ( result . OriginQuery . RawQuery , out var value ) )
217
250
{
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 ) ;
223
254
records . TryAdd ( result . OriginQuery . RawQuery , value ) ;
224
255
}
225
256
else
226
257
{
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 ;
231
262
}
232
263
}
233
264
}
234
265
235
266
/// <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
237
268
/// </summary>
238
- internal class ConcurrentDictionaryConcurrentBagConverter : JsonConverter < ConcurrentDictionary < string , ConcurrentBag < Record > > >
269
+ internal class ConcurrentDictionaryConcurrentQueueConverter : JsonConverter < ConcurrentDictionary < string , ConcurrentQueue < Record > > >
239
270
{
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 )
241
272
{
242
273
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 > > ( ) ;
244
275
foreach ( var kvp in dictionary )
245
276
{
246
- concurrentDictionary . TryAdd ( kvp . Key , new ConcurrentBag < Record > ( kvp . Value ) ) ;
277
+ concurrentDictionary . TryAdd ( kvp . Key , new ConcurrentQueue < Record > ( kvp . Value ) ) ;
247
278
}
248
279
return concurrentDictionary ;
249
280
}
250
281
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 )
252
283
{
253
284
var dict = new Dictionary < string , List < Record > > ( ) ;
254
285
foreach ( var kvp in value )
0 commit comments