UnityIncomingChangesTree.cs 5.3 KB

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