Skip to content

Commit 70d1986

Browse files
committed
Merge branch 'optimization/messenger-shared-pool' into feature/weak-tracking-messenger
2 parents c6553d1 + 6f0f7c3 commit 70d1986

File tree

3 files changed

+27
-55
lines changed

3 files changed

+27
-55
lines changed

Microsoft.Toolkit.Mvvm/Messaging/Internals/Microsoft.Collections.Extensions/DictionarySlim{TKey,TValue}.cs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -218,13 +218,6 @@ public bool TryRemove(TKey key, out object? result)
218218
return false;
219219
}
220220

221-
/// <inheritdoc/>
222-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
223-
public bool Remove(TKey key)
224-
{
225-
return TryRemove(key, out _);
226-
}
227-
228221
/// <summary>
229222
/// Gets the value for the specified key, or, if the key is not present,
230223
/// adds an entry and returns the value by ref. This makes it possible to

Microsoft.Toolkit.Mvvm/Messaging/Internals/Microsoft.Collections.Extensions/IDictionarySlim{TKey}.cs

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,11 @@ internal interface IDictionarySlim<in TKey> : IDictionarySlim
2121
public bool ContainsKey(TKey key);
2222

2323
/// <summary>
24-
/// Tries to remove a value with a specified key.
24+
/// Tries to remove a value with a specified key, if present.
2525
/// </summary>
2626
/// <param name="key">The key of the value to remove.</param>
2727
/// <param name="result">The removed value, if it was present.</param>
2828
/// <returns>Whether or not the key was present.</returns>
2929
bool TryRemove(TKey key, out object? result);
30-
31-
/// <summary>
32-
/// Removes an item from the dictionary with the specified key, if present.
33-
/// </summary>
34-
/// <param name="key">The key of the item to remove.</param>
35-
/// <returns>Whether or not an item was removed.</returns>
36-
bool Remove(TKey key);
3730
}
3831
}

Microsoft.Toolkit.Mvvm/Messaging/Messenger.cs

Lines changed: 26 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -157,18 +157,8 @@ public void UnregisterAll(object recipient)
157157
// Removes all the lists of registered handlers for the recipient
158158
foreach (IMapping mapping in set!)
159159
{
160-
if (mapping.TryRemove(key, out object? handlersMap))
160+
if (mapping.TryRemove(key, out _))
161161
{
162-
// If this branch is taken, it means the target recipient to unregister
163-
// had at least one registered handler for the current <TToken, TMessage>
164-
// pair of type parameters, which here is masked out by the IMapping interface.
165-
// Before removing the handlers, we need to retrieve the count of how many handlers
166-
// are being removed, in order to update the total counter for the mapping.
167-
// Just casting the dictionary to the base interface and accessing the Count
168-
// property directly gives us O(1) access time to retrieve this count.
169-
// The handlers map is the IDictionary<TToken, TMessage> instance for the mapping.
170-
int handlersCount = Unsafe.As<IDictionarySlim>(handlersMap).Count;
171-
172162
if (mapping.Count == 0)
173163
{
174164
// Maps here are really of type Mapping<,> and with unknown type arguments.
@@ -179,13 +169,13 @@ public void UnregisterAll(object recipient)
179169
// dictionary (a hashed collection) only costs O(1) in the best case, while
180170
// if we had tried to iterate the whole dictionary every time we would have
181171
// paid an O(n) minimum cost for each single remove operation.
182-
this.typesMap.Remove(mapping.TypeArguments);
172+
this.typesMap.TryRemove(mapping.TypeArguments, out _);
183173
}
184174
}
185175
}
186176

187177
// Remove the associated set in the recipients map
188-
this.recipientsMap.Remove(key);
178+
this.recipientsMap.TryRemove(key, out _);
189179
}
190180
}
191181

@@ -253,26 +243,24 @@ public void UnregisterAll<TToken>(object recipient, TToken token)
253243

254244
// Try to remove the registered handler for the input token,
255245
// for the current message type (unknown from here).
256-
if (holder.Remove(token))
246+
if (holder.TryRemove(token, out _) &&
247+
holder.Count == 0)
257248
{
258-
if (holder.Count == 0)
259-
{
260-
// If the map is empty, remove the recipient entirely from its container
261-
map.Remove(key);
249+
// If the map is empty, remove the recipient entirely from its container
250+
map.TryRemove(key, out _);
262251

263-
if (map.Count == 0)
252+
if (map.Count == 0)
253+
{
254+
// If no handlers are left at all for the recipient, across all
255+
// message types and token types, remove the set of mappings
256+
// entirely for the current recipient, and lost the strong
257+
// reference to it as well. This is the same situation that
258+
// would've been achieved by just calling UnregisterAll(recipient).
259+
set.Remove(Unsafe.As<IMapping>(map));
260+
261+
if (set.Count == 0)
264262
{
265-
// If no handlers are left at all for the recipient, across all
266-
// message types and token types, remove the set of mappings
267-
// entirely for the current recipient, and lost the strong
268-
// reference to it as well. This is the same situation that
269-
// would've been achieved by just calling UnregisterAll(recipient).
270-
set.Remove(Unsafe.As<IMapping>(map));
271-
272-
if (set.Count == 0)
273-
{
274-
this.recipientsMap.Remove(key);
275-
}
263+
this.recipientsMap.TryRemove(key, out _);
276264
}
277265
}
278266
}
@@ -320,25 +308,23 @@ public void Unregister<TMessage, TToken>(object recipient, TToken token)
320308
}
321309

322310
// Remove the target handler
323-
if (dictionary!.Remove(token))
311+
if (dictionary!.TryRemove(token, out _) &&
312+
dictionary.Count == 0)
324313
{
325314
// If the map is empty, it means that the current recipient has no remaining
326315
// registered handlers for the current <TMessage, TToken> combination, regardless,
327316
// of the specific token value (ie. the channel used to receive messages of that type).
328317
// We can remove the map entirely from this container, and remove the link to the map itself
329318
// to the current mapping between existing registered recipients (or entire recipients too).
330-
if (dictionary.Count == 0)
331-
{
332-
mapping.Remove(key);
319+
mapping.TryRemove(key, out _);
333320

334-
HashSet<IMapping> set = this.recipientsMap[key];
321+
HashSet<IMapping> set = this.recipientsMap[key];
335322

336-
set.Remove(mapping);
323+
set.Remove(mapping);
337324

338-
if (set.Count == 0)
339-
{
340-
this.recipientsMap.Remove(key);
341-
}
325+
if (set.Count == 0)
326+
{
327+
this.recipientsMap.TryRemove(key, out _);
342328
}
343329
}
344330
}

0 commit comments

Comments
 (0)