Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch CreateNodeAsync to an iterative approach #5624

Merged
merged 8 commits into from
Feb 23, 2024
Merged
Show file tree
Hide file tree
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
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ public static IEnumerable<RestoreLogMessage> GetMissingLowerBounds(IEnumerable<I
foreach (var graph in graphs)
{
messages.AddRange(graph.ResolvedDependencies
.Distinct()
.Where(e => !ignoreIds.Contains(e.Child.Name, StringComparer.OrdinalIgnoreCase)
&& DependencyRangeHasMissingExactMatch(e))
.OrderBy(e => e.Child.Name, StringComparer.OrdinalIgnoreCase)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -704,19 +704,18 @@ private static IEnumerable<string> GetLanguageConditions(string language, Sorted

public static string GetLanguage(string nugetLanguage)
{
var lang = nugetLanguage.ToUpperInvariant();

// Translate S -> #
switch (lang)
if (StringComparer.OrdinalIgnoreCase.Equals(nugetLanguage, "CS"))
{
return "C#";
}
else if (StringComparer.OrdinalIgnoreCase.Equals(nugetLanguage, "FS"))
{
case "CS":
return "C#";
case "FS":
return "F#";
return "F#";
}

// Return the language as it is
return lang;
return nugetLanguage.ToUpperInvariant();
}

private static IEnumerable<MSBuildRestoreItemGroup> GetLanguageGroups(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ internal bool AreAllParentsRejected()
/// <param name="additionalSpace">The count of additional items that will be added.</param>
internal void EnsureInnerNodeCapacity(int additionalSpace)
{
if (additionalSpace <= 0)
{
return;
}

if (InnerNodes is List<GraphNode<TItem>> innerList)
{
int requiredCapacity = innerList.Count + additionalSpace;
Expand All @@ -70,6 +75,10 @@ internal void EnsureInnerNodeCapacity(int additionalSpace)
innerList.Capacity = requiredCapacity;
}
}
else
{
InnerNodes = new List<GraphNode<TItem>>(additionalSpace);
nkolev92 marked this conversation as resolved.
Show resolved Hide resolved
}
}

public override string ToString()
Expand Down
115 changes: 105 additions & 10 deletions src/NuGet.Core/NuGet.DependencyResolver.Core/GraphModel/Tracker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

Expand Down Expand Up @@ -44,7 +45,7 @@ public bool IsBestVersion(GraphItem<TItem> item)
{
var version = item.Key.Version;

foreach (var known in entry.Items.NoAllocEnumerate())
foreach (var known in entry)
{
if (version < known.Key.Version)
{
Expand All @@ -58,7 +59,13 @@ public bool IsBestVersion(GraphItem<TItem> item)

public IEnumerable<GraphItem<TItem>> GetDisputes(GraphItem<TItem> item)
{
return TryGetEntry(item)?.Items ?? Enumerable.Empty<GraphItem<TItem>>();
var entry = TryGetEntry(item);
if (entry is null)
{
return Enumerable.Empty<GraphItem<TItem>>();
}

return entry;
}

internal void Clear()
Expand All @@ -83,7 +90,7 @@ private Entry GetOrAddEntry(GraphItem<TItem> item)
return entry;
}

private sealed class Entry
private sealed class Entry : IEnumerable<GraphItem<TItem>>
{
/// <summary>
/// This field can have one of three values:
Expand Down Expand Up @@ -123,17 +130,105 @@ public void AddItem(GraphItem<TItem> item)
}
}

public Enumerator GetEnumerator()
{
return new Enumerator(this);
}

IEnumerator<GraphItem<TItem>> IEnumerable<GraphItem<TItem>>.GetEnumerator()
{
return new Enumerator(this);
}

IEnumerator IEnumerable.GetEnumerator()
{
return new Enumerator(this);
}

public bool HasMultipleItems => _storage is HashSet<GraphItem<TItem>>;

public IEnumerable<GraphItem<TItem>> Items
public struct Enumerator : IEnumerator<GraphItem<TItem>>, IDisposable, IEnumerator
nkolev92 marked this conversation as resolved.
Show resolved Hide resolved
{
get
private enum Type : byte
{
Empty,
SingleItem,
MultipleItems,
}

private readonly Type _type;
private readonly Entry _entry;
private GraphItem<TItem> _current;
private bool _done;
private HashSet<GraphItem<TItem>>.Enumerator _setEnumerator;

public Enumerator(Entry entry)
{
_entry = entry;
_current = default!;
_done = false;

if (_entry._storage is null)
{
_type = Type.Empty;
}
else if (_entry._storage is GraphItem<TItem>)
{
_type = Type.SingleItem;
}
else
{
_type = Type.MultipleItems;
_setEnumerator = ((HashSet<GraphItem<TItem>>)_entry._storage).GetEnumerator();
}
}

public readonly GraphItem<TItem> Current => _current;

readonly object IEnumerator.Current => Current;

public bool MoveNext()
{
if (_done || _type == Type.Empty)
{
return false;
}
else if (_type == Type.SingleItem)
{
_done = true;
_current = (GraphItem<TItem>)_entry._storage!;

return true;
}
else
{
bool result = _setEnumerator.MoveNext();
_current = _setEnumerator.Current;

return result;
}
}

public void Dispose()
{
if (_storage is null)
return Enumerable.Empty<GraphItem<TItem>>();
if (_storage is GraphItem<TItem> item)
return new[] { item };
return (HashSet<GraphItem<TItem>>)_storage;
if (_type == Type.MultipleItems)
{
_setEnumerator.Dispose();
}
}

void IEnumerator.Reset()
{
if (_type == Type.SingleItem)
{
_done = false;
}
else
{
((IEnumerator)_setEnumerator).Reset();
}

_current = default!;
}
}
}
Expand Down
Loading