Ranides Atterwim %!s(int64=4) %!d(string=hai) anos
pai
achega
ec48b9bb62

+ 5 - 4
assira.core/src/main/java/net/ranides/assira/collection/query/CQueryAbstract.java

@@ -8,6 +8,7 @@ package net.ranides.assira.collection.query;
 
 import net.ranides.assira.collection.HashFunction;
 import net.ranides.assira.collection.iterators.IterableUtils;
+import net.ranides.assira.collection.query.base.CQArray;
 import net.ranides.assira.collection.query.base.CQList;
 import net.ranides.assira.collection.query.derived.*;
 import net.ranides.assira.collection.query.support.BaseEach;
@@ -203,14 +204,14 @@ public abstract class CQueryAbstract<T> implements CQuery<T>, CQueryFeatures {
 
     @Override
     public CQuery<T> cache(Path filename) throws IOException {
-        List<T> data;
+        Object[] data;
         if(Files.exists(filename)) {
-            data = SerializationUtils.read(new TypeToken<List<T>>() {}, filename);
+            data = SerializationUtils.read(new TypeToken<T[]>() {}, filename);
         } else {
-            data = list();
+            data = array();
             SerializationUtils.write(filename, data);
         }
-        return new CQList<>(data);
+        return new CQArray<T>((T[])data);
     }
 
     @Override

+ 7 - 0
assira.core/src/main/java/net/ranides/assira/collection/query/base/CQArray.java

@@ -15,6 +15,7 @@ import java.util.Optional;
 import java.util.Set;
 import java.util.Spliterator;
 import java.util.function.Consumer;
+import java.util.function.IntFunction;
 import java.util.function.Predicate;
 import java.util.stream.Stream;
 
@@ -85,6 +86,12 @@ public class CQArray<T> extends CQueryAbstract<T> {
         return end - begin;
     }
 
+    @Override
+    public <A> A[] array(IntFunction<A[]> generator) {
+        int n = size();
+        return (A[])ArrayUtils.copy(data, begin, generator.apply(n), 0, n);
+    }
+
     @Override
     public Object[] array() {
         return isSlice() ? ArrayUtils.slice(data, begin, end) : data;

+ 61 - 7
assira.core/src/test/java/net/ranides/assira/collection/query/CQueryAbstractTest.java

@@ -6,20 +6,27 @@ import org.junit.Assert;
 import org.junit.Test;
 
 import net.ranides.assira.collection.lists.VirtualList;
+import net.ranides.assira.collection.maps.ArrayMap;
+import net.ranides.assira.collection.maps.MapBuilder;
 import net.ranides.assira.collection.query.base.CQArray;
 import net.ranides.assira.collection.query.base.CQArraySupplier;
 import net.ranides.assira.collection.query.base.CQIterator;
 import net.ranides.assira.collection.query.base.CQListSupplier;
 
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.Map;
 import java.util.concurrent.atomic.AtomicInteger;
 
 public class CQueryAbstractTest {
 
     @Test
-    public void validateContent() {
+    public void testContent() {
         Integer[] array = {3, 4, 5, 6};
         List<Integer> expected = new ArrayList<>(Arrays.asList(array));
 
@@ -34,7 +41,7 @@ public class CQueryAbstractTest {
     }
 
     @Test
-    public void validateContentForSpecialFeatures() {
+    public void testContentForSpecialFeatures() {
         Integer[] array = {3, 4, 5, 6};
         List<Integer> expected = new ArrayList<>(Arrays.asList(array));
 
@@ -52,7 +59,7 @@ public class CQueryAbstractTest {
     }
 
     @Test
-    public void validateJoin() {
+    public void testJoin() {
         Integer[] array = {3, 4, 5, 6};
         List<Integer> expected = new ArrayList<>(Arrays.asList(array));
 
@@ -70,7 +77,7 @@ public class CQueryAbstractTest {
     }
 
     @Test
-    public void validateFetch() {
+    public void testFetch() {
         AtomicInteger counter = new AtomicInteger(0);
         AtomicInteger state = new AtomicInteger(777);
         List<Integer> list = VirtualList.of(5, i -> {
@@ -116,7 +123,7 @@ public class CQueryAbstractTest {
     }
 
     @Test
-    public void validatePrefetch() {
+    public void testPrefetch() {
         AtomicInteger counter = new AtomicInteger(0);
         AtomicInteger state = new AtomicInteger(777);
         List<Integer> list = VirtualList.of(5, i -> {
@@ -160,8 +167,55 @@ public class CQueryAbstractTest {
         Assert.assertEquals(base+10, counter.get());
     }
 
-//    @Test
-//    public void validateList() {
+    @Test
+    public void testCache() throws IOException {
+        AtomicInteger counter = new AtomicInteger(0);
+        AtomicInteger state = new AtomicInteger(777);
+        List<Integer> list = VirtualList.of(5, i -> {
+            counter.incrementAndGet();
+            return state.get()+i;
+        });
+
+        Path file = File.createTempFile("cquery2", ".bin").toPath();
+        Files.deleteIfExists(file);
+
+        state.set(10);
+        CQuery<Integer> a = CQListSupplier.from(true, () -> list).cache(file);
+        Assert.assertEquals(5, counter.get());
+
+        state.set(20);
+        CQueryAssert.assertEquals(Arrays.asList(10,11,12,13,14), a);
+        Assert.assertEquals(5, counter.get());
+
+        state.set(30);
+        CQueryAssert.assertEquals(Arrays.asList(10,11,12,13,14), a);
+        Assert.assertEquals(5, counter.get());
+
+        CQuery<Integer> b = CQListSupplier.from(true, () -> list).cache(file);
+        CQuery<Integer> c = CQListSupplier.from(true, () -> list);
+
+        state.set(40);
+        CQueryAssert.assertEquals(Arrays.asList(10,11,12,13,14), b);
+        Assert.assertEquals(5, counter.get());
+        CQueryAssert.assertEquals(Arrays.asList(40,41,42,43,44), c);
+        Assert.assertTrue(counter.get() > 5);
+    }
+
+    @Test
+    public void testGroup() {
+        Integer[] array = {4, 5, 6, 7, 8, 9};
+        List<Integer> expected = new ArrayList<>(Arrays.asList(array));
+
+        CQueryAssert.assertGroup(expected, CQueryMockup.of("each1", array));
+        CQueryAssert.assertGroup(expected, CQueryMockup.of("each2", array));
+        CQueryAssert.assertGroup(expected, CQueryMockup.of("stream", array));
+        CQueryAssert.assertGroup(expected, CQueryMockup.of("iterator", array));
+    }
+
+
+
+    //    @Test
+//    public void testList() {
 //        // TODO: in fact, we must not return VIEW of data, but independent list
 //        // Independent means:
 //        //  - modification of source collection should not be visible

+ 16 - 0
assira.core/src/test/java/net/ranides/test/CQueryAssert.java

@@ -1,8 +1,10 @@
 package net.ranides.test;
 
+import net.ranides.test.mockup.query.CQueryMockup;
 import org.junit.Assert;
 
 import net.ranides.assira.collection.lists.ListUtils;
+import net.ranides.assira.collection.maps.ArrayMap;
 import net.ranides.assira.collection.query.CQuery;
 import net.ranides.assira.collection.query.support.BaseArray;
 import net.ranides.assira.collection.query.support.BaseEach;
@@ -11,13 +13,27 @@ import net.ranides.assira.collection.query.support.BaseStream;
 import net.ranides.assira.text.StringUtils;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 import java.util.stream.Collectors;
 
 public class CQueryAssert {
 
+    public static <T> void assertGroup(List<T> values, CQuery<T> query) {
+        Map<String, T> expected1 = new HashMap<>();
+        Map<String, String> expected2 = new HashMap<>();
+
+        for(T v : values) {
+            expected1.put("#"+v, v);
+            expected2.put("#K"+v, "#V"+v);
+        }
+        Assert.assertEquals(expected1, query.group(i -> "#" + i));
+        Assert.assertEquals(expected2, query.group(i -> "#K" + i, i -> "#V"+i));
+    }
+
     public static <T> void assertEquals(List<T> expected, CQuery<T> query) {
         assertList(expected, query);
         assertSet(expected, query);