Package edu.umass.pql

Source Code of edu.umass.pql.ReductionTest$ReductorTest

/***************************************************************************
Copyright (C) 2011 Christoph Reichenbach <creichen@gmail.com>

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public Licence as
published by the Free Software Foundaton; either version 2 of the
Licence, or (at your option) any later version.

It is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
merchantability or fitness for a particular purpose. See the
GNU General Public Licence for more details.

You should have received a copy of the GNU General Public Licence
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.

***************************************************************************/


package edu.umass.pql;

import edu.umass.pql.il.ReductionImpl;
import edu.umass.pql.container.PDefaultMap;
import edu.umass.pql.container.PMap;
import java.util.*;
import org.junit.*;
import java.lang.reflect.Array;
import static org.junit.Assert.*;

public class ReductionTest extends TestBase
{
  static java.lang.reflect.Method sumInt = getSumIntMethod();

  @Test public void testForallZero() { paratest("para_testForallZero"); }

  public void
  para_testForallZero()
  {
    setInts(0, 0, 0, 1);
    Reduction red = PQLFactory.Forall(PQLFactory.LT_Int(i0r, i1r),
                 PQLFactory.LT_Int(i0r, i1r),
                 i4r, i3r
                 );

    testCount(1, red);
  }

  @Test public void testForallOne() { paratest("para_testForallOne"); }

  public void
  para_testForallOne()
  {
    setInts(0, 0, 0, 1);
    Reduction red = PQLFactory.Forall(PQLFactory.LTE_Int(i0r, i1r),
                 PQLFactory.LTE_Int(i0r, i1r),
                 i4r, i3r
                 );

    testCount(1, red);

    red = PQLFactory.Forall(PQLFactory.LTE_Int(i0r, i1r),
             PQLFactory.LT_Int(i0r, i1r),
             i4r, i3r
             );

    testCount(0, red);
  }


  @Test public void testForallSet() { paratest("para_testForallSet"); }

  public void
  para_testForallSet()
  {
    Set<Integer> set = new HashSet<Integer>();
    setObjects(set, null, null);
    setInts(1, 0, 0);
    set.add(2);
    set.add(3);
    set.add(4);
    set.add(17);

    ReductionImpl red = (ReductionImpl) PQLFactory.Forall(PQLFactory.CONTAINS(o0r, i1w),
                 PQLFactory.LT_Int(i0r, i1r),
                 i4r, i0r
                 );

    testCount(1, red);

    set.add(0);

    testCount(0, red);
  }


  @Test
  public void
  testFusedAPI()
  {
    final Reduction red = PQLFactory.Reduction(PQLFactory.Reductors.MAP(i0r, l0r, o0w),
                 PQLFactory.ConjunctiveBlock(), PQLFactory.ConjunctiveBlock());
    assertEquals(3, red.getArgsNr());
    assertEquals(2, red.getReadArgsNr());
    assertEquals(0, red.getOuterReadArgsNr());
    red.addReductor(PQLFactory.Reductors.DEFAULT_MAP(d1r, i1r, l1r, o1w));
    assertEquals(7, red.getArgsNr());
    assertEquals(5, red.getReadArgsNr());
    assertEquals(1, red.getOuterReadArgsNr());
    red.addReductor(PQLFactory.Reductors.DEFAULT_MAP(d2r, i2r, l2r, o2w));
    assertEquals(11, red.getArgsNr());
    assertEquals(8, red.getReadArgsNr());
    assertEquals(2, red.getOuterReadArgsNr());

    int[] expected_args = new int[] {
      d1r, d2r, i0r, l0r, i1r, l1r, i2r, l2r, o0w, o1w, o2w
    };

    assertEquals(11, expected_args.length);

    for (int k = -1; k < expected_args.length; k++) {
      if (k >= 0) {
        expected_args[k] = Env.encodeVar(TYPE_INT, k+10);
        red.setArg(k, expected_args[k]);
      }

      for (int i = 0; i < expected_args.length; i++)
        assertEquals("argument #" + i + ": " + Env.showVar(expected_args[i]) + " vs " + Env.showVar(red.getArg(i)) + " at k=" + k,
               expected_args[i],
               red.getArg(i));
    }
  }


  @Test
  public void
  testPredicateIteration()
  {
    setInts(0, 1, 0);
    testCount(1, PQLFactory.LT_Int(i0r, i1r));
  }


  Set<Integer> setLow = new HashSet<Integer>();
  Set<Integer> setLow2 = new HashSet<Integer>();
  Set<Integer> setHigh = new HashSet<Integer>();



  protected void
  resetSets()
  {
    this.reset();
  }


  @Override
  protected void
  reset()
  {
    setObjects(setLow, setHigh, setLow2);

    setLow.clear();
    setLow2.clear();
    setHigh.clear();

    setLow.add(2);
    setLow.add(3);
    setLow.add(5);
    setLow.add(7);

    setLow2.add(20);
    setLow2.add(30);
    setLow2.add(50);
    setLow2.add(7);

    setHigh.add(20);
    setHigh.add(300);
    setHigh.add(5000);
    setHigh.add(70000);
  }


  @Test
  public void
  testComboBlock()
  {
    resetSets();
    ControlStructure b = PQLFactory.ConjunctiveBlock(new Join[] {
        PQLFactory.CONTAINS(o0r, i0w),
        PQLFactory.CONTAINS(o1r, i1w)
      });

    testCount(16, b);
  }

  @Test public void testMergedForall() { paratest("para_testMergedForall"); }

  public void
  para_testMergedForall()
  {
    resetSets();
    ControlStructure b = PQLFactory.ConjunctiveBlock(new Join[] {
        PQLFactory.CONTAINS(o0r, i0w),
        PQLFactory.CONTAINS(o1r, i1w)
      });
    setInts(0, 0, 0, 1);

    testCount(1, PQLFactory.Forall(b,
              PQLFactory.LT_Int(i0r, i1r),
              i4r, i3r
              ));
  }

  @Test public void testNestedForall() { paratest("para_testNestedForall"); }

  public void
  para_testNestedForall()
  {
    resetSets();
    setInts(0, 0, 0, 1);
    ControlStructure b = PQLFactory.ConjunctiveBlock(new Join[] {
        PQLFactory.Forall(PQLFactory.CONTAINS(o0r, i0w),
                 PQLFactory.LT_Int(i0r, i1r),
                 i4r, i3r)
      });

    testCount(1, PQLFactory.Forall(PQLFactory.CONTAINS(o1r, i1w),
              b,
              i4r, i3r));
            
  }

  @Test public void testExistsZero() { paratest("para_testExistsZero"); }

  public void
  para_testExistsZero()
  {
    setInts(0, 0, 0, 1);
    Reduction red = PQLFactory.Exists(PQLFactory.LT_Int(i0r, i1r),
                 PQLFactory.LT_Int(i0r, i1r),
                 i4r, i3r);

    testCount(0, red);
  }

  @Test public void testExistsOne() { paratest("para_testExistsOne"); }

  public void
  para_testExistsOne()
  {
    setInts(0, 0, 0, 1);
    Reduction red = PQLFactory.Exists(PQLFactory.LTE_Int(i0r, i1r),
                 PQLFactory.LTE_Int(i0r, i1r),
                 i4r, i3r);

    testCount(1, red);

    red = PQLFactory.Exists(PQLFactory.LTE_Int(i0r, i1r),
             PQLFactory.LT_Int(i0r, i1r),
             i4r, i3r);

    testCount(0, red);
  }


  @Test public void testExistsSet() { paratest("para_testExistsSet"); }

  public void
  para_testExistsSet()
  {
    Set<Integer> set = new HashSet<Integer>();
    setObjects(set, null, null);
    setInts(15, 0, 0, 1);
    set.add(2);
    set.add(3);
    set.add(4);
    set.add(15);

    Reduction red = PQLFactory.Exists(PQLFactory.CONTAINS(o0r, i1w),
                 PQLFactory.LT_Int(i0r, i1r),
                 i4r, i3r);

    testCount(0, red);

    set.add(17);

    testCount(1, red);
  }

  @Test public void testNestedExists() { paratest("para_testNestedExists"); }

  public void
  para_testNestedExists()
  {
    resetSets();
    setInts(0, 0, 0, 1);
    ControlStructure b = PQLFactory.ConjunctiveBlock(new Join[] {
        PQLFactory.Exists(PQLFactory.CONTAINS(o0r, i0w),
                 PQLFactory.EQ_Int(i0r, i1r),
                 i5r, i3r)

      });

    testCount(1, PQLFactory.Exists(PQLFactory.CONTAINS(o2r, i1w),
              b,
              i6r, i3r
              ));
            
  }

  @Test public void testNestedNotExists() { paratest("para_testNestedNotExists"); }

  public void
  para_testNestedNotExists()
  {
    resetSets();
    setInts(0, 0, 0, 1);
    ControlStructure b = PQLFactory.ConjunctiveBlock(new Join[] {
        PQLFactory.Exists(PQLFactory.CONTAINS(o0r, i0w),
                 PQLFactory.EQ_Int(i0r, i1r),
                 i4r, i3r)
      });

    testCount(0, PQLFactory.Exists(PQLFactory.CONTAINS(o1r, i1w),
              b,
              i5r, i3r
              ));
            
  }


  public static java.lang.reflect.Method
  getSumIntMethod()
  {
    try {
      return Query.class.getDeclaredMethod("sumInt", int.class, int.class);
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }

  @Test
  public void
  testSumInt()
  {
    testReductor(PQLFactory.Reductors.METHOD_ADAPTER(sumInt, i1w, i0w),
           new Object[] { 1, 1, 1, 1, 1, 1, 1, 2, 2 },
           null,
           new Object[] { 11 },
           true);
  }

  @Test
  public void
  testSumLong() throws NoSuchMethodException
  {
    testReductor(PQLFactory.Reductors.METHOD_ADAPTER(Query.class.getDeclaredMethod("sumLong", long.class, long.class), i1w, i0w),
           new Object[] { 1, 1, 1, 1, 1, 1, 1, 2, 2, 1000000000000l },
           null,
           new Object[] { (1000000000000l + 11l) },
           true);
  }

  @Test
  public void
  testSumDouble() throws NoSuchMethodException
  {
    testReductor(PQLFactory.Reductors.METHOD_ADAPTER(Query.class.getDeclaredMethod("sumDouble", double.class, double.class), i1w, i0w),
           new Object[] { 1, 1, 1, 1, 1, 1, 1, 1.75, 2 },
           null,
           new Object[] { 10.75 },
           true);
  }

  public static Set<Integer>
  setUnion(Set<Integer> s1, Set<Integer> s2)
  {
    if (s1 == null)
      return s2;
    if (s2 == null)
      return s1;
    final HashSet<Integer> retval = new HashSet<Integer>(s1);
    retval.addAll(s2);
    return retval;
  }

  @Test
  public void
  testSetUnion() throws NoSuchMethodException
  {
    final HashSet<Integer> s0 = new HashSet<Integer>();
    final HashSet<Integer> s1 = new HashSet<Integer>();
    final HashSet<Integer> s2 = new HashSet<Integer>();
    final HashSet<Integer> s3 = new HashSet<Integer>();
    final HashSet<Integer> s4 = new HashSet<Integer>();
    final HashSet<Integer> s_all = new HashSet<Integer>();

    s0.add(0);
    s1.add(1);
    s2.add(2);
    s3.add(17);
    s4.add(2);

    s_all.add(0);
    s_all.add(1);
    s_all.add(2);
    s_all.add(17);

    testReductor(PQLFactory.Reductors.METHOD_ADAPTER(ReductionTest.class.getDeclaredMethod("setUnion", Set.class, Set.class), i1w, i0w),
           new Object[] { s0, s1, s2, s3, s4 },
           null,
           new Object[] { s_all },
           true);
  }


  @Test
  public void
  testSet()
  {
    Set<Integer> resultset = new HashSet<Integer>();
    resultset.add(1);
    resultset.add(3);
    resultset.add(7);
    resultset.add(15);
    testReductor(PQLFactory.Reductors.SET(i1w, o0w),
           new Object[] { 1, 3, 7, 3, 1, 15 },
           null,
           new Object[] { resultset },
           true);
  }

  @Test
  public void
  testMapSuccess()
  {
    Map<Integer, String> resultmap = new PMap<Integer, String>();
    resultmap.put(1, "one");
    resultmap.put(7, "seven");
    resultmap.put(42, "fourty-two");
    testReductor(PQLFactory.Reductors.MAP(i1r, i2r, o0w),
           new Object[] { 1, "one",
              42, "fourty-two",
              7, "seven",
              42, "fourty-two", },
           null,
           new Object[] { resultmap },
           true);
  }

  @Test
  public void
  testMapDefault()
  {
    PDefaultMap<Integer, String> resultmap = new PDefaultMap<Integer, String>("twenty-three");
    resultmap.put(1, "one");
    resultmap.put(7, "seven");
    resultmap.put(42, "fourty-two");
    setInts(0, 0, 0, 23);
    testReductor(PQLFactory.Reductors.DEFAULT_MAP(i3r, i1r, i2r, o0w),
           new Object[] { "twenty-three" },
           new Object[] { 1, "one",
              42, "fourty-two",
              7, "seven",
              42, "fourty-two", },
           null,
           new Object[] { resultmap },
           true);
  }


  @Test
  public void
  testMapFailure()
  {
    Map<Integer, String> resultmap = new PMap<Integer, String>();
    resultmap.put(3, "three");
    resultmap.put(7, "seven");
    resultmap.put(42, "fourty-two");
    testReductor(PQLFactory.Reductors.MAP(i1r, i2r, o0w),
           new Object[] { 3, "three",
              42, "fourty-two",
              7, "seven",
              42, "fourty-two",
              3, "five" },
           null,
           new Object[] { new AmbiguousMapKeyException(new Integer(3)) },
           true);
  }

  // --------------------------------------------------------------------------------

  // int[] expected_int_array = new int[5];
  // {
  //   expected_int_array[1] = -1;
  //   expected_int_array[3] = -3;
  //   expected_int_array[4] = -4;
  // }

  // @Test
  // public void
  // testIntArraySuccess()
  // {
  //   testReductor(PQLFactory.Reductors.INT_ARRAY(i1r, i2r, o0w),
  //          new Object[] { 1, -1,
  //             4, -4,
  //             3, -3,
  //             4, -4 },
  //          null,
  //          new Object[] { expected_int_array },
  //          true);
  // }


  // @Test
  // public void
  // testIntArrayFailure()
  // {
  //   testReductor(PQLFactory.Reductors.INT_ARRAY(i1r, i2r, o0w),
  //          new Object[] { 1, -1,
  //             4, -4,
  //             3, -3,
  //             4, -4,
  //             3, 5},
  //          null,
  //          new Object[] { new AmbiguousMapKeyException(new Integer(3)) },
  //          true);
  // }


  // @Test
  // public void
  // testIntArraySizeFailure()
  // {
  //   testReductor(PQLFactory.Reductors.INT_ARRAY(i1r, i2r, o0w),
  //          new Object[] { 1, -1,
  //             4, -4,
  //             3, -3,
  //             -17, 17,
  //             4, -4 },
  //          null,
  //          new Object[] { new ArrayIndexOutOfBoundsException(-17) },
  //          true);
  // }

  // // --------------------------------------------------------------------------------

  // boolean[] expected_bool_array = new boolean[5];
  // {
  //   expected_bool_array[1] = true;
  //   expected_bool_array[3] = true;
  //   expected_bool_array[4] = false;
  // }

  // @Test
  // public void
  // testBooleanArraySuccess()
  // {
  //   testReductor(PQLFactory.Reductors.BOOLEAN_ARRAY(i1r, i2r, o0w),
  //          new Object[] { 1, true,
  //             4, false,
  //             3, true,
  //             4, false },
  //          null,
  //          new Object[] { expected_bool_array },
  //          true);
  // }


  // @Test
  // public void
  // testBooleanArrayFailure()
  // {
  //   testReductor(PQLFactory.Reductors.BOOLEAN_ARRAY(i1r, i2r, o0w),
  //          new Object[] { 1, true,
  //             4, false,
  //             3, true,
  //             4, false,
  //             3, false},
  //          null,
  //          new Object[] { new AmbiguousMapKeyException(new Integer(3)) },
  //          true);
  // }


  // @Test
  // public void
  // testBooleanArraySizeFailure()
  // {
  //   testReductor(PQLFactory.Reductors.BOOLEAN_ARRAY(i1r, i2r, o0w),
  //          new Object[] { 1, true,
  //             4, true,
  //             3, true,
  //             -17, true,
  //             4, true },
  //          null,
  //          new Object[] { new ArrayIndexOutOfBoundsException(-17) },
  //          true);
  // }

  // // --------------------------------------------------------------------------------

  // byte[] expected_byte_array = new byte[5];
  // {
  //   expected_byte_array[1] = -1;
  //   expected_byte_array[3] = -3;
  //   expected_byte_array[4] = -4;
  // }

  // @Test
  // public void
  // testByteArraySuccess()
  // {
  //   testReductor(PQLFactory.Reductors.BYTE_ARRAY(i1r, i2r, o0w),
  //          new Object[] { 1, -1,
  //             4, -4,
  //             3, -3,
  //             4, -4 },
  //          null,
  //          new Object[] { expected_byte_array },
  //          true);
  // }


  // @Test
  // public void
  // testByteArrayFailure()
  // {
  //   testReductor(PQLFactory.Reductors.BYTE_ARRAY(i1r, i2r, o0w),
  //          new Object[] { 1, -1,
  //             4, -4,
  //             3, -3,
  //             4, -4,
  //             3, 5},
  //          null,
  //          new Object[] { new AmbiguousMapKeyException(new Integer(3)) },
  //          true);
  // }


  // @Test
  // public void
  // testByteArraySizeFailure()
  // {
  //   testReductor(PQLFactory.Reductors.BYTE_ARRAY(i1r, i2r, o0w),
  //          new Object[] { 1, -1,
  //             4, -4,
  //             3, -3,
  //             -17, 17,
  //             4, -4 },
  //          null,
  //          new Object[] { new ArrayIndexOutOfBoundsException(-17) },
  //          true);
  // }

  // // --------------------------------------------------------------------------------

  // short[] expected_short_array = new short[5];
  // {
  //   expected_short_array[1] = -1;
  //   expected_short_array[3] = -3;
  //   expected_short_array[4] = -4;
  // }

  // @Test
  // public void
  // testShortArraySuccess()
  // {
  //   testReductor(PQLFactory.Reductors.SHORT_ARRAY(i1r, i2r, o0w),
  //          new Object[] { 1, -1,
  //             4, -4,
  //             3, -3,
  //             4, -4 },
  //          null,
  //          new Object[] { expected_short_array },
  //          true);
  // }


  // @Test
  // public void
  // testShortArrayFailure()
  // {
  //   testReductor(PQLFactory.Reductors.SHORT_ARRAY(i1r, i2r, o0w),
  //          new Object[] { 1, -1,
  //             4, -4,
  //             3, -3,
  //             4, -4,
  //             3, 5},
  //          null,
  //          new Object[] { new AmbiguousMapKeyException(new Integer(3)) },
  //          true);
  // }


  // @Test
  // public void
  // testShortArraySizeFailure()
  // {
  //   testReductor(PQLFactory.Reductors.SHORT_ARRAY(i1r, i2r, o0w),
  //          new Object[] { 1, -1,
  //             4, -4,
  //             3, -3,
  //             -17, 17,
  //             4, -4 },
  //          null,
  //          new Object[] { new ArrayIndexOutOfBoundsException(-17) },
  //          true);
  // }

  // // --------------------------------------------------------------------------------

  // char[] expected_char_array = new char[5];
  // {
  //   expected_char_array[1] = 'a';
  //   expected_char_array[3] = 'b';
  //   expected_char_array[4] = 'c';
  // }

  // @Test
  // public void
  // testCharArraySuccess()
  // {
  //   testReductor(PQLFactory.Reductors.CHAR_ARRAY(i1r, i2r, o0w),
  //          new Object[] { 1, 'a',
  //             4, 'c',
  //             3, 'b',
  //             4, 'c' },
  //          null,
  //          new Object[] { expected_char_array },
  //          true);
  // }


  // @Test
  // public void
  // testCharArrayFailure()
  // {
  //   testReductor(PQLFactory.Reductors.CHAR_ARRAY(i1r, i2r, o0w),
  //          new Object[] { 1, 'a',
  //             4, 'c',
  //             3, 'b',
  //             4, 'c',
  //             3, 'x'},
  //          null,
  //          new Object[] { new AmbiguousMapKeyException(new Integer(3)) },
  //          true);
  // }


  // @Test
  // public void
  // testCharArraySizeFailure()
  // {
  //   testReductor(PQLFactory.Reductors.CHAR_ARRAY(i1r, i2r, o0w),
  //          new Object[] { 1, 'a',
  //             4, 'b',
  //             3, 'c',
  //             -17, 'd',
  //             4, 'b' },
  //          null,
  //          new Object[] { new ArrayIndexOutOfBoundsException(-17) },
  //          true);
  // }

  // // --------------------------------------------------------------------------------

  // long[] expected_long_array = new long[5];
  // {
  //   expected_long_array[1] = -10000000000l;
  //   expected_long_array[3] = -30000000000l;
  //   expected_long_array[4] = -40000000000l;
  // }

  // @Test
  // public void
  // testLongArraySuccess()
  // {
  //   testReductor(PQLFactory.Reductors.LONG_ARRAY(i1r, i2r, o0w),
  //          new Object[] { 1, -10000000000l,
  //             4, -40000000000l,
  //             3, -30000000000l,
  //             4, -40000000000l },
  //          null,
  //          new Object[] { expected_long_array },
  //          true);
  // }


  // @Test
  // public void
  // testLongArrayFailure()
  // {
  //   testReductor(PQLFactory.Reductors.LONG_ARRAY(i1r, i2r, o0w),
  //          new Object[] { 1, -10000000000l,
  //             4, -40000000000l,
  //             3, -30000000000l,
  //             4, -40000000000l,
  //             3, 5l},
  //          null,
  //          new Object[] { new AmbiguousMapKeyException(new Integer(3)) },
  //          true);
  // }


  // @Test
  // public void
  // testLongArraySizeFailure()
  // {
  //   testReductor(PQLFactory.Reductors.LONG_ARRAY(i1r, i2r, o0w),
  //          new Object[] { 1, -10000000000l,
  //             4, -40000000000l,
  //             3, -30000000000l,
  //             -17, 170000000000l,
  //             4, -40000000000l },
  //          null,
  //          new Object[] { new ArrayIndexOutOfBoundsException(-17) },
  //          true);
  // }

  // // --------------------------------------------------------------------------------

  // double[] expected_double_array = new double[5];
  // {
  //   expected_double_array[1] = -1.5;
  //   expected_double_array[3] = -3.5;
  //   expected_double_array[4] = -4.5;
  // }

  // @Test
  // public void
  // testDoubleArraySuccess()
  // {
  //   testReductor(PQLFactory.Reductors.DOUBLE_ARRAY(i1r, i2r, o0w),
  //          new Object[] { 1, -1.5,
  //             4, -4.5,
  //             3, -3.5,
  //             4, -4.5 },
  //          null,
  //          new Object[] { expected_double_array },
  //          true);
  // }

  // @Test
  // public void
  // testDoubleArrayFailure()
  // {
  //   testReductor(PQLFactory.Reductors.DOUBLE_ARRAY(i1r, i2r, o0w),
  //          new Object[] { 1, -1.5,
  //             4, -4.5,
  //             3, -3.5,
  //             4, -4.5,
  //             3, 5.5},
  //          null,
  //          new Object[] { new AmbiguousMapKeyException(new Integer(3)) },
  //          true);
  // }


  // @Test
  // public void
  // testDoubleArraySizeFailure()
  // {
  //   testReductor(PQLFactory.Reductors.DOUBLE_ARRAY(i1r, i2r, o0w),
  //          new Object[] { 1, -1.5,
  //             4, -4.5,
  //             3, -3.5,
  //             -17, 17.5,
  //             4, -4.5 },
  //          null,
  //          new Object[] { new ArrayIndexOutOfBoundsException(-17) },
  //          true);
  // }

  // // --------------------------------------------------------------------------------

  // float[] expected_float_array = new float[5];
  // {
  //   expected_float_array[1] = -1.5f;
  //   expected_float_array[3] = -3.5f;
  //   expected_float_array[4] = -4.5f;
  // }

  // @Test
  // public void
  // testFloatArraySuccess()
  // {
  //   testReductor(PQLFactory.Reductors.FLOAT_ARRAY(i1r, i2r, o0w),
  //          new Object[] { 1, -1.5f,
  //             4, -4.5f,
  //             3, -3.5f,
  //             4, -4.5f },
  //          null,
  //          new Object[] { expected_float_array },
  //          true);
  // }


  // @Test
  // public void
  // testFloatArrayFailure()
  // {
  //   testReductor(PQLFactory.Reductors.FLOAT_ARRAY(i1r, i2r, o0w),
  //          new Object[] { 1, -1.5f,
  //             4, -4.5f,
  //             3, -3.5f,
  //             4, -4.5f,
  //             3, 5.5f},
  //          null,
  //          new Object[] { new AmbiguousMapKeyException(new Integer(3)) },
  //          true);
  // }


  // @Test
  // public void
  // testFloatArraySizeFailure()
  // {
  //   testReductor(PQLFactory.Reductors.FLOAT_ARRAY(i1r, i2r, o0w),
  //          new Object[] { 1, -1.5f,
  //             4, -4.5f,
  //             3, -3.5f,
  //             -17, 17.5f,
  //             4, -4.5f },
  //          null,
  //          new Object[] { new ArrayIndexOutOfBoundsException(-17) },
  //          true);
  // }

  // // --------------------------------------------------------------------------------

  // final Object obj1 = new Integer(42);
  // final Object obj3 = new String("foo");
  // final Object obj4 = new int[2];

  // Object[] expected_object_array = new Object[5];
  // {
  //   expected_object_array[1] = obj1;
  //   expected_object_array[3] = obj3;
  //   expected_object_array[4] = obj4;
  // }

  // @Test
  // public void
  // testObjectArraySuccess()
  // {
  //   testReductor(PQLFactory.Reductors.OBJECT_ARRAY(i1r, i2r, o0w),
  //          new Object[] { 1, obj1,
  //             4, obj4,
  //             3, obj3,
  //             4, obj4 },
  //          null,
  //          new Object[] { expected_object_array },
  //          true);
  // }


  // @Test
  // public void
  // testObjectArrayFailure()
  // {
  //   testReductor(PQLFactory.Reductors.OBJECT_ARRAY(i1r, i2r, o0w),
  //          new Object[] { 1, obj1,
  //             4, obj4,
  //             3, obj3,
  //             4, new Integer(2),
  //             3, obj3},
  //          null,
  //          new Object[] { new AmbiguousMapKeyException(new Integer(4)) },
  //          true);
  // }


  // @Test
  // public void
  // testObjectArraySizeFailure()
  // {
  //   testReductor(PQLFactory.Reductors.OBJECT_ARRAY(i1r, i2r, o0w),
  //          new Object[] { 1, obj1,
  //             4, obj4,
  //             3, obj3,
  //             -17, obj1,
  //             4, obj4 },
  //          null,
  //          new Object[] { new ArrayIndexOutOfBoundsException(-17) },
  //          true);
  // }

  // --------------------------------------------------------------------------------

  // @Test
  // public void
  // testReductionAPI()
  // {
  //   Reductor reductor1 = PQLFactory.Reductors.DOUBLE_ARRAY(i1r, i2r, o0w);
  //   Reduction red = PQLFactory.Reduction(reductor1,
  //             PQLFactory.LT_Int(i0r, i1r),
  //             PQLFactory.LT_Int(i0r, i1r)
  //             );

  //   checkAPI(red,
  //      2, 3, new int[] { i1r, i2r, o0w });
  // }


  @Test
  public void
  testForallManifestTrue()
  {
    testReductor(PQLFactory.Reductors.FORALL(i1w, i0w),
           new Object[] { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
           null,
           new Object[] { 1 },
           true);
  }


  @Test
  public void
  testForallManifestFalse0()
  {
    testReductor(PQLFactory.Reductors.FORALL(i1w, i0w),
           new Object[] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 },
           null,
           new Object[] { 0 },
           true);
  }


  @Test
  public void
  testForallManifestFalse1()
  {
    testReductor(PQLFactory.Reductors.FORALL(i1w, i0w),
           new Object[] { 1, 1, 1, 1, 0, 1, 1, 1, 1, 1 },
           null,
           new Object[] { 0 },
           true);
  }


  @Test
  public void
  testForallManifestFalse2()
  {
    testReductor(PQLFactory.Reductors.FORALL(i1w, i0w),
           new Object[] { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
           null,
           new Object[] { 0 },
           true);
  }


  @Test
  public void
  testExistsManifestFalse()
  {
    testReductor(PQLFactory.Reductors.EXISTS(i1w, i0w),
           new Object[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
           null,
           new Object[] { 0 },
           true);
  }


  @Test
  public void
  testExistsManifestTrue0()
  {
    testReductor(PQLFactory.Reductors.EXISTS(i1w, i0w),
           new Object[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
           null,
           new Object[] { 1 },
           true);
  }


  @Test
  public void
  testExistsManifestTrue1()
  {
    testReductor(PQLFactory.Reductors.EXISTS(i1w, i0w),
           new Object[] { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
           null,
           new Object[] { 1 },
           true);
  }


  @Test
  public void
  testExistsManifestTrue2()
  {
    testReductor(PQLFactory.Reductors.EXISTS(i1w, i0w),
           new Object[] { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
           null,
           new Object[] { 1 },
           true);
  }


  // --------------------------------------------------------------------------------
  // Fused

  @Test
  public void
  testFusedReductionAPI()
  {
    Reductor reductor1 = PQLFactory.Reductors.MAP(i0r, l0r, o0w);
    Reductor reductor2 = PQLFactory.Reductors.MAP(i1r, l1r, o1w);
    Reductor reductor3 = PQLFactory.Reductors.MAP(i2r, l2r, o2w);
    Reduction red = PQLFactory.Reduction(reductor1,
              PQLFactory.LT_Int(i0r, i1r),
              PQLFactory.LT_Int(i0r, i1r)
              );
    checkAPI(red,
       2, 3, new int[] { i0r, l0r, o0w });
    red.addReductor(reductor2);

    checkAPI(red,
       4, 6, new int[] { i0r, l0r, i1r, l1r, o0w, o1w });
    red.addReductor(reductor3);

    checkAPI(red,
       6, 9, new int[] { i0r, l0r, i1r, l1r, i2r, l2r, o0w, o1w, o2w });
  }

  @Test public void testFusedSetMap() { paratest("para_testFusedSetMap"); }

  public void
  para_testFusedSetMap() // compute set and array at same time
  {
    int[] int_array = new int[] { 3, 5, 7, 9 };
    Map<Integer, Integer> int_map = new PMap<Integer, Integer>();
    for (int k = 0; k < int_array.length; k++)
      int_map.put(k, int_array[k]);
    Set<Integer> set = new HashSet<Integer>();
    set.add(2);
    set.add(4);
    set.add(6);
    set.add(8);

    setLongs(0l, 3l, 0l);
    setInts(2, 1, 0);

    Join generator = PQLFactory.INT_RANGE_CONTAINS(l0r, l1r, i5w);
    ControlStructure computer = PQLFactory.ConjunctiveBlock(new Join[] {
        PQLFactory.MUL_Int(i5r, i0r, i2w),
        PQLFactory.ADD_Int(i2r, i0r, i3w),
        PQLFactory.ADD_Int(i3r, i1r, i4w),
      });

    Reductor r1 = PQLFactory.Reductors.MAP(i5r, i4r, o0w);
    Reductor r2 = PQLFactory.Reductors.SET(i3r, o1w);

    Reduction red = PQLFactory.Reduction(r1,
              generator,
              computer);
    red.addReductor(r2);

    testCount(1, red);

    check_equal(int_map, env.getObject(o0r));
    check_equal(set, env.getObject(o1r));
  }

  @Test public void testFusedTruthMap() { paratest("para_testFusedTruthMap"); }

  public void
  para_testFusedTruthMap() // compute map and truth value at same time
  {
    Map<Long, Integer> map = new PMap<Long, Integer>();
    map.put(0l, 1);
    map.put(1l, 2);
    map.put(2l, 3);
    map.put(3l, 4);

    setLongs(0l, 3l, 0l);
    setInts(0, 1, 0);

    Join generator = PQLFactory.INT_RANGE_CONTAINS(l0r, l1r, l2w);
    ControlStructure computer = PQLFactory.ConjunctiveBlock(new Join[] {
        PQLFactory.ADD_Int(l2r, i1r, i4w),
        PQLFactory.Bool(PQLFactory.LT_Int(i0r, i4r),
           i2w)
      });

    Reductor r1 = PQLFactory.Reductors.FORALL(i2r, i3w);
    Reductor r2 = PQLFactory.Reductors.MAP(l2r, i4r, o0w);

    Reduction red = PQLFactory.Reduction(r1,
              generator,
              computer);
    red.addReductor(r2);

    testCount(1, red);

    check_equal(map, env.getObject(o0r));
    check_equal(1, env.getInt(i3r));
  }

  public void
  testFusedTruthCheck(int index_base, int contents_base,
          int expected_lhs, int expected_rhs)
  {
    int[] source = new int[] { 1, 2, 3, 4, 5 };
    setObjects(source, null, null);

    setLongs(index_base, contents_base, 0l);

    Join generator = PQLFactory.ARRAY_LOOKUP_Int(o0r, i0w, i1w);
    ControlStructure computer = PQLFactory.ConjunctiveBlock(new Join[] {
        PQLFactory.Bool(PQLFactory.LT_Int(l0r, i0r),
           i2w),
        PQLFactory.Bool(PQLFactory.LT_Int(l1r, i1r),
           i3w)
      });

    Reductor r1 = PQLFactory.Reductors.FORALL(i2r, i4w);
    Reductor r2 = PQLFactory.Reductors.FORALL(i3r, i5w);

    Reduction red = PQLFactory.Reduction(r1,
              generator,
              computer);
    red.addReductor(r2);

    testCount(1, red);
    check_equal(expected_lhs, env.getInt(i4r));
    check_equal(expected_rhs, env.getInt(i5r));
  }



  @Test public void testFusedTruthTruthSuccess() { paratest("para_testFusedTruthTruthSuccess"); }

  public void
  para_testFusedTruthTruthSuccess() // compute two truth values at same time, left failing
  {
    testFusedTruthCheck(-1, 0,
            1, // all indices will be > -1
            1);// all contents will be > 0
  }

  @Test public void testFusedTruthTruthLFail() { paratest("para_testFusedTruthTruthLFail"); }

  public void
  para_testFusedTruthTruthLFail() // compute two truth values at same time, left failing
  {
    testFusedTruthCheck(0, 0,
            0, // one index will be zero, i.e., not > 0
            1);// all contents will be > 0
  }

  @Test public void testFusedTruthTruthRFail() { paratest("para_testFusedTruthTruthRFail"); }

  public void
  para_testFusedTruthTruthRFail() // compute two truth values at same time, left failing
  {
    testFusedTruthCheck(-1, 1,
            1,
            0);
  }

  @Test public void testFusedTruthTruthLRFail() { paratest("para_testFusedTruthTruthLRFail"); }

  public void
  para_testFusedTruthTruthLRFail() // compute two truth values at same time, left failing
  {
    testFusedTruthCheck(0, 1,
            0,
            0);
  }


  // --------------------------------------------------------------------------------

  public void
  testReductor(Reductor reductor,
         Object[] values,
         boolean[] successes,
         Object[] expected,
         boolean expected_success)
  {
    testReductor(reductor, null, values, successes, expected, expected_success);
  }

  public void
  testReductor(Reductor reductor,
         Object[] outer_values,
         Object[] values,
         boolean[] successes,
         Object[] expected,
         boolean expected_success)
  {
    if (reductor.getInnerReductor() == null
        && !reductor.isMethodAdapter())
      checkFactory(reductor, PQLFactory.Gen.REDUCTOR_FACTORY_CLASS, reductor.getName());
    (new ReductorTest(reductor, outer_values, values, successes, expected, expected_success)).test();
  }

  public static void
  check_equal(Object lhs, Object rhs)
  {
    if (lhs == null) {
      assertNull(rhs);
      return;
    } else if (rhs == null)
      fail();

    assertEquals(lhs.getClass().isArray(),
           rhs.getClass().isArray());

    if (lhs.getClass().isArray()) {
      assertEquals(Array.getLength(lhs),
             Array.getLength(rhs));
      for (int j = 0; j < Array.getLength(lhs); j++)
        check_equal(Array.get(lhs, j),
              Array.get(rhs, j));
    } else {
      // if (lhs instanceof Set
      //     && rhs instanceof Set) {
      //   Set l = (Set) lhs;
      //   Set r = (Set) rhs;
      //   assertTrue(l.containsAll(r));
      //   assertTrue(r.containsAll(l));
      // } else if (lhs instanceof Map
      //      && rhs instanceof Map) {
      //   Map l = (Map) lhs;
      //   Map r = (Map) rhs;
      //   Set l_keys = l.keySet();
      //   Set r_keys = r.keySet();
      //   assertTrue(l_keys.containsAll(r_keys));
      //   assertTrue(r_keys.containsAll(l_keys));
      //   for (Object k : l_keys)
      //     assertEquals(l.get(k),
      //            r.get(k));
      // } else
        assertEquals(lhs, rhs);
    }
  }

  private class ReductorTest
  {
    Reductor reductor;
    Object[] outer_inputs;
    Object[] inputs;
    boolean[] successes;
    Object[] expected;
    boolean expected_success;
    int read_delta; // number of input entries to set up for each reductor test
    int read_offset_start; // start offset of the first input entry (same as getOuterReadArgsNr())

    public ReductorTest(Reductor reductor,
            Object[] outer_values,
            Object[] values,
            boolean[] successes,
            Object[] expected,
            boolean expected_success)
    {
      this.outer_inputs = outer_values;
      this.inputs = values;
      this.reductor = reductor;
      this.successes = successes;
      this.expected_success = expected_success;
      this.expected = expected;

      this.read_delta = reductor.getInnerReadArgsNr();
      this.read_offset_start = reductor.getOuterReadArgsNr();
    }

    public void
    test()
    {
      assertTrue(reductor.getArgsNr() >= 0);
      assertTrue(reductor.getInnerReadArgsNr() >= 0);
      assertTrue(reductor.getOuterReadArgsNr() >= 0);
      assertTrue(reductor.getOuterReadArgsNr() <= reductor.getReadArgsNr());
      assertTrue(reductor.getReadArgsNr() <= reductor.getReadArgsNr());
      assertEquals(reductor.getOuterReadArgsNr(), this.outer_inputs == null ? 0 : this.outer_inputs.length);

      if (this.successes == null
          && this.inputs == null)
        throw new RuntimeException("Forgot to specify expected results");

      for (int i = 0; i < reductor.getArgsNr(); i++) {
        reductor.setArg(i, i0r);
        assertEquals(i0r, reductor.getArg(i));
        reductor.setArg(i, o1w);
        assertEquals(o1w, reductor.getArg(i));
      }

      int max_size;
      if (successes != null)
        max_size = successes.length + 2;
      else
        max_size = inputs.length + 1;

      for (int i = 0; i < reductor.getOuterReadArgsNr(); i++) {
        final int register = Env.encodeReadVar(VarConstants.TYPE_OBJECT, i);
        reductor.setArg(i, register);
        env.setObject(register, this.outer_inputs[i]);

      }

      for (int i = 1; i < max_size; i++) {
//        System.err.println("alpha:" + i);
        try {
          this.testReductorCountSliced(i);
        } catch (Exception emk) {
          check_exn_result(emk);
        }
//        System.err.println("bravo:" + i);
        try {
          this.testReductorCountChunked(i);
        } catch (Exception emk) {
          check_exn_result(emk);
        }
      }
    }

    private void
    check_exn_result(Exception e)
    {
      assertEquals(1, this.expected.length);
      if (this.expected[0] instanceof ArrayIndexOutOfBoundsException)
        assertTrue(e instanceof ArrayIndexOutOfBoundsException); // unfortunately we can't rely on the exact message
      else {
        try {
          assertEquals(this.expected[0], e);
        } catch (Throwable t) {
          if (t instanceof Exception) {
            System.err.println("\nUnexpected exception:");
            t.printStackTrace();
          }
          throw new RuntimeException(t);
        }
      }
    }

    private void
    check_result(Reductor reductor, boolean succeeded)
    {
      final int first_write_var = reductor.getReadArgsNr();
      assertEquals(expected_success, succeeded);

      if (expected != null) {
        for (int i = 0; i < expected.length; i++) {
          Object actual_result =
            env.getObject(Env.encodeReadVar(VarConstants.TYPE_OBJECT,
                    i + first_write_var));
          check_equal(expected[i], actual_result);
        }
      }
    }

    public void
    testReductorCountSliced(int reductors_nr)
    {
      final Reductor main_reductor = reductor;
      boolean success = true;
      main_reductor.setup(env);

      // set up input variables
      for (int i = reductor.getOuterReadArgsNr(); i < reductor.getReadArgsNr(); i++)
        reductor.setArg(i, Env.encodeReadVar(VarConstants.TYPE_OBJECT, i));
      for (int i = reductor.getReadArgsNr(); i < reductor.getArgsNr(); i++)
        reductor.setArg(i, Env.encodeWriteVar(VarConstants.TYPE_OBJECT, i));

      for (int reductor_index = 0; reductor_index < reductors_nr; reductor_index++) {
        final Reductor clone_reductor = reductor.copy();

        clone_reductor.setup(env);

        int inputs_index = this.read_delta * reductor_index;
        int success_index = reductor_index;

        // For each feasible value
        while (((this.inputs == null) || inputs_index + this.read_delta <= this.inputs.length)
               && ((this.successes == null) || success_index < this.successes.length)) {

          // Set up input values, if needed
          for (int j = 0; j < this.read_delta; j++)
            env.setObject(Env.encodeWriteVar(VarConstants.TYPE_OBJECT, j + this.read_offset_start),
                    this.inputs[j + inputs_index]);

          if (this.successes == null
              || this.successes[success_index]) {
            if (clone_reductor.succeed(env))
              break;
          }

          // march forward, skipping entries processed by other reductor instances
          success_index += reductors_nr;
          inputs_index += this.read_delta * reductors_nr;
        }

        if (reductors_nr == 1) {
          success = clone_reductor.eval(env);
          check_result(clone_reductor, success);
        }

        if (reductors_nr > 1)
          main_reductor.absorbAggregate(clone_reductor.getAggregate());
      }

      if (reductors_nr > 1)
        check_result(main_reductor, main_reductor.eval(env));
    }

    public void
    testReductorCountChunked(int reductors_nr)
    {
      final Reductor main_reductor = reductor;
      main_reductor.setup(env);

      // set up input variables
      for (int i = reductor.getOuterReadArgsNr(); i < reductor.getReadArgsNr(); i++)
        reductor.setArg(i, Env.encodeReadVar(VarConstants.TYPE_OBJECT, i));
      for (int i = reductor.getReadArgsNr(); i < reductor.getArgsNr(); i++)
        reductor.setArg(i, Env.encodeWriteVar(VarConstants.TYPE_OBJECT, i));

      Reductor[] clone_reductors = new Reductor[reductors_nr];
      for (int i = 0; i < reductors_nr; i++)
        clone_reductors[i] = main_reductor.copy();
      boolean[] clone_aborts = new boolean[reductors_nr];
      for (int i = 0; i < reductors_nr; i++)
        clone_aborts[i] = false;

      int inputs_index = 0;
      int success_index = 0;
      int clone_nr = 0;

      while (((this.inputs == null) || inputs_index + this.read_delta <= this.inputs.length)
             && ((this.successes == null) || success_index < this.successes.length)) {

        final Reductor clone_reductor = clone_reductors[clone_nr];

        if (!clone_aborts[clone_nr]) {

          // Set up input values, if needed
          for (int j = 0; j < this.read_delta; j++)
            env.setObject(Env.encodeWriteVar(VarConstants.TYPE_OBJECT, j + this.read_offset_start),
                    this.inputs[j + inputs_index]);

          if (this.successes == null
              || this.successes[success_index]) {
            if (clone_reductor.succeed(env))
              clone_aborts[clone_nr] = true;
          }
        }

        // march forward, skipping entries processed by other reductor instances
        success_index += 1;
        inputs_index += this.read_delta;
        clone_nr = (clone_nr + 1) % reductors_nr;
      }

      // first, merge all odds to their preceding evens
      for (int i = 1; i < reductors_nr; i += 2)
        clone_reductors[i-1].absorbAggregate(clone_reductors[i].getAggregate());

      // Now, sum up:
      for (int i = 2; i < reductors_nr; i += 2)
        clone_reductors[0].absorbAggregate(clone_reductors[i].getAggregate());

      final boolean success = clone_reductors[0].eval(env);

      check_result(clone_reductors[0], success);
    }
  }

}
TOP

Related Classes of edu.umass.pql.ReductionTest$ReductorTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.