Net-Game/Library/PackageCache/com.unity.collab-proxy@50ac96531b63/Editor/Views/Merge/Developer/UnityMergeTree.cs
2025-03-28 08:33:16 -04:00

189 lines
5.5 KiB
C#

using System.Collections.Generic;
using PlasticGui;
using PlasticGui.WorkspaceWindow.Merge;
namespace Unity.PlasticSCM.Editor.Views.Merge.Developer
{
internal class UnityMergeTree
{
internal static UnityMergeTree BuildMergeCategories(
MergeChangesTree tree)
{
return new UnityMergeTree(tree);
}
UnityMergeTree(
MergeChangesTree tree)
{
mInnerTree = tree;
mMetaCache.Build(mInnerTree.GetNodes());
}
internal List<MergeChangesCategory> GetNodes()
{
return mInnerTree.GetNodes();
}
internal bool HasMeta(MergeChangeInfo changeInfo)
{
return mMetaCache.ContainsMeta(changeInfo);
}
internal MergeChangeInfo GetMetaChange(MergeChangeInfo change)
{
return mMetaCache.GetExistingMeta(change);
}
internal void FillWithMeta(List<MergeChangeInfo> changes)
{
changes.AddRange(
mMetaCache.GetExistingMeta(changes));
}
internal void Filter(Filter filter, List<string> columnNames)
{
mInnerTree.Filter(filter, columnNames);
}
internal void Sort(string key, bool isAscending)
{
mInnerTree.Sort(key, isAscending);
}
internal void ResolveUserNames(
MergeChangesTree.ResolveUserName resolveUserName)
{
mInnerTree.ResolveUserNames(resolveUserName);
}
MetaCache mMetaCache = new MetaCache();
MergeChangesTree mInnerTree;
class MetaCache
{
internal bool ContainsMeta(MergeChangeInfo changeInfo)
{
string key = BuildKey.ForMetaChange(changeInfo);
return mCache.ContainsKey(key);
}
internal MergeChangeInfo GetExistingMeta(MergeChangeInfo change)
{
MergeChangeInfo result;
if (!mCache.TryGetValue(BuildKey.ForMetaChange(change), out result))
return null;
return result;
}
internal List<MergeChangeInfo> GetExistingMeta(
List<MergeChangeInfo> changes)
{
List<MergeChangeInfo> result = new List<MergeChangeInfo>();
foreach (MergeChangeInfo change in changes)
{
string key = BuildKey.ForMetaChange(change);
MergeChangeInfo metaChange;
if (!mCache.TryGetValue(key, out metaChange))
continue;
result.Add(metaChange);
}
return result;
}
internal void Build(List<MergeChangesCategory> mergeChangesCategories)
{
mCache.Clear();
foreach (MergeChangesCategory category in mergeChangesCategories)
{
ExtractMetaToCache(category, mCache);
}
}
static void ExtractMetaToCache(
MergeChangesCategory category,
Dictionary<string, MergeChangeInfo> cache)
{
List<MergeChangeInfo> changes = category.GetChanges();
HashSet<string> indexedKeys = BuildIndexedKeys(
changes);
for (int i = changes.Count - 1; i >= 0; i--)
{
MergeChangeInfo currentChange = changes[i];
string path = currentChange.GetPath();
if (!MetaPath.IsMetaPath(path))
continue;
string realPath = MetaPath.GetPathFromMetaPath(path);
if (!indexedKeys.Contains(BuildKey.BuildCacheKey(
currentChange.CategoryType, realPath)))
continue;
// found foo.c and foo.c.meta - move .meta to cache
cache.Add(BuildKey.ForChange(currentChange), currentChange);
changes.RemoveAt(i);
}
}
static HashSet<string> BuildIndexedKeys(
List<MergeChangeInfo> changes)
{
HashSet<string> result = new HashSet<string>();
foreach (MergeChangeInfo change in changes)
{
if (MetaPath.IsMetaPath(change.GetPath()))
continue;
result.Add(BuildKey.ForChange(change));
}
return result;
}
Dictionary<string, MergeChangeInfo> mCache =
new Dictionary<string, MergeChangeInfo>();
static class BuildKey
{
internal static string ForChange(
MergeChangeInfo change)
{
return BuildCacheKey(
change.CategoryType,
change.GetPath());
}
internal static string ForMetaChange(
MergeChangeInfo change)
{
return BuildCacheKey(
change.CategoryType,
MetaPath.GetMetaPath(change.GetPath()));
}
internal static string BuildCacheKey(
MergeChangesCategory.Type type,
string path)
{
return string.Concat(type, ":", path);
}
}
}
}
}