Bläddra i källkod

Didn't work well

Billy Barrow 3 veckor sedan
förälder
incheckning
0c92f9b04c

+ 1 - 1
src/lib/DataStructures/Series.vala

@@ -3,7 +3,7 @@ namespace Invercargill.DataStructures {
     public class Series<T> : Enumerable<T>, Lot<T>, ReadOnlyCollection<T>, Collection<T> {
      
         internal class SeriesItem<T> {
-            public SeriesItem next = null;
+            public SeriesItem<T>? next = null;
             public T value;
 
             public SeriesItem(T value) {

+ 180 - 151
src/lib/DataStructures/SortedSeries.vala

@@ -3,52 +3,74 @@ namespace Invercargill.DataStructures {
 
     public class SortedSeries<T> : Enumerable<T>, Lot<T>, ReadOnlyCollection<T>, Collection<T> {
 
-        private class SeriesNode<T> {
-            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 SeriesNode(T item, SeriesNode<T> nil) {
-                is_red = true;
-                left_child = nil;
-                right_child = nil;
-                values = new Series<T>();
-                values.add(item);
-            }
+        private uint root;
+        private uint nil;
 
-            public SeriesNode.nil() {
-                is_red = false;
-                left_child = this;
-                right_child = this;
-                values = new Series<T>();
-            }
+        private uint data_count = 0;
+        private uint[] data;
+        private Vector<Series<T>> buckets;
 
-            public T sample() {
-                return values.first_or_default();
+        private uint read_left_child(uint index) {
+            return data[index+1];
+        }
+        private uint read_right_child(uint index) {
+            return data[index+2];
+        }
+        private uint? read_parent(uint index) {
+            var value = data[index];
+            if(value == 0){
+                return null;
             }
-
-            public void add_value(T value) {
-                values.add(value);
+            return value;
+        }
+        private bool read_is_red(uint index) {
+            return data[index+4] == 1;
+        }
+        private void write_left_child(uint index, uint value) {
+            data[index+1] = value;
+        }
+        private void write_right_child(uint index, uint value) {
+            data[index+2] = value;
+        }
+        private void write_parent(uint index, uint? value) {
+            if(value == null) {
+                data[index] = 0;
+                return;
             }
-
-            //  public void remove_all_values_where (PredicateDelegate<T> predicate) {
-            //      values = values.where(v => !predicate(v)).to_buffer();
-            //  }
+            data[index] = value;
+        }
+        private void write_is_red(uint index, bool value) {
+            data[index+4] = value ? 1 : 0;
+        }
+        private void add_to_bucket(uint index, T item) {
+            buckets[data[index+3]].add(item);
+        }
+        private Tracker<T> get_bucket_tracker(uint index) {
+            return buckets[data[index+3]].get_tracker();
+        }
+        private T get_bucket_sample(uint index) {
+            print(@"$(buckets[data[index+3]].count()) in buk $index with $n_items\n");
+            return buckets[data[index+3]].first_or_default();
+        }
+        private uint create_node() {
+            var index = data_count;
+            data_count += 5;
+            //  data.add_all(Invercargill.range(0, 5).select<uint>(i => 0));
+            var bucket_index = buckets.count();
+            data[index+3] = bucket_index;
+            buckets.add(new Series<T>());
+            return index;
         }
 
-        private SeriesNode<T> root;
-        private SeriesNode<T> nil;
         private RWLock rw_lock;
-        private Series<SeriesNode<T>> node_refs;
         private CompareDelegate<T> comparitor;
         private int n_items;
 
         public SortedSeries(owned CompareDelegate<T>? comparitor = null) {
-            nil = new SeriesNode<T>.nil();
-            node_refs = new Series<SeriesNode<T>>();
-            node_refs.add(nil);
+            buckets = new Vector<Series<T>>();
+            //  data = new Vector<uint>();
+            data = new uint[15000];
+            nil = create_node();
             root = nil;
             rw_lock = RWLock();
             n_items = 0;
@@ -74,30 +96,30 @@ namespace Invercargill.DataStructures {
             rw_lock.writer_lock();
             n_items++;
 
-            SeriesNode<T>? parent = null;
-            SeriesNode<T> current = root;
+            uint? parent = null;
+            uint current = root;
             int cmp = 0;
 
             while(current != nil) {
                 parent = current;
-                cmp = comparitor(item, current.sample());
+                cmp = comparitor(item, get_bucket_sample(current));
                 if(cmp == 0) {
                     // Add to node, has no effect on tree
-                    current.add_value(item);
+                    add_to_bucket(current, item);
                     rw_lock.writer_unlock();
                     return;
                 }
                 if(cmp < 0) {
-                    current = current.left_child;
+                    current = read_left_child(current);
                 }
                 else {
-                    current = current.right_child;
+                    current = read_right_child(current);
                 }
             }
 
-            var new_node = new SeriesNode<T> (item, nil);
-            node_refs.add(new_node);
-            new_node.parent = parent;
+            var new_node = create_node();
+            add_to_bucket(new_node, item);
+            write_parent(new_node, parent);
             if(parent == null) {
                 root = new_node;
             }
@@ -107,63 +129,71 @@ namespace Invercargill.DataStructures {
                     assert_not_reached ();
                 }
                 else if(cmp < 0) {
-                    parent.left_child = new_node;
+                    write_left_child(parent, new_node);
                 }
                 else {
-                    parent.right_child = new_node;
+                    write_right_child(parent, new_node);
                 }
             }
 
-            if(new_node.parent == null) {
-                new_node.is_red = false;
+            if(read_parent(new_node) == null) {
+                write_is_red(new_node, false);
             }
-            else if(new_node.parent.parent != null) {
+            else if(read_parent(read_parent(new_node)) != null) {
                 fix_insert(new_node);
             }
 
             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(uint z) {
+            uint node = z;
+
+            while(node != root && read_is_red(read_parent(node))) {
+                uint parent = read_parent(node);
+                uint grandparent = read_parent(parent);
+
+                if(parent == read_left_child(grandparent)) {
+                    uint uncle = read_right_child(grandparent);
+                    if(uncle != nil && read_is_red(uncle)) {
+                        write_is_red(parent, false);
+                        write_is_red(uncle, false);
+                        write_is_red(grandparent, true);
+                        node = grandparent;
                         continue;
                     }
-                    if(node == node.parent.right_child) {
-                        node = node.parent;
+                    if(node == read_right_child(parent)) {
+                        node = parent;
                         rotate_left(node);
+                        parent = read_parent(node);
+                        grandparent = read_parent(parent);
                     }
-                    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;
+                    write_is_red(parent, false);
+                    write_is_red(grandparent, true);
+                    rotate_right(grandparent);
+                } else {
+                    uint uncle = read_left_child(grandparent);
+                    if(uncle != nil && read_is_red(uncle)) {
+                        write_is_red(parent, false);
+                        write_is_red(uncle, false);
+                        write_is_red(grandparent, true);
+                        node = grandparent;
                         continue;
                     }
-                    if(node == node.parent.left_child) {
-                        node = node.parent;
+                    if(node == read_left_child(parent)) {
+                        node = parent;
                         rotate_right(node);
+                        parent = read_parent(node);
+                        grandparent = read_parent(parent);
                     }
-                    node.parent.is_red = false;
-                    node.parent.parent.is_red = true;
-                    rotate_left(node.parent.parent);
+                    write_is_red(parent, false);
+                    write_is_red(grandparent, true);
+                    rotate_left(grandparent);
                 }
             }
-            root.is_red = false;
+            write_is_red(root, false);
         }
+
         public void remove_first_where (PredicateDelegate<T> predicate) {
             assert_not_reached ();
         }
@@ -175,111 +205,110 @@ 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(uint x) {
+            uint y = read_right_child(x);
+            write_right_child(x, read_left_child(y));
+            if(read_left_child(y) != nil)
+                write_parent(read_left_child(y), x);
+            write_parent(y, read_parent(x));
+            if(read_parent(x) == null)
                 root = y;
-            else if(x.parent.left_child == x)
-                x.parent.left_child = y;
+            else if(x == read_left_child(read_parent(x)))
+                write_left_child(read_parent(x), y);
             else
-                x.parent.right_child = y;
-            y.left_child = x;
-            x.parent = y;
+                write_right_child(read_parent(x), y);
+            write_left_child(y, x);
+            write_parent(x, 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(uint x) {
+            uint y = read_left_child(x);
+            write_left_child(x, read_right_child(y));
+            if(read_right_child(y) != nil)
+                write_parent(read_right_child(y), x);
+            write_parent(y, read_parent(x));
+            if(read_parent(x) == null)
                 root = y;
-            else if(x.parent.right_child == x)
-                x.parent.right_child = y;
+            else if(x == read_right_child(read_parent(x)))
+                write_right_child(read_parent(x), y);
             else
-                x.parent.left_child = y;
-            y.right_child = x;
-            x.parent = y;
+                write_left_child(read_parent(x), y);
+            write_right_child(y, x);
+            write_parent(x, y);
         }
-        
+
         private class TreeTracker<T> : Tracker<T> {
 
-            SeriesNode<T> node;
-            SeriesNode<T>? next_node;
-            SortedSeries<T> series;
-            Tracker<T> values;
+            private SortedSeries<T> series;
+            private uint current_node;
+            private uint? next_node;
+            private Tracker<T>? values;
 
             public TreeTracker(SortedSeries<T> series) {
-                print("New tracker!\n");
                 this.series = series;
-                node = series.root;
-                while(node.left_child != series.nil) {
-                    node = node.left_child;
+
+                // Find the leftmost node (smallest value)
+                current_node = series.root;
+                if(current_node != series.nil) {
+                    while(series.read_left_child(current_node) != series.nil) {
+                        current_node = series.read_left_child(current_node);
+                    }
+                    values = series.get_bucket_tracker(current_node);
                 }
-                values = node.values.get_tracker();
+
                 find_next_node();
             }
 
-            public override bool has_next () {
-                return values.has_next() || next_node != null;
+            public override bool has_next() {
+                return (values != null && values.has_next()) || next_node != null;
             }
-            public override T get_next () {
-                if(values.has_next()) {
+
+            public override T get_next() {
+                if(values != null && values.has_next()) {
                     return values.get_next();
                 }
-                node = next_node;
-                values = node.values.get_tracker();
-                var result = values.get_next();
+
+                if(next_node == null) {
+                    assert_not_reached();
+                }
+
+                current_node = next_node;
+                values = series.get_bucket_tracker(current_node);
+                T result = values.get_next();
+
                 find_next_node();
                 return result;
             }
 
             private void find_next_node() {
-                //  next_node = null;
-                //  if(node.right_child != series.nil) {
-                //      next_node = node.right_child;
-                //      while(next_node.left_child != series.nil) {
-                //          next_node = next_node.left_child;
-                //      }
-                //  }
-                //  else if(node.parent == null) {
-                //      next_node = null;
-                //  }
-                //  else if(node.parent.left_child == node) {
-                //      next_node = node.parent;
-                //  }
-                //  else if(node.parent.parent.right_child == node.parent) {
-                //      next_node = null;
-                //  }
-                //  else {
-                //      next_node = node.parent.parent;
-                //  }
                 next_node = null;
-                if (node == null) return;
-                // 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(current_node == series.nil) return;
+
+                uint n = current_node;
+
+                // If there is a right child, go there then all the way left
+                uint right = series.read_right_child(n);
+                if(right != series.nil) {
+                    n = right;
+                    while(series.read_left_child(n) != series.nil) {
+                        n = series.read_left_child(n);
+                    }
                     next_node = n;
                     return;
                 }
-                var n = node;
-                var p = n.parent;
-                while (p != null && n == p.right_child) {
-                    n = p;
-                    p = p.parent;
+
+                // Walk up the tree until we find a node that is a left child
+                uint? parent = series.read_parent(n);
+                while(parent != null && n == series.read_right_child(parent)) {
+                    n = parent;
+                    parent = series.read_parent(n);
                 }
-                next_node = p; // could be null (end)
-            }
 
+                next_node = parent; // could be null if we've reached the end
+            }
         }
 
+
     }
 
 }

+ 1 - 1
src/tests/Integration/SortedSeries.vala

@@ -9,8 +9,8 @@ void sorted_series_tests() {
         var series = new SortedSeries<int>();
         series.add(8);
 
-        assert(series.first_or_default() == 8);
         assert(series.count() == 1);
+        assert_cmpint(series.first_or_default(), CompareOperator.EQ, 8);
     });
 
     Test.add_func("/invercargill/structure/sorted_series/add_many", () => {

+ 23 - 23
src/tests/TestRunner.vala

@@ -3,33 +3,33 @@ public static int main(string[] args) {
 
     Test.init(ref args);
 
-    where_tests();
-    select_tests();
-    select_many_tests();
-    gee_tests();
-    tracker_tests();
-    parallel_tests();
-    first_tests();
-    binary_data_tests();
-    sort_tests();
-    vector_tests();
-    series_tests();
-    array_tests();
-    promotion_tests();
-    numbers_test();
-    dictionary_tests();
-    property_mapper_tests();
-    cache_tests();
-    sorted_vector_tests();
+    //  where_tests();
+    //  select_tests();
+    //  select_many_tests();
+    //  gee_tests();
+    //  tracker_tests();
+    //  parallel_tests();
+    //  first_tests();
+    //  binary_data_tests();
+    //  sort_tests();
+    //  vector_tests();
+    //  series_tests();
+    //  array_tests();
+    //  promotion_tests();
+    //  numbers_test();
+    //  dictionary_tests();
+    //  property_mapper_tests();
+    //  cache_tests();
+    //  sorted_vector_tests();
     sorted_series_tests();
 
     Test.run();
     
-    series_speed_test();
-    vector_speed_test();
-    set_speed_test();
-    dictionary_speed_test();
-    fifo_speed_test();
+    //  series_speed_test();
+    //  vector_speed_test();
+    //  set_speed_test();
+    //  dictionary_speed_test();
+    //  fifo_speed_test();
 
 
     return 0;