Advertisement
Guest User

Untitled

a guest
Mar 20th, 2017
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.50 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3.  
  4. namespace PortsManager
  5. {
  6. class PortsManager
  7. {
  8. int count = 0;
  9.  
  10. readonly (int minPort, int maxPort) range;
  11.  
  12. LinkedList<(int minPort, int maxPort)> ranges = new LinkedList<(int, int)>();
  13.  
  14. internal PortsManager(int minPort, int maxPort)
  15. {
  16. count = maxPort - minPort + 1;
  17. range = (minPort, maxPort);
  18. ranges.AddLast(range);
  19. }
  20.  
  21. internal int Count { get => count; }
  22.  
  23. internal bool IsPortAvailable(int port)
  24. {
  25. if (port < range.minPort || port > range.maxPort)
  26. {
  27. return false;
  28. }
  29.  
  30. for (var node = ranges.First; node != null; node = node.Next)
  31. {
  32. var range = node.Value;
  33. if (port >= range.minPort && port <= range.maxPort)
  34. {
  35. return true;
  36. }
  37. }
  38. return false;
  39. }
  40.  
  41. internal int? GetPort()
  42. {
  43. if (ranges.Count > 0)
  44. {
  45. var range = ranges.First.Value;
  46. int port = range.minPort++;
  47. ranges.RemoveFirst();
  48. if (range.minPort <= range.maxPort)
  49. {
  50. ranges.AddFirst(range);
  51. }
  52. --count;
  53. return port;
  54. }
  55. return null;
  56. }
  57.  
  58. internal void ReturnPort(int port)
  59. {
  60. if (port < range.minPort || port > range.maxPort)
  61. {
  62. return;
  63. }
  64.  
  65. ++count;
  66. for (var node = ranges.First; node != null; node = node.Next)
  67. {
  68. var range = node.Value;
  69. if (port < range.minPort)
  70. {
  71. if (port == range.minPort - 1)
  72. {
  73. if (node.Previous != null && port == node.Previous.Value.maxPort + 1)
  74. {
  75. // the port bridges the gap between two adjacent ranges, merge them
  76. range.minPort = node.Previous.Value.minPort;
  77. ranges.Remove(node.Previous);
  78. }
  79. else
  80. {
  81. // just merge the port into the current range
  82. --range.minPort;
  83. }
  84. var next = node.Next;
  85. ranges.Remove(node);
  86. node = next != null ? ranges.AddBefore(next, range) : ranges.AddLast(range);
  87. return;
  88. }
  89. if (node.Previous != null)
  90. {
  91. if (port == node.Previous.Value.maxPort + 1)
  92. {
  93. // merge with the previous node, and done
  94. range.minPort = node.Previous.Value.minPort;
  95. range.maxPort = node.Previous.Value.maxPort + 1;
  96. ranges.Remove(node.Previous);
  97. ranges.AddBefore(node, range);
  98. return;
  99. }
  100. }
  101. // add a new range
  102. ranges.AddBefore(node, (port, port));
  103. return;
  104. }
  105. else if (port <= range.maxPort)
  106. {
  107. --count; // NB: this is the only scenario where 'count' shouldn't be incremented
  108. return;
  109. }
  110. else if (node.Next == null)
  111. {
  112. if (port == range.maxPort + 1)
  113. {
  114. ++range.maxPort;
  115. ranges.RemoveLast();
  116. ranges.AddLast(range);
  117. return;
  118. }
  119. }
  120. }
  121.  
  122. // if control comes here, the port forms the last range
  123. ranges.AddLast((port, port));
  124. }
  125.  
  126. internal void VerifyIntegrity()
  127. {
  128. int count = 0;
  129. for (var node = ranges.First; node != null; node = node.Next)
  130. {
  131. var range = node.Value;
  132. System.Diagnostics.Debug.Assert(range.minPort <= range.maxPort);
  133. count += range.maxPort - range.minPort + 1;
  134.  
  135. if (node.Previous != null)
  136. {
  137. System.Diagnostics.Debug.Assert(node.Previous.Value.maxPort < range.minPort - 1);
  138. }
  139. }
  140. System.Diagnostics.Debug.Assert(count == this.count);
  141. }
  142. }
  143.  
  144. class Program
  145. {
  146. static void Main(string[] args)
  147. {
  148. PortsManager pm = new PortsManager(1, 100);
  149.  
  150. Random rnd = new Random();
  151. for (var c = 0; c < 100; ++c)
  152. {
  153. for (var i = 0; i < 50; ++i)
  154. {
  155. var port = pm.GetPort();
  156. Console.WriteLine($"GetPort: {port}");
  157. }
  158. pm.VerifyIntegrity();
  159. Console.WriteLine($"Count: {pm.Count}");
  160. for (var i = 0; i < 100; ++i)
  161. {
  162. var port = rnd.Next(1, 100);
  163. Console.WriteLine($"ReturnPort: {port}");
  164. pm.ReturnPort(port);
  165. }
  166. pm.VerifyIntegrity();
  167. Console.WriteLine($"Count: {pm.Count}");
  168. }
  169. }
  170. }
  171. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement