Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions Source/Mockolate/MockRegistry.Setup.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Diagnostics;
using System.Threading;
using Mockolate.Interactions;
using Mockolate.Setup;

namespace Mockolate;
Expand All @@ -10,6 +11,14 @@ public partial class MockRegistry
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private readonly object _setupsByMemberIdLock = new();

/// <summary>
/// Returns the generator-known member count hint when <see cref="Interactions" /> is a
/// <see cref="FastMockInteractions" />, so dispatch tables can be sized once on first allocation
/// instead of growing one slot at a time as setups for higher-numbered members come in.
/// </summary>
private int GetMemberCountHint()
=> Interactions is FastMockInteractions fast ? fast.Buffers.Length : 0;

[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private EventSetup[]?[]? _eventSetupsByMemberId;

Expand Down Expand Up @@ -84,7 +93,7 @@ private void AppendToIndexerMemberIdBucket(int memberId, IndexerSetup indexerSet
IndexerSetup[]?[]? oldTable = _indexerSetupsByMemberId;
int requiredLen = memberId + 1;
// Stryker disable once Conditional : when oldTable is not null and requiredLen <= oldTable.Length, the resize-condition below is false either way and the else-branch reuses oldTable; newLen is unread, so collapsing the ternary to requiredLen is observationally identical.
int newLen = oldTable is null ? requiredLen : Math.Max(oldTable.Length, requiredLen);
int newLen = oldTable is null ? Math.Max(requiredLen, GetMemberCountHint()) : Math.Max(oldTable.Length, requiredLen);
IndexerSetup[]?[] newTable;
// Stryker disable once Equality : flipping > to >= only fires the realloc-and-copy path when newLen == oldTable.Length, producing a fresh table with identical contents — externally indistinguishable from reusing oldTable.
if (oldTable is null || newLen > oldTable.Length)
Expand Down Expand Up @@ -180,7 +189,7 @@ private void AppendToMemberIdBucket(int memberId, MethodSetup methodSetup)
MethodSetup[]?[]? oldTable = _setupsByMemberId;
int requiredLen = memberId + 1;
// Stryker disable once Conditional : when oldTable is not null and requiredLen <= oldTable.Length, the resize-condition below is false either way and the else-branch reuses oldTable; newLen is unread, so collapsing the ternary to requiredLen is observationally identical.
int newLen = oldTable is null ? requiredLen : Math.Max(oldTable.Length, requiredLen);
int newLen = oldTable is null ? Math.Max(requiredLen, GetMemberCountHint()) : Math.Max(oldTable.Length, requiredLen);
MethodSetup[]?[] newTable;
// Stryker disable once Equality : flipping > to >= only fires the realloc-and-copy path when newLen == oldTable.Length, producing a fresh table with identical contents — externally indistinguishable from reusing oldTable.
if (oldTable is null || newLen > oldTable.Length)
Expand Down Expand Up @@ -275,7 +284,7 @@ private void PublishPropertyToMemberIdBucket(int memberId, PropertySetup propert
PropertySetup?[]? oldTable = _propertySetupsByMemberId;
int requiredLen = memberId + 1;
// Stryker disable once Conditional : when oldTable is not null and requiredLen <= oldTable.Length, the resize-condition below is false either way and the else-branch reuses oldTable; newLen is unread, so collapsing the ternary to requiredLen is observationally identical.
int newLen = oldTable is null ? requiredLen : Math.Max(oldTable.Length, requiredLen);
int newLen = oldTable is null ? Math.Max(requiredLen, GetMemberCountHint()) : Math.Max(oldTable.Length, requiredLen);
PropertySetup?[] newTable;
// Stryker disable once Equality : flipping > to >= only fires the realloc-and-copy path when newLen == oldTable.Length, producing a fresh table with identical contents — externally indistinguishable from reusing oldTable.
if (oldTable is null || newLen > oldTable.Length)
Expand Down Expand Up @@ -365,7 +374,7 @@ private void AppendToEventMemberIdBucket(int memberId, EventSetup eventSetup)
EventSetup[]?[]? oldTable = _eventSetupsByMemberId;
int requiredLen = memberId + 1;
// Stryker disable once Conditional : when oldTable is not null and requiredLen <= oldTable.Length, the resize-condition below is false either way and the else-branch reuses oldTable; newLen is unread, so collapsing the ternary to requiredLen is observationally identical.
int newLen = oldTable is null ? requiredLen : Math.Max(oldTable.Length, requiredLen);
int newLen = oldTable is null ? Math.Max(requiredLen, GetMemberCountHint()) : Math.Max(oldTable.Length, requiredLen);
EventSetup[]?[] newTable;
// Stryker disable once Equality : flipping > to >= only fires the realloc-and-copy path when newLen == oldTable.Length, producing a fresh table with identical contents — externally indistinguishable from reusing oldTable.
if (oldTable is null || newLen > oldTable.Length)
Expand Down
Loading