MultiMap.cs 2.6 KB

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