Rick

Rick
Rick

Monday, February 24, 2014

Boon News 0.11 is out

News in Boon

Boon 0.11 is out. Thanks Stephane Landelle! Boon JSON parser still faster than GSON and Jackson. Up to 3x faster.
Added lightweight JSON DI container that supports @Inject, @PostConstruct, @Required, @Autowire, and more.
public class CoffeeApp implements Runnable {
    @Inject
    CoffeeMaker coffeeMaker;
    @Inject
    Coffee coffee;
    @Inject
    Sugar sugar;
    @Inject
    Bacon bacon;
    @Inject
    @Named( "brown" )
    Bacon brownBacon;
JSON support now support @JsonProperty, @JsonView, and more. Learn more here: http://rick-hightower.blogspot.com/2014/01/boon-json-in-five-minutes-faster-json.html
Wrote invoker library to work JSON posts. It is a better way to do REST and WebSocket with Boon.
Wrote functional library based on work that I did with EasyJava.
You can do reflection based filters or regular Predicate filters.
        List<Employee> list = list( new Employee("Bob"), new Employee("Sally") );
        setListProperty( list, "salary", 200 );
        list.addAll(Lists.list(new Employee("Rick"), new Employee("Joe")));

        //Reflection
        List<Employee> filtered = filterBy(list, new Object() {
            boolean t(Employee e) { return e.salary>150; }
        });


        ...

         //Predicate based
         List<Employee> filtered = filterBy(list, new Predicate<Employee>() {
                    @Override
                    public boolean test(Employee input) {
                        return input.salary > 150;
                    }
         });

My goal is take some previous work that I did with invoke dynamic and make the reflection based predicate faster than the Predicate interface.
You can also filter with static or non-static methods
        List<Employee> filtered = filterBy(list, ListsTest.class, "filterBySalary");
        ...

        List<Employee> filtered = filterBy(list, this, "filterBySalaryMethod");
Also don't forget that Boon ships with a full in-memory query engine that is actually faster than the predicate based filters.
      List<Employee> filtered = query( list, gt("salary", 150) );
Learn more about the Boon data repo here:
But I digress back to functional framework:
The usual suspects are here:
        ...

        //Reflection Mapper -- Convert Employee object into HRObject
        List<HRObject> wrap = (List<HRObject>) mapBy(list, new Object() {
           HRObject hr(Employee e) {return new HRObject(e);}
        });

        ...
        //Reflection static or non-static methods
        List<HRObject> wrap = (List<HRObject>) mapBy(list, ListsTest.class, "createHRO" );

        List<HRObject> wrap = (List<HRObject>) mapBy(list, this, "createHROMethod" );

        ...
        //Constructor mapping
        List<Employee> list = list(new Employee("Bob"), new Employee("Sally"));
        List<HRObject> wrap = wrap(HRObject.class, list);
        ...


        //
        List<Employee> list =  list(  new Employee("Bob"), new Employee("Sally"));
        List<HRObject> wrap =  mapBy( list, new Function<Employee, HRObject>() {
            @Override
            public HRObject apply(Employee employee) {
                return new HRObject(employee);
            }
        });


Here is one you don't see much:
    @Test
    public void reduce() {
      long sum =  (int) reduceBy(Lists.list(1,2,3,4,5,6,7,8), new Object() {
          int sum(int s, int b) {return s+b;}
      });

      boolean ok = sum == 36 || die();
      puts (sum);



      sum =  (long) reduceBy(new Integer[]{1,2,3,4,5,6,7,8}, new Object() {
            long sum(long s, int b) {return s+b;}
      });

      ok &= sum == 36 || die();



      sum =  (long) reduceBy(new int[]{1,2,3,4,5,6,7,8}, new Object() {
            long sum(long s, int b) {return s+b;}
      });

      ok &= sum == 36 || die();


       sum =   (long) reduceBy(Lists.list(1,2,3,4,5,6,7,8), new Reducer<Integer, Integer>() {
            @Override
            public Integer apply(Integer sum, Integer v) {
                return sum == null ? v : sum + v;
            }
        }).longValue();


    }

EasyJava had currying and all sorts of wild stuff, so I might port some of that here. I might not. Let me know.
String Parsing.... Boon has really fast String parsing about 2x speed what you could do with JDK readily, and a smaller GC foot print so instead of this:
    static Pattern newLine = Pattern.compile("(\n|\r)");
    ...
        int i=0;
        String[] splitLines = newLine.split(str);
        String[] stats;

        for (String line : splitLines) {
            stats = line.split( ",");
            i += Integer.parseInt(stats[1]);
        }
        return i;
You can do this (for 2x speed and a lot less GC overhead):
        int i=0;
        String[] splitLines = splitLines(str);
        String[] stats;

        for (String line : splitLines) {
            stats = splitComma(line);
            i += Integer.parseInt(stats[1]);
        }
        return i;
Or even this (2.5x faster and even less GC overhead):
        char[] chars = toCharArray(csv);
        int i=0;
        char[][] splitLines = splitLines(chars);
        char[][] stats;

        for (char[] line : splitLines) {
            stats = splitComma(line);
            i += parseInt(stats[1]);
        }
        return i;
Boon is not just fast. Boon is a flame throwing, turbo-charged, get-out-of-the-way-I-am-coming-in, speed-demon that sips GC, and makes CPUs and virtual cores wish they went into dentistry.


Friday, February 21, 2014

Added respondsTo, invoke from Ruby to Java (via Boon), and added Go Programming style interface support, and dynamic JSON, list, map marshaling


Wrote some code to speed up injection container construction and then went ahead and wrote some code to speed up the toList biz. Then wrote some additional code to speed up dynamic invoke

Then I've always wanted to add some nice reflection utilities to easily invoke/marshal to Java objects.  I wrote a Ruby style respondsTo method (cached methods, should be fairly fast). I also added JSON, List, and Map marshaling to Java method calls. 

The respondsTo works with no args, class as args parameter types and objects as arguments. 

Then on top of respondsTo I wrote Go Programming style interface support so you can have an interface and as long as you support all the methods in that interface, you object does not have to implement it. This is so you don't have to have 100 jar file dependencies for design by interface. Read up on Go Programming to see what I am talking about because I am not giving it justice. 

Considering writing a respondsTo that works with JSON, maps and lists like the Invoker/Marshaler (seen at bottom of this post). I am also considering adding the ability for invoke to calling   missingMethod(String methodName, Object... args):Object if the method can't be found and there is a missingMethod defined in the instance. :)

Please take a look at the Ruby style respondsTo in Java.


Added Ruby style respondsTo to Java

We can invoke methods if they are supported. (Duck typing in Java)
        FileObject file = new FileObject();
        StringReaderThing reader = new StringReaderThing(lines("Hi mom", "how are you?"));
        List<Object> list = list(file, reader);


        for (Object object : list) {
            if ( respondsTo(object, "open", String.class) ) invoke(object, "open", "hi");

            if ( respondsTo(object, "add", int.class, int.class) ) puts ("add", invoke(object, "add", 1, 2));

            if ( respondsTo(object, "readLine") ) puts ( invoke(object, "readLine") );

            if ( respondsTo(object, "readLine") ) puts ( invoke(object, "readLine") );

            if ( respondsTo(object, "close" ) ) invoke(object, "close");
        }

The above invokes openaddreadLine and close methods if they are found. Above we pass types to see if there is a match. You don't have to pass types, respondsTo can also just check to see if the method exists. The invoke operation should be fairly fast in a tight loop.
You have the option of invoking by argument type match without passing around types (classes) as follows:
        FileObject file = new FileObject();
        StringReaderThing reader = new StringReaderThing(lines("Hi mom", "how are you?"));
        List<Object> list = list(file, reader);


        for (Object object : list) {
            if (respondsTo(object, "open", "hi") ) invoke(object, "open", "hi");

            if (respondsTo(object, "add", 1, 2) ) puts ("add", invoke(object, "add", 1, 2));


            if (respondsTo(object, "readLine") ) puts ( invoke(object, "readLine") );

            if (respondsTo(object, "readLine") ) puts ( invoke(object, "readLine") );

            if (respondsTo(object, "close" ) ) invoke(object, "close");
        }
You can also invoke with a java.util.List (invoke and respondsTo take var-arg Object... by default for arguments) as follows:
        FileObject file = new FileObject();
        StringReaderThing reader = new StringReaderThing(lines("Hi mom", "how are you?"));
        List<Object> list = list(file, reader);



        List <?> openList = list("hi");
        List <?> addList = list(1, 2);

        for (Object object : list) {
            if (respondsTo(object, "open", openList) ) invoke(object, "open", openList);

            if (respondsTo(object, "add", addList) ) puts ("add", invoke(object, "add", addList));


            if (respondsTo(object, "readLine") ) puts ( invoke(object, "readLine") );

            if (respondsTo(object, "readLine") ) puts ( invoke(object, "readLine") );

            if (respondsTo(object, "close" ) ) invoke(object, "close");
        }

        boolean ok = file.closeCalled && file.readLine && file.openCalled && file.addCalled || die();


I also added the ability to invoke by interface. This is a loosely typed interface concept like the Go Programming language in that the class does not have to implement the interface. It only has to implement the methods in the interface. This allows loosely coupled (no jar dependencies) contracts like Go, or so I hope.
        FileObject file = new FileObject();
        StringReaderThing reader = new StringReaderThing(lines("Hi mom", "how are you?"));
        List<Object> list = list(file, reader);



        List <?> openList = list("hi");
        List <?> addList = list(1, 2);

        for (Object object : list) {
            if ( handles(object, FileInterface.class) ) invoke(object, "open", openList);

            if ( respondsTo(object, "add", addList) ) puts ("add", invoke(object, "add", addList));


            if ( handles(object, FileInterface.class) ) {
                puts ( invoke(object, "readLine") );
                puts ( invoke(object, "readLine") );
                invoke(object, "close");
            }
        }


Here is the complete code listing for handles and respondsTo:
package org.boon.core.reflection;


import org.junit.Test;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.util.List;

import static org.boon.Boon.puts;
import static org.boon.Exceptions.die;
import static org.boon.Lists.list;
import static org.boon.Str.lines;
import static org.boon.core.reflection.Reflection.handles;
import static org.boon.core.reflection.Reflection.invoke;
import static org.boon.core.reflection.Reflection.respondsTo;

public class RespondsTo {

    public static interface FileInterface {
        void open(String fileName);

        String readLine();

        void close();
    }


    public static class FileObject {

        boolean readLine;
        boolean openCalled;
        boolean closeCalled;

        boolean addCalled;

        public void open(String fileName) {

            openCalled = true;
            puts("Open ", fileName);
        }

        public String readLine() {
            readLine = true;
            return "read line";
        }

        public int add(int i, int f) {
           addCalled = true;
           return i + f;
        }

        public void close() {
            closeCalled = true;
        }


    }

    public static class StringReaderThing {

        BufferedReader reader = null;

        String contents;

        public StringReaderThing(String contents) {
            this.contents = contents;
        }

        public void open(String fileName) {

            reader = new BufferedReader(new StringReader(contents));

        }

        public String readLine() throws IOException {
            return reader.readLine();
        }

        public void close() throws IOException {
            reader.close();
        }

    }



    @Test
    public void test() {
        FileObject file = new FileObject();
        StringReaderThing reader = new StringReaderThing(lines("Hi mom", "how are you?"));
        List<Object> list = list(file, reader);


        for (Object object : list) {
            if ( respondsTo(object, "open", String.class) ) invoke(object, "open", "hi");

            if ( respondsTo(object, "add", int.class, int.class) ) puts ("add", invoke(object, "add", 1, 2));

            if ( respondsTo(object, "readLine") ) puts ( invoke(object, "readLine") );

            if ( respondsTo(object, "readLine") ) puts ( invoke(object, "readLine") );

            if ( respondsTo(object, "close" ) ) invoke(object, "close");
        }

        boolean ok = file.closeCalled && file.readLine && file.openCalled && file.addCalled || die();


    }



    @Test
    public void testInvoke() {
        FileObject file = new FileObject();
        StringReaderThing reader = new StringReaderThing(lines("Hi mom", "how are you?"));
        List<Object> list = list(file, reader);


        for (Object object : list) {
            if (respondsTo(object, "open", "hi") ) invoke(object, "open", "hi");

            if (respondsTo(object, "add", 1, 2) ) puts ("add", invoke(object, "add", 1, 2));


            if (respondsTo(object, "readLine") ) puts ( invoke(object, "readLine") );

            if (respondsTo(object, "readLine") ) puts ( invoke(object, "readLine") );

            if (respondsTo(object, "close" ) ) invoke(object, "close");
        }

        boolean ok = file.closeCalled && file.readLine && file.openCalled && file.addCalled || die();



    }


    @Test
    public void testInvokeByList() {
        FileObject file = new FileObject();
        StringReaderThing reader = new StringReaderThing(lines("Hi mom", "how are you?"));
        List<Object> list = list(file, reader);



        List <?> openList = list("hi");
        List <?> addList = list(1, 2);

        for (Object object : list) {
            if (respondsTo(object, "open", openList) ) invoke(object, "open", openList);

            if (respondsTo(object, "add", addList) ) puts ("add", invoke(object, "add", addList));


            if (respondsTo(object, "readLine") ) puts ( invoke(object, "readLine") );

            if (respondsTo(object, "readLine") ) puts ( invoke(object, "readLine") );

            if (respondsTo(object, "close" ) ) invoke(object, "close");
        }

        boolean ok = file.closeCalled && file.readLine && file.openCalled && file.addCalled || die();



    }



    @Test
    public void testHandles() {
        FileObject file = new FileObject();
        StringReaderThing reader = new StringReaderThing(lines("Hi mom", "how are you?"));
        List<Object> list = list(file, reader);



        List <?> openList = list("hi");
        List <?> addList = list(1, 2);

        for (Object object : list) {
            if ( handles(object, FileInterface.class) ) invoke(object, "open", openList);

            if ( respondsTo(object, "add", addList) ) puts ("add", invoke(object, "add", addList));


            if ( handles(object, FileInterface.class) ) {
                puts ( invoke(object, "readLine") );
                puts ( invoke(object, "readLine") );
                invoke(object, "close");
            }
        }

        boolean ok = file.closeCalled && file.readLine && file.openCalled && file.addCalled || die();



    }
}

Dynamic invocation via list, map, Json Map, and Json List

I added the ability to dynamic dispatch to a method from a map or list or JSON. This is important for REST, Websocket, Service and JSON messaging.
Take a look and see if you can figure out where I am going, then let me know because sometimes I forget.
package org.boon.core.reflection;

import org.boon.Lists;
import org.boon.Maps;
import org.junit.Test;

import javax.annotation.PostConstruct;


import static org.boon.Boon.puts;
import static org.boon.Boon.sputs;
import static org.boon.Exceptions.die;

/**
 * Created by Richard on 2/17/14.
 */
public class InvokerTest {


    public static class HelloWorldArg  {
         int i = 0;
         String hello = "null";

        public HelloWorldArg( int i ) {
            this.i = i;
        }

        public HelloWorldArg( int i, String hello ) {
            this.i = i;
            this.hello = hello;
        }


        public HelloWorldArg(  String hello ) {
            this.hello = hello;
        }

        @Override
        public boolean equals( Object o ) {
            if ( this == o ) return true;
            if ( o == null || getClass() != o.getClass() ) return false;

            HelloWorldArg that = ( HelloWorldArg ) o;

            if ( i != that.i ) return false;
            if ( hello != null ? !hello.equals( that.hello ) : that.hello != null ) return false;

            return true;
        }



        @Override
        public int hashCode() {
            int result = i;
            result = 31 * result + ( hello != null ? hello.hashCode() : 0 );
            return result;
        }
    }

    public static class HelloWorld  {

        boolean initCalled;

        boolean called1st;
        boolean called2nd;



        private HelloWorldArg sayArg(HelloWorldArg hi, int i) {
            return hi;
        }



        private HelloWorldArg sayArg2 (HelloWorldArg hi) {
            return hi;
        }

        private void sayHi(String hi) {
            puts ( "hi ", hi );

        }



        private String say(String hi, int i) {
            return sputs( "hi ", hi, i );

        }



        private void sayHi2(String hi) {
            called1st = true;
            puts ( "hi ", hi );

        }

        private void sayHi2(String hi, int i) {
            called2nd = true;

            puts ( "hi ", hi );

        }


        @PostConstruct
        private void init() {
            initCalled = true;

        }



    }

    @Test
    public void test() {
        Invoker.invoke( new HelloWorld(), "sayHi", "Rick" );
    }



    @Test
    public void testPostConstruct() {
        HelloWorld hw = new HelloWorld();
        hw.initCalled = false;
        Invoker.invokeMethodWithAnnotationNoReturn( hw, "postConstruct" );
        if (!hw.initCalled) {
            die("Post construct not called");
        }
    }


    @Test
    public void testPostConstruct2() {
        HelloWorld hw = new HelloWorld();
        hw.initCalled = false;
        Invoker.invokeMethodWithAnnotationNoReturn( hw, "PostConstruct" );
        if (!hw.initCalled) {
            die("Post construct not called");
        }
    }


    @Test
    public void testPostConstruct3() {
        HelloWorld hw = new HelloWorld();
        hw.initCalled = false;
        Invoker.invokeMethodWithAnnotationNoReturn( hw, "javax.annotation.PostConstruct" );
        if (!hw.initCalled) {
            die("Post construct not called");
        }
    }


    @Test
    public void testNoOverloads() {
        try {
            Invoker.invoke( new HelloWorld(), "sayHi2", "Rick" );
            die("can't get this far");
        } catch (Exception ex) {

        }
    }




    @Test
    public void testAllowOverloads() {
        HelloWorld hw = new HelloWorld();
        hw.called1st = false;
        hw.called2nd = false;

        Invoker.invokeOverloaded( hw, "sayHi2", "Rick" );

        if ((!hw.called1st)) {
            die("");
        }


        if ((hw.called2nd)) {
            die("");
        }
    }




    @Test
    public void testAllowOverloads3() {
        HelloWorld hw = new HelloWorld();
        hw.called1st = false;
        hw.called2nd = false;

        Invoker.invokeOverloadedFromList( hw, "sayHi2", Lists.list("Rick") );

        if ((!hw.called1st)) {
            die("");
        }


        if ((hw.called2nd)) {
            die("");
        }
    }



    @Test
    public void testAllowOverloads2() {
        HelloWorld hw = new HelloWorld();
        hw.called1st = false;
        hw.called2nd = false;

        Invoker.invokeOverloaded( hw, "sayHi2", "Rick", 1 );

        if ((hw.called1st)) {
            die("");
        }


        if ((!hw.called2nd)) {
            die("");
        }
    }



    @Test
    public void testAllowOverloads4() {
        HelloWorld hw = new HelloWorld();
        hw.called1st = false;
        hw.called2nd = false;

        Invoker.invokeOverloadedFromList( hw, "sayHi2", Lists.list("Rick", "1") );

        if ((hw.called1st)) {
            die("");
        }


        if ((!hw.called2nd)) {
            die("");
        }
    }



    @Test
    public void testWithListSimple() {
        Invoker.invokeFromList( new HelloWorld(), "sayHi", Lists.list( "Rick" ) );
    }


    @Test
    public void testWithListSimple2() {
        String message = (String) Invoker.invokeFromList( new HelloWorld(), "say", Lists.list( "Rick", 1 ) );
        puts (message);

        if (!message.equals( "hi  Rick 1\n" )) die(message);
    }


    @Test
    public void testWithListSimpleWithConversion() {
        String message = (String) Invoker.invokeFromList( new HelloWorld(), "say", Lists.list( "Rick", "1" ) );
        puts (message);
        if (!message.equals( "hi  Rick 1\n" )) die(message);
    }



    @Test
    public void testComplex() {
        HelloWorldArg message = (HelloWorldArg) Invoker.invokeFromList( new HelloWorld(), "sayArg",
                Lists.list( Lists.list( "1", "Hello" ), 1 ) );


        if (!message.equals( new HelloWorldArg( 1, "Hello" ) )) {
            die();
        }
    }



    @Test
    public void testComplex2() {
        HelloWorldArg message = (HelloWorldArg) Invoker.invokeFromObject( new HelloWorld(), "sayArg2",
                Lists.list( "1", "Hello" ) );


        if (!message.equals( new HelloWorldArg( 1, "Hello" ) )) {
            die();
        }
    }



    @Test
    public void testComplex3() {
        HelloWorldArg message = (HelloWorldArg) Invoker.invokeFromList( new HelloWorld(), "sayArg2",
                Lists.list( (Object)Lists.list( "1", "Hello" ) ) );


        if (!message.equals( new HelloWorldArg( 1, "Hello" ) )) {
            die();
        }
    }



    @Test
    public void testComplex4() {
        HelloWorldArg message = (HelloWorldArg) Invoker.invokeFromList( new HelloWorld(), "sayArg2",
                Lists.list( Maps.map( "i", "1", "hello", "Hello" )));


        if (!message.equals( new HelloWorldArg( 1, "Hello" ) )) {
            die();
        }
    }



    @Test
    public void testComplex5() {
        HelloWorldArg message = (HelloWorldArg) Invoker.invokeFromList( new HelloWorld(), "sayArg2",
                Lists.list( Maps.map( "i", "1", "hello", "Hello" )));


        if (!message.equals( new HelloWorldArg( 1, "Hello" ) )) {
            die();
        }
    }

}

Kafka and Cassandra support, training for AWS EC2 Cassandra 3.0 Training