Clean up discarding implicit references from ProjectRootElementCache (#8576)

Simplify and correct logic when discarding implicit references from the ProjectRootElementCache
This commit is contained in:
Forgind 2023-05-04 11:16:46 -07:00 коммит произвёл GitHub
Родитель b313662f92
Коммит 57c2833dbf
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
2 изменённых файлов: 33 добавлений и 13 удалений

Просмотреть файл

@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using Microsoft.Build.Shared;
@ -15,7 +16,7 @@ namespace Microsoft.Build.Collections
/// </summary>
/// <typeparam name="K">Type of key</typeparam>
/// <typeparam name="V">Type of value, without the WeakReference wrapper.</typeparam>
internal class WeakValueDictionary<K, V>
internal class WeakValueDictionary<K, V> : IEnumerable<KeyValuePair<K, V>>
where V : class
{
/// <summary>
@ -233,5 +234,22 @@ namespace Microsoft.Build.Collections
{
_dictionary.Clear();
}
public IEnumerator<KeyValuePair<K, V>> GetEnumerator()
{
foreach (KeyValuePair<K, WeakReference<V>> kvp in _dictionary)
{
if (kvp.Value is null)
{
yield return new KeyValuePair<K, V>(kvp.Key, null);
}
else if (kvp.Value.TryGetTarget(out V target))
{
yield return new KeyValuePair<K, V>(kvp.Key, target);
}
}
}
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}
}

Просмотреть файл

@ -522,25 +522,27 @@ namespace Microsoft.Build.Evaluation
LinkedList<ProjectRootElement> oldStrongCache = _strongCache;
_strongCache = new LinkedList<ProjectRootElement>();
foreach (string projectPath in oldWeakCache.Keys)
foreach (KeyValuePair<string, ProjectRootElement> kvp in oldWeakCache)
{
ProjectRootElement rootElement;
if (oldWeakCache.TryGetValue(projectPath, out rootElement))
if (kvp.Value is null)
{
if (rootElement.IsExplicitlyLoaded)
{
_weakCache[projectPath] = rootElement;
}
continue;
}
if (rootElement.IsExplicitlyLoaded && oldStrongCache.Contains(rootElement))
if (kvp.Value.IsExplicitlyLoaded)
{
_weakCache[kvp.Key] = kvp.Value;
}
if (oldStrongCache.Contains(kvp.Value))
{
if (kvp.Value.IsExplicitlyLoaded)
{
_strongCache.AddFirst(rootElement);
_strongCache.AddFirst(kvp.Value);
}
else
{
_strongCache.Remove(rootElement);
RaiseProjectRootElementRemovedFromStrongCache(rootElement);
RaiseProjectRootElementRemovedFromStrongCache(kvp.Value);
}
}
}