changeset 190:528f16f988d8

Implement repeated
author Chris Cannam
date Sun, 05 May 2013 18:24:00 +0100
parents fa9a15681ba9
children 1141702908dc
files yetilab/matrix/matrix.yeti yetilab/stream/filter.yeti yetilab/stream/test/test_filter.yeti
diffstat 3 files changed, 34 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/yetilab/matrix/matrix.yeti	Sun May 05 17:55:01 2013 +0100
+++ b/yetilab/matrix/matrix.yeti	Sun May 05 18:24:00 2013 +0100
@@ -197,9 +197,8 @@
 
 concat direction mm = //!!! doc: storage order is taken from first matrix in sequence
     //!!! would this be better as separate concatHorizontal/concatVertical functions?
-    if empty? mm then zeroSizeMatrix ()
-    else
-        first = head mm;
+    case mm of
+    first::rest: 
         checkDimensionsFor direction first mm;
         row = first.isRowMajor?;
         // horizontal, row-major: against grain with rows
@@ -216,7 +215,9 @@
             else concatAgainstGrain ColM (.getColumn) (.columns) mm;
             fi;
         esac;
-    fi;
+    [single]: single;
+    _: zeroSizeMatrix ();
+    esac;
 
 rowSlice start count m = //!!! doc: storage order same as input
     if m.isRowMajor? then
--- a/yetilab/stream/filter.yeti	Sun May 05 17:55:01 2013 +0100
+++ b/yetilab/stream/filter.yeti	Sun May 05 18:24:00 2013 +0100
@@ -91,27 +91,38 @@
     };
 
 repeated s =
-    // There is no way to reset a stream (in principle, they might be
-    // "live") so we can't read from the same stream repeatedly -- we
-    // have to cache its output and then repeat that. This is tricky
-    // to do efficiently without knowing how much is going to be
-    // requested at a time.
+    // There is no way to reset a stream (as in principle, they might
+    // be "live") so we can't read from the same stream repeatedly --
+    // we have to cache its output and then repeat that. This is a
+    // little tricky to do efficiently without knowing how long the
+    // stream is (in general) or how much is going to be requested at
+    // a time.
     if s.available == Infinite () then s
     else
         var pos = 0;
         var cache = mat.zeroSizeMatrix ();
         chunks = array [];
+        cachedPartsFor count =
+           (start = pos % cache.size.columns;
+            avail = cache.size.columns - start;
+            if avail >= count then
+                pos := pos + count;
+                [mat.columnSlice start count cache]
+            else
+                pos := pos + avail;
+                mat.columnSlice start avail cache ::
+                    cachedPartsFor (count - avail);
+            fi);
         readFromCache count =
            (if cache.size.columns == 0 then
-                cache := mat.concat (Horizontal ()) chunks;
+                cache := mat.concat (Horizontal ()) (list chunks);
                 clearArray chunks;
             fi;
-
-            //!!! implement
-            result = mat.zeroSizeMatrix ();
-
-            pos := pos + count;
-            result);
+            if cache.size.columns == 0 then
+                cache
+            else
+                mat.concat (Horizontal ()) (cachedPartsFor count);
+            fi);
         {
             get position () = pos,
             get channels () = s.channels,
--- a/yetilab/stream/test/test_filter.yeti	Sun May 05 17:55:01 2013 +0100
+++ b/yetilab/stream/test/test_filter.yeti	Sun May 05 18:24:00 2013 +0100
@@ -209,13 +209,17 @@
         compare str.available (Infinite ()) and
         compare str.finished? false and
         compare (map bl.list (mat.asRows (str.read 1))) [[1]] and
+        compare str.position 1 and
         compare (map bl.list (mat.asRows (str.read 2))) [[2,3]] and
+        compare str.position 3 and
         compare (map bl.list (mat.asRows (str.read 3))) [[1,2,3]] and
+        compare str.position 6 and
         compare (map bl.list (mat.asRows (str.read 5))) [[1,2,3,1,2]] and
+        compare (map bl.list (mat.asRows (str.read 9))) [[3,1,2,3,1,2,3,1,2]] and
         compare (map bl.list (mat.asRows (str.read 2))) [[3,1]] and
         compare str.available (Infinite ()) and
-        compare str.finished? true and
-        compare str.position 13 and
+        compare str.finished? false and
+        compare str.position 22 and
         ( str.close (); true )
 ),