MultiMap.cs 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. using System.Collections.Generic;
  2. using System.Linq;
  3. namespace Model
  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. public SortedDictionary<T, List<K>> GetDictionary()
  11. {
  12. return this.dictionary;
  13. }
  14. public void Add(T t, K k)
  15. {
  16. List<K> list;
  17. this.dictionary.TryGetValue(t, out list);
  18. if (list == null)
  19. {
  20. list = this.FetchList();
  21. }
  22. list.Add(k);
  23. this.dictionary[t] = list;
  24. }
  25. public KeyValuePair<T, List<K>> First()
  26. {
  27. return this.dictionary.First();
  28. }
  29. public int Count
  30. {
  31. get
  32. {
  33. return this.dictionary.Count;
  34. }
  35. }
  36. private List<K> FetchList()
  37. {
  38. if (this.queue.Count > 0)
  39. {
  40. List<K> list = this.queue.Dequeue();
  41. list.Clear();
  42. return list;
  43. }
  44. return new List<K>();
  45. }
  46. private void RecycleList(List<K> list)
  47. {
  48. // 防止暴涨
  49. if (this.queue.Count > 100)
  50. {
  51. return;
  52. }
  53. list.Clear();
  54. this.queue.Enqueue(list);
  55. }
  56. public bool Remove(T t, K k)
  57. {
  58. List<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. List<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. List<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 List<K> this[T t]
  106. {
  107. get
  108. {
  109. List<K> list;
  110. this.dictionary.TryGetValue(t, out list);
  111. return list;
  112. }
  113. }
  114. public K GetOne(T t)
  115. {
  116. List<K> list;
  117. this.dictionary.TryGetValue(t, out list);
  118. if (list != null && list.Count > 0)
  119. {
  120. return list[0];
  121. }
  122. return default(K);
  123. }
  124. public bool Contains(T t, K k)
  125. {
  126. List<K> list;
  127. this.dictionary.TryGetValue(t, out list);
  128. if (list == null)
  129. {
  130. return false;
  131. }
  132. return list.Contains(k);
  133. }
  134. public bool ContainsKey(T t)
  135. {
  136. return this.dictionary.ContainsKey(t);
  137. }
  138. }
  139. }