Skip to content

Commit

Permalink
chore: refactored UniqueNameBuilder for improved performance (#493)
Browse files Browse the repository at this point in the history
  • Loading branch information
TimothyMakkison authored Jun 13, 2023
1 parent 230dffc commit 85347e4
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ namespace Riok.Mapperly.Descriptors.Enumerables.EnsureCapacity;
/// </remarks>
public class EnsureCapacityNonEnumerated : EnsureCapacity
{
private const string SourceCountVariableName = "sourceCount";
private readonly string _targetAccessor;
private readonly IMethodSymbol _getNonEnumeratedMethod;

Expand All @@ -33,7 +34,7 @@ public override StatementSyntax Build(TypeMappingBuildContext ctx, ExpressionSyn
{
var targetCount = MemberAccess(target, _targetAccessor);

var countIdentifier = Identifier(ctx.NameBuilder.New("sourceCount"));
var countIdentifier = Identifier(ctx.NameBuilder.New(SourceCountVariableName));
var countIdentifierName = IdentifierName(countIdentifier);

var enumerableArgument = Argument(ctx.Source);
Expand Down
23 changes: 19 additions & 4 deletions src/Riok.Mapperly/Helpers/UniqueNameBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,46 @@ namespace Riok.Mapperly.Helpers;
public class UniqueNameBuilder
{
private readonly HashSet<string> _usedNames;
private readonly UniqueNameBuilder? _parentScope;

public UniqueNameBuilder()
{
_usedNames = new HashSet<string>();
}

private UniqueNameBuilder(IEnumerable<string> usedNames)
private UniqueNameBuilder(UniqueNameBuilder parentScope)
{
_usedNames = new HashSet<string>(usedNames);
_usedNames = new HashSet<string>();
_parentScope = parentScope;
}

public void Reserve(string name) => _usedNames.Add(name);

public UniqueNameBuilder NewScope() => new(_usedNames);
public UniqueNameBuilder NewScope() => new(this);

public string New(string name)
{
var i = 0;
var uniqueName = name;
while (!_usedNames.Add(uniqueName))
while (Contains(uniqueName))
{
i++;
uniqueName = name + i;
}

_usedNames.Add(uniqueName);

return uniqueName;
}

private bool Contains(string name)
{
if (_usedNames.Contains(name))
return true;

if (_parentScope != null)
return _parentScope.Contains(name);

return false;
}
}

0 comments on commit 85347e4

Please sign in to comment.