MultiMapSet.cs 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. using System.Collections.Generic;
  2. using System.Linq;
  3. namespace ET
  4. {
  5. public class MultiMapSet<T, K>
  6. {
  7. private readonly SortedDictionary<T, HashSet<K>> dictionary = new SortedDictionary<T, HashSet<K>>();
  8. // 重用list
  9. private static readonly Queue<HashSet<K>> queue = new Queue<HashSet<K>>();
  10. private static HashSet<K> Empty = new HashSet<K>();
  11. public SortedDictionary<T, HashSet<K>> GetDictionary()
  12. {
  13. return this.dictionary;
  14. }
  15. public void Add(T t, K k)
  16. {
  17. HashSet<K> list;
  18. this.dictionary.TryGetValue(t, out list);
  19. if (list == null)
  20. {
  21. list = this.FetchList();
  22. this.dictionary[t] = list;
  23. }
  24. list.Add(k);
  25. }
  26. public KeyValuePair<T, HashSet<K>> First()
  27. {
  28. return this.dictionary.First();
  29. }
  30. public T FirstKey()
  31. {
  32. return this.dictionary.Keys.First();
  33. }
  34. public int Count
  35. {
  36. get
  37. {
  38. return this.dictionary.Count;
  39. }
  40. }
  41. private HashSet<K> FetchList()
  42. {
  43. if (queue.Count > 0)
  44. {
  45. HashSet<K> list = queue.Dequeue();
  46. list.Clear();
  47. return list;
  48. }
  49. return new HashSet<K>();
  50. }
  51. private void RecycleList(HashSet<K> list)
  52. {
  53. list.Clear();
  54. queue.Enqueue(list);
  55. }
  56. public bool Remove(T t, K k)
  57. {
  58. HashSet<K> list;
  59. this.dictionary.TryGetValue(t, out list);
  60. if (list == null)
  61. {
  62. return false;
  63. }
  64. if (!list.Remove(k))
  65. {
  66. return false;
  67. }
  68. if (list.Count == 0)
  69. {
  70. this.RecycleList(list);
  71. this.dictionary.Remove(t);
  72. }
  73. return true;
  74. }
  75. public bool Remove(T t)
  76. {
  77. HashSet<K> list = null;
  78. this.dictionary.TryGetValue(t, out list);
  79. if (list != null)
  80. {
  81. this.RecycleList(list);
  82. }
  83. return this.dictionary.Remove(t);
  84. }
  85. /// <summary>
  86. /// 不返回内部的list,copy一份出来
  87. /// </summary>
  88. /// <param name="t"></param>
  89. /// <returns></returns>
  90. public K[] GetAll(T t)
  91. {
  92. HashSet<K> list;
  93. this.dictionary.TryGetValue(t, out list);
  94. if (list == null)
  95. {
  96. return new K[0];
  97. }
  98. return list.ToArray();
  99. }
  100. /// <summary>
  101. /// 返回内部的list
  102. /// </summary>
  103. /// <param name="t"></param>
  104. /// <returns></returns>
  105. public HashSet<K> this[T t]
  106. {
  107. get
  108. {
  109. this.dictionary.TryGetValue(t, out var list);
  110. return list ?? Empty;
  111. }
  112. }
  113. public K GetOne(T t)
  114. {
  115. HashSet<K> list;
  116. this.dictionary.TryGetValue(t, out list);
  117. if (list != null && list.Count > 0)
  118. {
  119. return list.FirstOrDefault();
  120. }
  121. return default(K);
  122. }
  123. public bool Contains(T t, K k)
  124. {
  125. HashSet<K> list;
  126. this.dictionary.TryGetValue(t, out list);
  127. if (list == null)
  128. {
  129. return false;
  130. }
  131. return list.Contains(k);
  132. }
  133. public bool ContainsKey(T t)
  134. {
  135. return this.dictionary.ContainsKey(t);
  136. }
  137. public void Clear()
  138. {
  139. foreach (HashSet<K> list in this.dictionary.Values)
  140. {
  141. list.Clear();
  142. queue.Enqueue(list);
  143. }
  144. dictionary.Clear();
  145. }
  146. }
  147. }