|
@@ -3,34 +3,37 @@ namespace Invercargill.DataStructures {
|
|
|
|
|
|
public class SortedSeries<T> : Enumerable<T>, Lot<T>, ReadOnlyCollection<T>, Collection<T> {
|
|
public class SortedSeries<T> : Enumerable<T>, Lot<T>, ReadOnlyCollection<T>, Collection<T> {
|
|
|
|
|
|
|
|
+ [Compact]
|
|
private class SeriesNode<T> {
|
|
private class SeriesNode<T> {
|
|
public bool is_red;
|
|
public bool is_red;
|
|
- public Series<T> values { get; private set; }
|
|
|
|
- public SeriesNode<T> left_child { get; set; }
|
|
|
|
- public SeriesNode<T> right_child { get; set; }
|
|
|
|
- public SeriesNode<T> parent { get; set; }
|
|
|
|
|
|
+ public SeriesNodeItem<T>* first_value;
|
|
|
|
+ public SeriesNodeItem<T>* last_value;
|
|
|
|
+ public SeriesNode<T>* left_child;
|
|
|
|
+ public SeriesNode<T>* right_child;
|
|
|
|
+ public SeriesNode<T>* parent;
|
|
|
|
|
|
- public SeriesNode(T item, SeriesNode<T> nil) {
|
|
|
|
|
|
+ public SeriesNode(owned T value, SeriesNode<T>* nil) {
|
|
is_red = true;
|
|
is_red = true;
|
|
left_child = nil;
|
|
left_child = nil;
|
|
right_child = nil;
|
|
right_child = nil;
|
|
- values = new Series<T>();
|
|
|
|
- values.add(item);
|
|
|
|
|
|
+ first_value = new SeriesNodeItem<T>((owned)value);
|
|
|
|
+ last_value = first_value;
|
|
}
|
|
}
|
|
|
|
|
|
public SeriesNode.nil() {
|
|
public SeriesNode.nil() {
|
|
is_red = false;
|
|
is_red = false;
|
|
left_child = this;
|
|
left_child = this;
|
|
right_child = this;
|
|
right_child = this;
|
|
- values = new Series<T>();
|
|
|
|
}
|
|
}
|
|
|
|
|
|
public T sample() {
|
|
public T sample() {
|
|
- return values.first_or_default();
|
|
|
|
|
|
+ return first_value->item;
|
|
}
|
|
}
|
|
|
|
|
|
- public void add_value(T value) {
|
|
|
|
- values.add(value);
|
|
|
|
|
|
+ public void add_value(owned T value) {
|
|
|
|
+ SeriesNodeItem<T>* new_value = new SeriesNodeItem<T>((owned)value);
|
|
|
|
+ last_value->next = new_value;
|
|
|
|
+ last_value = new_value;
|
|
}
|
|
}
|
|
|
|
|
|
// public void remove_all_values_where (PredicateDelegate<T> predicate) {
|
|
// public void remove_all_values_where (PredicateDelegate<T> predicate) {
|
|
@@ -38,17 +41,24 @@ namespace Invercargill.DataStructures {
|
|
// }
|
|
// }
|
|
}
|
|
}
|
|
|
|
|
|
- private SeriesNode<T> root;
|
|
|
|
- private SeriesNode<T> nil;
|
|
|
|
|
|
+ [Compact]
|
|
|
|
+ private class SeriesNodeItem<T> {
|
|
|
|
+ public T item;
|
|
|
|
+ public SeriesNodeItem<T>* next;
|
|
|
|
+
|
|
|
|
+ public SeriesNodeItem(owned T item) {
|
|
|
|
+ this.item = (owned)item;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private SeriesNode<T>* root;
|
|
|
|
+ private SeriesNode<T>* nil;
|
|
private RWLock rw_lock;
|
|
private RWLock rw_lock;
|
|
- private Series<SeriesNode<T>> node_refs;
|
|
|
|
private CompareDelegate<T> comparitor;
|
|
private CompareDelegate<T> comparitor;
|
|
private int n_items;
|
|
private int n_items;
|
|
|
|
|
|
public SortedSeries(owned CompareDelegate<T>? comparitor = null) {
|
|
public SortedSeries(owned CompareDelegate<T>? comparitor = null) {
|
|
nil = new SeriesNode<T>.nil();
|
|
nil = new SeriesNode<T>.nil();
|
|
- node_refs = new Series<SeriesNode<T>>();
|
|
|
|
- node_refs.add(nil);
|
|
|
|
root = nil;
|
|
root = nil;
|
|
rw_lock = RWLock();
|
|
rw_lock = RWLock();
|
|
n_items = 0;
|
|
n_items = 0;
|
|
@@ -71,33 +81,32 @@ namespace Invercargill.DataStructures {
|
|
|
|
|
|
public void add (T item) {
|
|
public void add (T item) {
|
|
// Get lock and update count of items
|
|
// Get lock and update count of items
|
|
- rw_lock.writer_lock();
|
|
|
|
|
|
+ // rw_lock.writer_lock();
|
|
n_items++;
|
|
n_items++;
|
|
|
|
|
|
- SeriesNode<T>? parent = null;
|
|
|
|
- SeriesNode<T> current = root;
|
|
|
|
|
|
+ SeriesNode<T>* parent = null;
|
|
|
|
+ SeriesNode<T>* current = root;
|
|
int cmp = 0;
|
|
int cmp = 0;
|
|
|
|
|
|
while(current != nil) {
|
|
while(current != nil) {
|
|
parent = current;
|
|
parent = current;
|
|
- cmp = comparitor(item, current.sample());
|
|
|
|
|
|
+ cmp = comparitor(item, current->sample());
|
|
if(cmp == 0) {
|
|
if(cmp == 0) {
|
|
// Add to node, has no effect on tree
|
|
// Add to node, has no effect on tree
|
|
- current.add_value(item);
|
|
|
|
- rw_lock.writer_unlock();
|
|
|
|
|
|
+ current->add_value(item);
|
|
|
|
+ // rw_lock.writer_unlock();
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
if(cmp < 0) {
|
|
if(cmp < 0) {
|
|
- current = current.left_child;
|
|
|
|
|
|
+ current = current->left_child;
|
|
}
|
|
}
|
|
else {
|
|
else {
|
|
- current = current.right_child;
|
|
|
|
|
|
+ current = current->right_child;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- var new_node = new SeriesNode<T> (item, nil);
|
|
|
|
- node_refs.add(new_node);
|
|
|
|
- new_node.parent = parent;
|
|
|
|
|
|
+ SeriesNode<T>* new_node = new SeriesNode<T> (Invercargill.single<T>(item).to_series(), nil);
|
|
|
|
+ new_node->parent = parent;
|
|
if(parent == null) {
|
|
if(parent == null) {
|
|
root = new_node;
|
|
root = new_node;
|
|
}
|
|
}
|
|
@@ -107,62 +116,62 @@ namespace Invercargill.DataStructures {
|
|
assert_not_reached ();
|
|
assert_not_reached ();
|
|
}
|
|
}
|
|
else if(cmp < 0) {
|
|
else if(cmp < 0) {
|
|
- parent.left_child = new_node;
|
|
|
|
|
|
+ parent->left_child = new_node;
|
|
}
|
|
}
|
|
else {
|
|
else {
|
|
- parent.right_child = new_node;
|
|
|
|
|
|
+ parent->right_child = new_node;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- if(new_node.parent == null) {
|
|
|
|
- new_node.is_red = false;
|
|
|
|
|
|
+ if(new_node->parent == null) {
|
|
|
|
+ new_node->is_red = false;
|
|
}
|
|
}
|
|
- else if(new_node.parent.parent != null) {
|
|
|
|
|
|
+ else if(new_node->parent->parent != null) {
|
|
fix_insert(new_node);
|
|
fix_insert(new_node);
|
|
}
|
|
}
|
|
|
|
|
|
- rw_lock.writer_unlock();
|
|
|
|
|
|
+ // rw_lock.writer_unlock();
|
|
}
|
|
}
|
|
|
|
|
|
- private void fix_insert(SeriesNode<T> new_node) {
|
|
|
|
- var 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;
|
|
|
|
|
|
+ private void fix_insert(SeriesNode<T>* new_node) {
|
|
|
|
+ SeriesNode<T>* 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;
|
|
continue;
|
|
}
|
|
}
|
|
- if(node == node.parent.right_child) {
|
|
|
|
- node = node.parent;
|
|
|
|
|
|
+ if(node == node->parent->right_child) {
|
|
|
|
+ node = node->parent;
|
|
rotate_left(node);
|
|
rotate_left(node);
|
|
}
|
|
}
|
|
- node.parent.is_red = false;
|
|
|
|
- node.parent.parent.is_red = true;
|
|
|
|
- rotate_right (node.parent.parent);
|
|
|
|
|
|
+ node->parent->is_red = false;
|
|
|
|
+ node->parent->parent->is_red = true;
|
|
|
|
+ rotate_right (node->parent->parent);
|
|
}
|
|
}
|
|
else {
|
|
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;
|
|
|
|
|
|
+ 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;
|
|
continue;
|
|
}
|
|
}
|
|
- if(node == node.parent.left_child) {
|
|
|
|
- node = node.parent;
|
|
|
|
|
|
+ if(node == node->parent->left_child) {
|
|
|
|
+ node = node->parent;
|
|
rotate_right(node);
|
|
rotate_right(node);
|
|
}
|
|
}
|
|
- node.parent.is_red = false;
|
|
|
|
- node.parent.parent.is_red = true;
|
|
|
|
- rotate_left(node.parent.parent);
|
|
|
|
|
|
+ node->parent->is_red = false;
|
|
|
|
+ node->parent->parent->is_red = true;
|
|
|
|
+ rotate_left(node->parent->parent);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- root.is_red = false;
|
|
|
|
|
|
+ root->is_red = false;
|
|
}
|
|
}
|
|
public void remove_first_where (PredicateDelegate<T> predicate) {
|
|
public void remove_first_where (PredicateDelegate<T> predicate) {
|
|
assert_not_reached ();
|
|
assert_not_reached ();
|
|
@@ -175,68 +184,71 @@ namespace Invercargill.DataStructures {
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
- private void rotate_left(SeriesNode<T> x) {
|
|
|
|
- var 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)
|
|
|
|
|
|
+ private void rotate_left(SeriesNode<T>* x) {
|
|
|
|
+ SeriesNode<T>* 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;
|
|
root = y;
|
|
- else if(x.parent.left_child == x)
|
|
|
|
- x.parent.left_child = y;
|
|
|
|
|
|
+ else if(x->parent->left_child == x)
|
|
|
|
+ x->parent->left_child = y;
|
|
else
|
|
else
|
|
- x.parent.right_child = y;
|
|
|
|
- y.left_child = x;
|
|
|
|
- x.parent = y;
|
|
|
|
|
|
+ x->parent->right_child = y;
|
|
|
|
+ y->left_child = x;
|
|
|
|
+ x->parent = y;
|
|
}
|
|
}
|
|
|
|
|
|
- private void rotate_right(SeriesNode<T> x) {
|
|
|
|
- var 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)
|
|
|
|
|
|
+ private void rotate_right(SeriesNode<T>* x) {
|
|
|
|
+ SeriesNode<T>* 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;
|
|
root = y;
|
|
- else if(x.parent.right_child == x)
|
|
|
|
- x.parent.right_child = y;
|
|
|
|
|
|
+ else if(x->parent->right_child == x)
|
|
|
|
+ x->parent->right_child = y;
|
|
else
|
|
else
|
|
- x.parent.left_child = y;
|
|
|
|
- y.right_child = x;
|
|
|
|
- x.parent = y;
|
|
|
|
|
|
+ x->parent->left_child = y;
|
|
|
|
+ y->right_child = x;
|
|
|
|
+ x->parent = y;
|
|
}
|
|
}
|
|
|
|
|
|
private class TreeTracker<T> : Tracker<T> {
|
|
private class TreeTracker<T> : Tracker<T> {
|
|
|
|
|
|
- SeriesNode<T> node;
|
|
|
|
- SeriesNode<T>? next_node;
|
|
|
|
|
|
+ SeriesNode<T>* node;
|
|
|
|
+ SeriesNode<T>* next_node;
|
|
SortedSeries<T> series;
|
|
SortedSeries<T> series;
|
|
- Tracker<T> values;
|
|
|
|
|
|
+ SeriesNodeItem<T>* values;
|
|
|
|
|
|
public TreeTracker(SortedSeries<T> series) {
|
|
public TreeTracker(SortedSeries<T> series) {
|
|
print("New tracker!\n");
|
|
print("New tracker!\n");
|
|
this.series = series;
|
|
this.series = series;
|
|
node = series.root;
|
|
node = series.root;
|
|
- while(node.left_child != series.nil) {
|
|
|
|
- node = node.left_child;
|
|
|
|
|
|
+ while(node->left_child != series.nil) {
|
|
|
|
+ node = node->left_child;
|
|
}
|
|
}
|
|
- values = node.values.get_tracker();
|
|
|
|
|
|
+ values = node->first_value;
|
|
find_next_node();
|
|
find_next_node();
|
|
}
|
|
}
|
|
|
|
|
|
public override bool has_next () {
|
|
public override bool has_next () {
|
|
- return values.has_next() || next_node != null;
|
|
|
|
|
|
+ return values != null || next_node != null;
|
|
}
|
|
}
|
|
public override T get_next () {
|
|
public override T get_next () {
|
|
- if(values.has_next()) {
|
|
|
|
- return values.get_next();
|
|
|
|
|
|
+ if(values != null) {
|
|
|
|
+ var item = values->item;
|
|
|
|
+ print(@"get next $((int)item)\n");
|
|
|
|
+ values = values->next;
|
|
|
|
+ print(@"next up $((int)values)\n");
|
|
|
|
+ return item;
|
|
}
|
|
}
|
|
node = next_node;
|
|
node = next_node;
|
|
- values = node.values.get_tracker();
|
|
|
|
- var result = values.get_next();
|
|
|
|
|
|
+ values = node->first_value;
|
|
find_next_node();
|
|
find_next_node();
|
|
- return result;
|
|
|
|
|
|
+ return values->item;
|
|
}
|
|
}
|
|
|
|
|
|
private void find_next_node() {
|
|
private void find_next_node() {
|
|
@@ -262,18 +274,18 @@ namespace Invercargill.DataStructures {
|
|
next_node = null;
|
|
next_node = null;
|
|
if (node == null) return;
|
|
if (node == null) return;
|
|
// standard inorder successor:
|
|
// standard inorder successor:
|
|
- if (node.right_child != series.nil) {
|
|
|
|
- var n = node.right_child;
|
|
|
|
- while (n.left_child != series.nil)
|
|
|
|
- n = n.left_child;
|
|
|
|
|
|
+ if (node->right_child != series.nil) {
|
|
|
|
+ SeriesNode<T>* n = node->right_child;
|
|
|
|
+ while (n->left_child != series.nil)
|
|
|
|
+ n = n->left_child;
|
|
next_node = n;
|
|
next_node = n;
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
- var n = node;
|
|
|
|
- var p = n.parent;
|
|
|
|
- while (p != null && n == p.right_child) {
|
|
|
|
|
|
+ SeriesNode<T>* n = node;
|
|
|
|
+ SeriesNode<T>* p = n->parent;
|
|
|
|
+ while (p != null && n == p->right_child) {
|
|
n = p;
|
|
n = p;
|
|
- p = p.parent;
|
|
|
|
|
|
+ p = p->parent;
|
|
}
|
|
}
|
|
next_node = p; // could be null (end)
|
|
next_node = p; // could be null (end)
|
|
}
|
|
}
|