namespace Invercargill.DataStructures { public class SortedSeries : Enumerable, Lot, ReadOnlyCollection, Collection { [Compact] private class SeriesNode { public bool is_red; public SeriesNodeItem* first_value; public SeriesNodeItem* last_value; public SeriesNode* left_child; public SeriesNode* right_child; public SeriesNode* parent; public SeriesNode(owned T value, SeriesNode* nil) { is_red = true; left_child = nil; right_child = nil; first_value = new SeriesNodeItem((owned)value); last_value = first_value; } public SeriesNode.nil() { is_red = false; left_child = this; right_child = this; } public unowned T sample() { return first_value->item; } public void add_value(owned T value) { SeriesNodeItem* new_value = new SeriesNodeItem((owned)value); last_value->next = new_value; last_value = new_value; } // public void remove_all_values_where (PredicateDelegate predicate) { // values = values.where(v => !predicate(v)).to_buffer(); // } } [Compact] private class SeriesNodeItem { public T item; public SeriesNodeItem* next; public SeriesNodeItem(owned T item) { this.item = (owned)item; } } private SeriesNode* root; private SeriesNode* nil; private RWLock rw_lock; private CompareDelegate comparitor; private int n_items; public override uint length { get { return n_items; }} public SortedSeries(owned CompareDelegate? comparitor = null) { nil = new SeriesNode.nil(); root = nil; rw_lock = RWLock(); n_items = 0; this.comparitor = (owned)comparitor ?? Operators.comparison(); } public override Tracker get_tracker () { if(root == nil) { return empty().get_tracker(); } return new TreeTracker(this); } public override int? peek_count () { return n_items; } public override EnumerableInfo get_info () { return new EnumerableInfo.infer_ultimate (this, EnumerableCategory.IN_MEMORY); } public void add (T item) { // Get lock and update count of items // rw_lock.writer_lock(); n_items++; SeriesNode* parent = null; SeriesNode* current = root; int cmp = 0; while(current != nil) { parent = current; cmp = comparitor(item, current->sample()); if(cmp == 0) { // Add to node, has no effect on tree current->add_value(item); // rw_lock.writer_unlock(); return; } if(cmp < 0) { current = current->left_child; } else { current = current->right_child; } } SeriesNode* new_node = new SeriesNode (item, nil); new_node->parent = parent; if(parent == null) { root = new_node; } else { if(cmp == 0) { print("Does this actually happen?\n"); assert_not_reached (); } else if(cmp < 0) { parent->left_child = new_node; } else { parent->right_child = new_node; } } if(new_node->parent == null) { new_node->is_red = false; } else if(new_node->parent->parent != null) { fix_insert(new_node); } // rw_lock.writer_unlock(); } private void fix_insert(SeriesNode* new_node) { SeriesNode* node = new_node; while(node != root && node->parent->is_red) { if(node->parent == node->parent->parent->left_child) { var uncle = node->parent->parent->right_child; if(uncle->is_red) { node->parent->is_red = false; uncle->is_red = false; node->parent->parent->is_red = true; node = node->parent->parent; continue; } if(node == node->parent->right_child) { node = node->parent; rotate_left(node); } node->parent->is_red = false; node->parent->parent->is_red = true; rotate_right (node->parent->parent); } else { var uncle = node->parent->parent->left_child; if(uncle->is_red) { node->parent->is_red = false; uncle->is_red = false; node->parent->parent->is_red = true; node = node->parent->parent; continue; } if(node == node->parent->left_child) { node = node->parent; rotate_right(node); } node->parent->is_red = false; node->parent->parent->is_red = true; rotate_left(node->parent->parent); } } root->is_red = false; } public void remove_first_where (PredicateDelegate predicate) { assert_not_reached (); } public void remove_all_where (PredicateDelegate predicate) { assert_not_reached (); } public void clear () { assert_not_reached (); } private void rotate_left(SeriesNode* x) { SeriesNode* y = x->right_child; x->right_child = y->left_child; if(y->left_child != nil) y->left_child->parent = x; y->parent = x->parent; if(x->parent == null) root = y; else if(x->parent->left_child == x) x->parent->left_child = y; else x->parent->right_child = y; y->left_child = x; x->parent = y; } private void rotate_right(SeriesNode* x) { SeriesNode* y = x->left_child; x->left_child = y->right_child; if(y->right_child != nil) y->right_child->parent = x; y->parent = x->parent; if(x->parent == null) root = y; else if(x->parent->right_child == x) x->parent->right_child = y; else x->parent->left_child = y; y->right_child = x; x->parent = y; } private class TreeTracker : Tracker { SeriesNode* node; SeriesNode* next_node; SortedSeries series; SeriesNodeItem* values; public TreeTracker(SortedSeries series) { this.series = series; node = series.root; while(node->left_child != series.nil) { node = node->left_child; } values = node->first_value; find_next_node(); } public override bool has_next () { return values != null || next_node != null; } public override T get_next () { if(values != null) { var item = values->item; values = values->next; return item; } node = next_node; var item = node->first_value->item; values = node->first_value->next; find_next_node(); return item; } private void find_next_node() { next_node = null; if (node == null) return; // standard inorder successor: if (node->right_child != series.nil) { SeriesNode* n = node->right_child; while (n->left_child != series.nil) n = n->left_child; next_node = n; return; } SeriesNode* n = node; SeriesNode* p = n->parent; while (p != null && n == p->right_child) { n = p; p = p->parent; } next_node = p; // could be null (end) } } } }