UnityIncomingChangesTree.cs 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. using System.Collections.Generic;
  2. using PlasticGui.WorkspaceWindow.Merge;
  3. namespace Unity.PlasticSCM.Editor.Views.IncomingChanges.Developer
  4. {
  5. internal class UnityIncomingChangesTree
  6. {
  7. internal static UnityIncomingChangesTree BuildIncomingChangeCategories(
  8. MergeChangesTree tree)
  9. {
  10. return new UnityIncomingChangesTree(tree);
  11. }
  12. UnityIncomingChangesTree(
  13. MergeChangesTree tree)
  14. {
  15. mInnerTree = tree;
  16. mMetaCache.Build(mInnerTree.GetNodes());
  17. }
  18. internal List<MergeChangesCategory> GetNodes()
  19. {
  20. return mInnerTree.GetNodes();
  21. }
  22. internal bool HasMeta(MergeChangeInfo changeInfo)
  23. {
  24. return mMetaCache.ContainsMeta(changeInfo);
  25. }
  26. internal MergeChangeInfo GetMetaChange(MergeChangeInfo change)
  27. {
  28. return mMetaCache.GetExistingMeta(change);
  29. }
  30. internal void FillWithMeta(List<MergeChangeInfo> changes)
  31. {
  32. changes.AddRange(
  33. mMetaCache.GetExistingMeta(changes));
  34. }
  35. internal void Sort(string key, bool isAscending)
  36. {
  37. mInnerTree.Sort(key, isAscending);
  38. }
  39. internal void ResolveUserNames(
  40. MergeChangesTree.ResolveUserName resolveUserName)
  41. {
  42. mInnerTree.ResolveUserNames(resolveUserName);
  43. }
  44. MetaCache mMetaCache = new MetaCache();
  45. MergeChangesTree mInnerTree;
  46. class MetaCache
  47. {
  48. internal bool ContainsMeta(MergeChangeInfo changeInfo)
  49. {
  50. string key = BuildKey.ForMetaChange(changeInfo);
  51. return mCache.ContainsKey(key);
  52. }
  53. internal MergeChangeInfo GetExistingMeta(MergeChangeInfo change)
  54. {
  55. MergeChangeInfo result;
  56. if (!mCache.TryGetValue(BuildKey.ForMetaChange(change), out result))
  57. return null;
  58. return result;
  59. }
  60. internal List<MergeChangeInfo> GetExistingMeta(
  61. List<MergeChangeInfo> changes)
  62. {
  63. List<MergeChangeInfo> result = new List<MergeChangeInfo>();
  64. foreach (MergeChangeInfo change in changes)
  65. {
  66. string key = BuildKey.ForMetaChange(change);
  67. MergeChangeInfo metaChange;
  68. if (!mCache.TryGetValue(key, out metaChange))
  69. continue;
  70. result.Add(metaChange);
  71. }
  72. return result;
  73. }
  74. internal void Build(List<MergeChangesCategory> incomingChangesCategories)
  75. {
  76. mCache.Clear();
  77. foreach (MergeChangesCategory category in incomingChangesCategories)
  78. {
  79. ExtractMetaToCache(category, mCache);
  80. }
  81. }
  82. static void ExtractMetaToCache(
  83. MergeChangesCategory category,
  84. Dictionary<string, MergeChangeInfo> cache)
  85. {
  86. List<MergeChangeInfo> changes = category.GetChanges();
  87. HashSet<string> indexedKeys = BuildIndexedKeys(
  88. changes);
  89. for (int i = changes.Count - 1; i >= 0; i--)
  90. {
  91. MergeChangeInfo currentChange = changes[i];
  92. string path = currentChange.GetPath();
  93. if (!MetaPath.IsMetaPath(path))
  94. continue;
  95. string realPath = MetaPath.GetPathFromMetaPath(path);
  96. if (!indexedKeys.Contains(BuildKey.BuildCacheKey(
  97. currentChange.CategoryType, realPath)))
  98. continue;
  99. // found foo.c and foo.c.meta - move .meta to cache
  100. cache.Add(BuildKey.ForChange(currentChange), currentChange);
  101. changes.RemoveAt(i);
  102. }
  103. }
  104. static HashSet<string> BuildIndexedKeys(
  105. List<MergeChangeInfo> changes)
  106. {
  107. HashSet<string> result = new HashSet<string>();
  108. foreach (MergeChangeInfo change in changes)
  109. {
  110. if (MetaPath.IsMetaPath(change.GetPath()))
  111. continue;
  112. result.Add(BuildKey.ForChange(change));
  113. }
  114. return result;
  115. }
  116. Dictionary<string, MergeChangeInfo> mCache =
  117. new Dictionary<string, MergeChangeInfo>();
  118. static class BuildKey
  119. {
  120. internal static string ForChange(
  121. MergeChangeInfo change)
  122. {
  123. return BuildCacheKey(
  124. change.CategoryType,
  125. change.GetPath());
  126. }
  127. internal static string ForMetaChange(
  128. MergeChangeInfo change)
  129. {
  130. return BuildCacheKey(
  131. change.CategoryType,
  132. MetaPath.GetMetaPath(change.GetPath()));
  133. }
  134. internal static string BuildCacheKey(
  135. MergeChangesCategory.Type type,
  136. string path)
  137. {
  138. return string.Concat(type, ":", path);
  139. }
  140. }
  141. }
  142. }
  143. }