SortedSeries.vala 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. namespace Invercargill.DataStructures {
  2. public class SortedSeries<T> : Enumerable<T>, Lot<T>, ReadOnlyCollection<T>, Collection<T> {
  3. private class SeriesNode<T> {
  4. public bool is_red;
  5. public Series<T> values;
  6. public SeriesNode<T>? left_child;
  7. public SeriesNode<T>? right_child;
  8. public SeriesNode<T>? parent;
  9. public SeriesNode(T item) {
  10. is_red = true;
  11. values = new Series<T>();
  12. values.add(item);
  13. }
  14. public T sample() {
  15. return values.first_or_default();
  16. }
  17. public void add_value(T value) {
  18. values.add(value);
  19. }
  20. // public void remove_all_values_where (PredicateDelegate<T> predicate) {
  21. // values = values.where(v => !predicate(v)).to_buffer();
  22. // }
  23. }
  24. private SeriesNode<T> root;
  25. private RWLock rw_lock;
  26. private CompareDelegate<T> comparitor;
  27. private int n_items;
  28. public SortedSeries(owned CompareDelegate<T>? comparitor = null) {
  29. rw_lock = RWLock();
  30. n_items = 0;
  31. this.comparitor = (owned)comparitor ?? Operators.comparison<T>();
  32. }
  33. public override Tracker<T> get_tracker () {
  34. if(root == null) {
  35. return empty<T>().get_tracker();
  36. }
  37. return new TreeTracker<T>(root);
  38. }
  39. public override int? peek_count () {
  40. return n_items;
  41. }
  42. public override EnumerableInfo get_info () {
  43. return new EnumerableInfo.infer_ultimate (this, EnumerableCategory.IN_MEMORY);
  44. }
  45. public void add (T item) {
  46. // Get lock and update count of items
  47. print("Get lock and update count of items\n");
  48. rw_lock.writer_lock();
  49. n_items++;
  50. // Set root if it doesn't exist
  51. print("Set root if it doesn't exist\n");
  52. if(root == null) {
  53. root = new SeriesNode<T>(item);
  54. root.is_red = false;
  55. rw_lock.writer_unlock();
  56. return;
  57. }
  58. // Find leaf node
  59. print("Find leaf node\n");
  60. var node = root;
  61. int cmp;
  62. while(true) {
  63. cmp = comparitor(item, node.sample());
  64. print(@"CMP=$cmp; item=$((int)item); sample=$((int)node.sample());\n");
  65. if(cmp == 0) {
  66. // No change to tree, simply add the value to this node
  67. print("No change to tree, simply add the value to this node\n");
  68. node.add_value (item);
  69. rw_lock.writer_unlock();
  70. return;
  71. }
  72. if(cmp > 0) {
  73. if(node.right_child == null)
  74. break;
  75. node = node.right_child;
  76. }
  77. if(cmp < 0) {
  78. if(node.left_child == null)
  79. break;
  80. node = node.left_child;
  81. }
  82. }
  83. // Make new node, replacing the leaf
  84. print("Make new node, replacing the leaf\n");
  85. var new_node = new SeriesNode<T>(item);
  86. new_node.parent = node;
  87. if(node == null) {
  88. root = new_node;
  89. new_node.is_red = true;
  90. }
  91. else if(cmp > 0) {
  92. node.right_child = new_node;
  93. }
  94. else {
  95. node.left_child = new_node;
  96. }
  97. // Balance the tree
  98. print("Balance the tree\n");
  99. if(new_node.parent?.parent != null) {
  100. fix_insert (new_node);
  101. }
  102. rw_lock.writer_unlock();
  103. }
  104. private void fix_insert(SeriesNode<T> new_node) {
  105. var node = new_node;
  106. while(node != root && node.parent.is_red) {
  107. if(node.parent == node.parent.parent.left_child) {
  108. var uncle = node.parent.parent.right_child;
  109. if(uncle != null && uncle.is_red) {
  110. node.parent.is_red = false;
  111. uncle.is_red = false;
  112. uncle.parent.is_red = true;
  113. node = node.parent.parent;
  114. continue;
  115. }
  116. if(node == node.parent.right_child) {
  117. node = node.parent;
  118. rotate_left(node);
  119. }
  120. node.parent.is_red = false;
  121. node.parent.parent.is_red = true;
  122. rotate_right (node.parent.parent);
  123. }
  124. else {
  125. var uncle = node.parent.parent.left_child;
  126. if(uncle != null && uncle.is_red) {
  127. node.parent.is_red = false;
  128. uncle.is_red = false;
  129. uncle.parent.is_red = true;
  130. node = node.parent.parent;
  131. continue;
  132. }
  133. if(node == node.parent.left_child) {
  134. node = node.parent;
  135. rotate_right(node);
  136. }
  137. node.parent.is_red = false;
  138. node.parent.parent.is_red = true;
  139. rotate_left(node.parent.parent);
  140. }
  141. }
  142. root.is_red = false;
  143. }
  144. public void remove_first_where (PredicateDelegate<T> predicate) {
  145. assert_not_reached ();
  146. }
  147. public void remove_all_where (PredicateDelegate<T> predicate) {
  148. assert_not_reached ();
  149. }
  150. public void clear () {
  151. assert_not_reached ();
  152. }
  153. private void rotate_left(SeriesNode<T> x) {
  154. var y = x.right_child;
  155. x.right_child = y.left_child;
  156. if(y.left_child != null)
  157. y.left_child.parent = x;
  158. y.parent = x.parent;
  159. if(x.parent == null)
  160. root = y;
  161. else if(x.parent.left_child == x)
  162. x.parent.left_child = y;
  163. else
  164. x.parent.right_child = y;
  165. y.left_child = x;
  166. x.parent = y;
  167. }
  168. private void rotate_right(SeriesNode<T> x) {
  169. var y = x.left_child;
  170. x.left_child = y.right_child;
  171. if(y.right_child != null)
  172. y.right_child.parent = x;
  173. y.parent = x.parent;
  174. if(x.parent == null)
  175. root = y;
  176. else if(x.parent.right_child == x)
  177. x.parent.right_child = y;
  178. else
  179. x.parent.left_child = y;
  180. y.right_child = x;
  181. x.parent = y;
  182. }
  183. private class TreeTracker<T> : Tracker<T> {
  184. SeriesNode<T> node;
  185. SeriesNode<T>? next_node;
  186. Tracker<T> values;
  187. public TreeTracker(SeriesNode<T> root) {
  188. print("New tracker!\n");
  189. node = root;
  190. while(node.left_child != null) {
  191. node = node.left_child;
  192. }
  193. values = node.values.get_tracker();
  194. find_next_node();
  195. }
  196. public override bool has_next () {
  197. return values.has_next() || next_node != null;
  198. }
  199. public override T get_next () {
  200. if(values.has_next()) {
  201. return values.get_next();
  202. }
  203. node = next_node;
  204. values = node.values.get_tracker();
  205. var result = values.get_next();
  206. find_next_node();
  207. return result;
  208. }
  209. private void find_next_node() {
  210. next_node = null;
  211. if(node.right_child != null) {
  212. next_node = node.right_child;
  213. while(next_node.left_child != null) {
  214. next_node = next_node.left_child;
  215. }
  216. }
  217. else if(node.parent == null) {
  218. next_node = null;
  219. }
  220. else if(node.parent.left_child == node) {
  221. next_node = node.parent;
  222. }
  223. else if(node.parent.parent.right_child == node.parent) {
  224. next_node = null;
  225. }
  226. else {
  227. next_node = node.parent.parent;
  228. }
  229. }
  230. }
  231. }
  232. }