Minborg

Minborg
Minborg

Thursday, December 1, 2016

Day 2, Java Holiday Calendar 2016, Composition

2. Favor Composition Over Inheritance



Today's tips is to avoid inheritance. For good reasons, there can only be one super class for any given Java class. Furthermore, exposing abstract or base classes in your API that are supposed to be inherited by client code is a very big and problematic API commitment. Avoid API inheritance altogether, and instead consider providing static interface methods that take one or several lambda parameters and apply those given lambdas to a default internal API implementation class.

This also creates a much clearer separation of concerns. For example, instead of inheriting from a public API class AbstractReader and overriding abstract void handleError(IOException ioe), it is better to expose a static method or a builder in the Reader interface that takes a Consumer<IOException> and applies it to an internal generic ReaderImpl.

Do This:

Reader reader = Reader.builder()
    .withErrorHandler(IOException::printStackTrace)
    .build();

Don't Do This:

Reader reader = new AbstractReader() {

    @Override
    public void handleError(IOException ioe) {
        ioe.printStackTrace();
    }
};

Read more in the original article at https://dzone.com/articles/the-java-8-api-design-principles

Follow the Java Holiday Calendar 2016 with small tips and tricks all the way through the winter holiday season.

Day 1, Java Holiday Calendar 2016, Functional Interfaces

1. Use the @FunctionalInterface Annotation



Today's tips is to annotate a functional interface with the @FunctionalInterface annotation thereby signaling that API users may use lambdas to implement the interface. It also ensures that the interface remains usable for lambdas over time by preventing abstract methods from accidentally being added to the API later on.

Do This:

@FunctionalInterface
public interface CircleSegmentConstructor {

    CircleSegment apply(Point cntr, Point p, double ang);

    // abstract methods cannot be added

}


Don't Do This:

public interface CircleSegmentConstructor {

    CircleSegment apply(Point cntr, Point p, double ang);

    // abstract methods may be accidentally added later

}


Read more in the original article at https://dzone.com/articles/the-java-8-api-design-principles

Follow the Java Holiday Calendar 2016 with small tips and tricks all the way through the winter holiday season.

Thursday, November 10, 2016

Work with Parallel Database Streams using Custom Thread Pools

Parallel Database Streams

In my previous post, I wrote about processing database content in parallel using parallel streams and Speedment. Parallel streams can, under many circumstances, be significantly faster than the usual sequential database streams.

The Thread Pool
By default, parallel streams are executed on the common ForkJoinPool where they potentially might compete with other tasks. In this post we will learn how we can execute parallell database streams on our own custom ForkJoinPool, allowing a much better control of our execution environment.

Speedment is an open-source Stream ORM Java Toolkit and Runtime Java tool that wraps an existing database and its tables into Java 8 streams. We can use an existing database and run the Speedment tool and it will generate POJO classes that corresponds to the tables we have selected using the tool. One distinct feature with Speedment is that it supports parallel database streams and that it can use different parallel strategies to further optimize performance.

Getting Started With Speedment

Head out to open-souce Speedment on GitHub and learn how to get started with a Speedment project. Connecting the tool to an existing database is really easy. Read my previous post for more information on how the database table and PrimeUtil class looks like for the examples below.

Executing on the Default ForkJoinPool

Here is the application that I talked about in my previous post that will scan a database table in parallel for undetermined prime number candidates and then it will determine if they are primes or not and update the table accordingly. This is how it looks:

Manager<PrimeCandidate> candidatesHigh = app.configure(PrimeCandidateManager.class)
            .withParallelStrategy(ParallelStrategy.computeIntensityHigh())
            .build();

        candidatesHigh.stream() 
            .parallel()                                                // Use a parallel stream
            .filter(PrimeCandidate.PRIME.isNull())                     // Only consider nondetermined prime candidates
            .map(pc -> pc.setPrime(PrimeUtil.isPrime(pc.getValue())))  // Sets if it is a prime or not
            .forEach(candidatesHigh.updater());                        // Apply the Manager's updater

First, we create a stream over all candidates (using a parallel strategy named ParallelStrategy.computeIntensityHigh()) where the 'prime' column is null using the stream().filter(PrimeCandidate.PRIME.isNull()) method. Then, for each such prime candidate pc, we either set the 'prime' column to true if pc.getValue() is a prime or false if pc.getValue() is not a prime. Interestingly, the pc.setPrime() method returns the entity pc itself, allowing us to easily tag on multiple stream operations. On the last line, we update the database with the result of our check by applying the candidatesHigh.updater() function.

Again, make sure to check out my previous post on the details and benefits of parallel strategies. In short, Java's default parallel strategy works well for low computational demands because it places a large amount of initial work items on each thread. Speedment's parallel strategies works much better for medium to high computational demands whereby a small amount of work items are laid out on the participating threads.

The stream will determine prime numbers fully parallel and the execution threads will use the common  ForkJoinPool as can be seen in this picture (my laptop has 4 CPU cores and 8 CPU threads):

Use a Custom Executor Service


As we learned in the beginning of this post, parallel streams are executed by the common ForkJoinPool by default. But, sometimes we want to use our own Executor, perhaps because we are afraid of flooding the common ForkJoinPool, so that other tasks cannot run properly. Defining our own executor can easily be done for Speedment (and other stream libraries) like this:

    final ForkJoinPool forkJoinPool = new ForkJoinPool(3);
    forkJoinPool.submit(() -> 
        
        candidatesHigh.stream() 
            .parallel()
            .filter(PrimeCandidate.PRIME.isNull())
            .map(pc -> pc.setPrime(PrimeUtil.isPrime(pc.getValue())))
            .forEach(candidatesHigh.updater()); 
            
    );

    try {
        forkJoinPool.shutdown();
        forkJoinPool.awaitTermination(1, TimeUnit.HOURS);
    } catch (InterruptedException ie) {
        ie.printStackTrace();
    } 

The application code is unmodified, but wrapped into a custom ForkJoinPool that we can control ourselves. In the example above, we setup a thread pool with just three worker threads. The worker threads are not shared with the threads in the common ForkJoinPool.

Here is how the threads looks like using the custom executor service:


This way we can control both the actual ThreadPool itself and precisely how work items are laid out in that pool using a parallel strategy!

Keep up the heat in your pools!

Monday, October 24, 2016

Work with Parallel Database Streams using Java 8

What is a Parallel Database Stream?

Read this post and learn how you can process data from a database in parallel using parallel streams and Speedment. Parallel streams can, under many circumstances, be significantly faster than the usual sequential streams.

With the introduction of Java 8, we got the long awaited Stream library. One of the advantages with streams is that it is very easy to make streams parallel. Basically, we could take any stream and then just apply the method parallel() and we get a parallel stream instead of a sequential one. By default, parallel streams are executed by the common ForkJoinPool.
Spire and Duke Working in Parallel

Parallel streams are good if the work items to be performed in the parallel stream pipelines are largely uncoupled and when the effort of dividing up the work in several threads is relatively low. Equally, the effort of combining the parallel results must also be relatively low.

So, if we have work items that are relatively compute intensive, then parallel streams would often make sense.

Speedment is an open-source Stream ORM Java Toolkit and RuntimeJava tool that wraps an existing database and its tables into Java 8 streams. We can use an existing database and run the Speedment tool and it will generate POJO classes that corresponds to the tables we have selected using the tool.

One cool feature with Speedment is that the database streams supports parallelism using the standard Stream semantics. This way, we can easily work with database content in parallel and produce results much faster than if we process the streams sequentially!

Getting Started With Speedment

Visit open-souce Speedment on GitHub and learn how to get started with a Speedment project. It should be very easy to connect the tool to an existing database.

In this post, the following MySQL table is used for the examples below.

CREATE TABLE `prime_candidate` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `value` bigint(20) NOT NULL,
  `prime` bit(1) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB;


The idea is that people may insert values into this table and then we will write an application that computes if the inserted values are a prime numbers or not. In a real case scenario, we could use any table in a MySQL, PostgreSQL or MariaDB database.

Writing a Sequential Stream Solution

First, we need to have a method that returns if a value is a prime number. Here is a simple way of doing it. Note that the algorithm is purposely made slow so we clearly can se the effects of parallel streams over an expensive operation.

public class PrimeUtil {

    /**
     * Returns if the given parameter is a prime number.
     *
     * @param n the given prime number candidate
     * @return if the given parameter is a prime number
     */
        static boolean isPrime(long n) {
        // primes are equal or greater than 2 
        if (n < 2) {
            return false;
        }
        // check if n is even
        if (n % 2 == 0) {
            // 2 is the only even prime
            // all other even n:s are not
            return n == 2;
        }
        // if odd, then just check the odds
        // up to the square root of n
        // for (int i = 3; i * i <= n; i += 2) {
        //
        // Make the methods purposely slow by
        // checking all the way up to n
        for (int i = 3; i <= n; i += 2) {
            if (n % i == 0) {
                return false;
            }
        }
        return true;
    }

}

Again, the object of this post is not to devise an efficient prime number determination method.

Given this simple prime number method, we can now easily write a Speedment application that will scan the database table for undetermined prime number candidates and then it will determine if they are primes or not and update the table accordingly. This is how it might look:

final JavapotApplication app = new JavapotApplicationBuilder()
            .withPassword("javapot") // Replace with the real password
            .withLogging(LogType.STREAM)
            .build();
        
        final Manager<PrimeCandidate> candidates = app.getOrThrow(PrimeCandidateManager.class);
        
        candidates.stream()
            .filter(PrimeCandidate.PRIME.isNull())                      // Filter out undetermined primes
            .map(pc -> pc.setPrime(PrimeUtil.isPrime(pc.getValue())))   // Sets if it is a prime or not
            .forEach(candidates.updater());                             // Applies the Manager's updater

The last part contains the interesting stuff. First, we create a stream over all candidates where the 'prime' column is null using the stream().filter(PrimeCandidate.PRIME.isNull()) method. It is important to understand that the Speedment stream implementation will recognize the filter predicate and will be able to use that to reduce the number of candidates that are actually pulled in from the database (e.g. a "SELECT * FROM candidate WHERE prime IS NULL" will be used). Then, for each such prime candidate pc, we either set the 'prime' column to true if pc.getValue() is a prime or false if pc.getValue() is not a prime. Interestingly, the pc.setPrime() method returns the entity pc itself, allowing us to easily tag on multiple stream operations. On the last line, we update the database with the result of our check by applying the candidates.updater() function. So, this application's main functionality is really a one-liner (broken up into five lines for improved readability).

Now, before we can test our application, we need to generate some test data input. Here is an example of how that can be done using Speedment:

final JavapotApplication app = new JavapotApplicationBuilder()
            .withPassword("javapot") // Replace with the real password
            .build();

        final Manager<PrimeCandidate> candidates = app.getOrThrow(PrimeCandidateManager.class);

        final Random random = new SecureRandom();

        // Create a bunch of new prime candidates
        random.longs(1_100, 0, Integer.MAX_VALUE)
            .mapToObj(new PrimeCandidateImpl()::setValue)  // Sets the random value 
            .forEach(candidates.persister());              // Applies the Manager's persister function

Again, we can accomplish our task with just a few lines of code.

Try the Default Parallel Stream

If we want to parallelize our stream, we just need to add one single method to our previous solution:

        candidates.stream()
            .parallel()                                 // Now indicates a parallel stream
            .filter(PrimeCandidate.PRIME.isNull())
            .map(pc -> pc.setPrime(PrimeUtil.isPrime(pc.getValue())))
            .forEach(candidates.updater());             // Applies the Manager's updater

And we are parallel! However, by default, Speedment is using Java's default parallelization behavior (as defined in Spliterators::spliteratorUnknownSize) which is optimized for non-compute-intensive operations. If we analyze Java's default parallelization behavior, we will determine that it will use a first thread for the first 1024 work items, a second thread for the following 2*1024 = 2048 work items and then 3*1024 = 3072 work items for the third thread and so on. This is bad for our application, where the cost of each operation is very high. If we are computing 1100 prime candidates, we will only use two threads because the first thread will take on the first 1024 items and the second thread will take on the rest 76. Modern servers have a lot more threads than that. Read the next section to see how we can fix this issue.

Built-in Parallelization Strategies

Speedment has a number of built-in parallelization strategies that we can select depending on the work item's expected computational demands. This is an improvement over Java 8 that only has one default strategy. The built-in parallel strategies are:

@FunctionalInterface
public interface ParallelStrategy {

    /**
     * A Parallel Strategy that is Java's default <code>Iterator</code> to
     * <code>Spliterator</code> converter. It favors relatively large sets (in
     * the ten thousands or more) with low computational overhead.
     *
     * @return a ParallelStrategy
     */
    static ParallelStrategy computeIntensityDefault() {...}

    /**
     * A Parallel Strategy that favors relatively small to medium sets with
     * medium computational overhead.
     *
     * @return a ParallelStrategy
     */
    static ParallelStrategy computeIntensityMedium() {...}

    /**
     * A Parallel Strategy that favors relatively small to medium sets with high
     * computational overhead.
     *
     * @return a ParallelStrategy
     */
    static ParallelStrategy computeIntensityHigh() {...}

    /**
     * A Parallel Strategy that favors small sets with extremely high
     * computational overhead. The set will be split up in solitary elements
     * that are executed separately in their own thread.
     *
     * @return a ParallelStrategy
     */
    static ParallelStrategy computeIntensityExtreme() {...}

    <T> Spliterator<T> spliteratorUnknownSize(Iterator<? extends T> iterator, int characteristics);

    static ParallelStrategy of(final int... batchSizes) {
        return new ParallelStrategy() {
            @Override
            public <T> Spliterator<T> spliteratorUnknownSize(Iterator<? extends T> iterator, int characteristics) {
                return ConfigurableIteratorSpliterator.of(iterator, characteristics, batchSizes);
            }
        };
    }

Applying a Parallel Strategy

The only thing we have to do is to configure a parallelization strategy to a manager like this, and we are good to go:

Manager<PrimeCandidate> candidatesHigh = app.configure(PrimeCandidateManager.class)
            .withParallelStrategy(ParallelStrategy.computeIntensityHigh())
            .build();

        candidatesHigh.stream() // Better parallel performance for our case!
            .parallel()
            .filter(PrimeCandidate.PRIME.isNull())
            .map(pc -> pc.setPrime(PrimeUtil.isPrime(pc.getValue())))
            .forEach(candidatesHigh.updater());

The ParallelStrategy.computeIntensityHigh() strategy will break up the work items in much smaller chunks. This will give us considerably better performance, since we now are going to use all the available threads. If we look under the hood, we can see that the strategy is defined like this:

    private final static int[] BATCH_SIZES = IntStream.range(0, 8)
            .map(ComputeIntensityUtil::toThePowerOfTwo)
            .flatMap(ComputeIntensityUtil::repeatOnHalfAvailableProcessors)
            .toArray();


This means that, on a computer with 8 threads, it will put one item on thread 1-4, two items on thread 5-8 and when the tasks are completed there will be four items on the next four available threads, then eight items and so on until we reach 256 which is the maximum items put on any thread. Obviously, this strategy is much better than Java's standard strategy for this particular problem.

Here is how the threads in the common ForkJoinPool looks like on my 8 threaded laptop:


Create Your Own Parallel Strategy

One cool thing with Speedment is that we, very easily, can write our parallelization strategy and just inject it into our streams. Consider this custom parallelization strategy:

    public static class MyParallelStrategy implements ParallelStrategy {

        private final static int[] BATCH_SIZES = {1, 2, 4, 8};

        @Override
        public <T> Spliterator<T> spliteratorUnknownSize(Iterator<? extends T> iterator, int characteristics) {
            return ConfigurableIteratorSpliterator.of(iterator, characteristics, BATCH_SIZES);
        }

    }

Which, in fact, it can be expressed even shorter:

    ParallelStrategy myParallelStrategy = ParallelStrategy.of(1, 2, 4, 8);


This strategy will put one work item on the first available thread, two on the second, four on the third, eight on the fourth with eight being the last digit in our array. The last digit will then be used for all subsequent available threads. So the order really becomes 1, 2, 4, 8, 8, 8, 8, ... We can now use our new strategy as follows:

Manager<PrimeCandidate> candidatesCustom = app.configure(PrimeCandidateManager.class)
            .withParallelStrategy(myParallelStrategy)
            .build();

        candidatesCustom.stream()
            .parallel()
            .filter(PrimeCandidate.PRIME.isNull())
            .map(pc -> pc.setPrime(PrimeUtil.isPrime(pc.getValue())))
            .forEach(candidatesCustom.updater());

Voilà! We have full control over how the work items are laid out over the available execution threads.

Benchmarks

All benchmarks used the same input of prime candidates. Tests were run on a MacBook Pro, 2.2 GHz Intel Core i7 with 4 physical cores and 8 threads.

Strategy

Sequential                       265 s (One thread processed all 1100 items)
Parallel Default Java 8          235 s (Because 1024 items were processed by thread 1 and 76 items by thread 2)
Parallel computeIntensityHigh()   69 s (All 4 hardware cores were used)

Conclusions

Speedment supports parallel processing of database content.

Speedment supports a variety of parallel strategies to allow full utilization of the execution environment.

We can easily create our own parallel strategies and use them in our Speedment streams.

It is possible to improve performance significantly by carefully selecting a parallel strategy over just settling with Java's default one.

Thursday, October 20, 2016

Java 8: A Closer Look at Speedment 3.0.1 “Forest” Stream ORM

Following the Road

Forest.png
I have been contributing to the open-source project Speedment (which is a Stream ORM Java Toolkit and Runtime) and a new major version called 3.0.1 “Forest” was just released. Releases are named after the avenues in Palo Alto, California where most of the contributors work. Each new major release gets a new name by following Middlefield Road southwards. The new version is now modularized which helps developers keep up the good pace. There are also a large number of new features for Speedment users and in this article we will look into some of the things to discover!

Persistence

People used to older ORMs can now use Speedment in the same way when creating, updating or removing entities from a database. For example, we can create entities in a database “JPA-style” like this:
Hare hare = new HareImpl();
hare.setName("Flopsy");
hare.setAge(1);
hare.setColor("Gray");

entityManager.persist(hare);  // Persists (=inserts) the new Hare in the database

While this is not a big change, it is still convenient.

Declarative Stream Composition

Speedment database queries are expressed as operations on Standard Java 8 Streams. In the new version, the Speedment API provides methods that returns functions rather than operating on objects directly. This simplifies something called Declarative Stream Composition which simply means that it becomes easier and more efficient to write streams.

Let us take a closer look at an example where we want to join objects from two different tables. We have two tables “hare” and “carrot” where “carrot” has a field named “owner” that is a foreign key to the column “hare”.”id”. The task is to build a Map that contains all Hare entities as keys and a List of Carrot entities that belongs to a particular Hare via its foreign key, as values. This can be expressed like this:

Map<Hare, List<Carrot>> joinMap = carrots.stream()
    .collect(
        groupingBy(hares.finderBy(Carrot.OWNER)) // Applies the finderBy(Carrot.OWNER) classifier
    );

The goupingBy() method takes a Function that maps from a Carrot to a Hare entity. So, by working by methods that returns functions, our code becomes very compact. This also opens up future ways of optimizing the stream, since these functions can be identified and analyzed in the stream pipeline prior to the stream is started. It should be noted that both the collect() and groupingBy() methods are standard Java 8 methods.

Even Better Code Generation

Speedment generates code automatically from the database schema data. One good thing with Speedment is that we can see, understand and change the generated code. This makes things less “magic” compared to other ORMs and puts the developer in the driving seat. The new code generation functionalities include:

Support for Primitive Types

Now we can use primitive types like int, long or double for columns and improve both execution speed and memory usage. Nullable fields can be mapped to specialized Optional types like OptionalInt, OptionalLong and OptionalDouble consistent with Java 8 code styling.

Modular Code Generation

We can plug in our own code generation logic and adapt the default code generator. This comes in handy for us developers that might understand our domain model in depth and want to leverage that knowledge. When new functionality is added by customizing the code generator, these new features will be applied immediately to all generated code. Code the code and get leverage!

Compatibility Mode

Some older solutions are not prepared for Optional fields and so a new “compatibility” mode was added where, for example, a nullable integer will be returned as an Integer and not as an OptionalInt.

Configurable Name Space

We can now configure the code generator to put entities, managers and configuration objects individually on any namespace. This is good for modularized projects.

Improved Code Renderer

Speedment is using a Model View Controller (MVC) paradigm for code generation. This means that the code Model (which is an Abstract Syntax Tree) is separate from the actual code rendering (View). The Views have been updated and improved so it produces better looking code.

Checksum Protection

Manually changes classes are protected by checksums so that they are retained even if we decide to change the name space.

Increased Type Safety

Speedment can now map columns that take values from small sets of strings to Enums further improving type safety. When the generated code uses an Enum, any mismatch between the database model and the values used in the business logic will be found as early as possible by the compiler, instead of later in the development cycle.

Improved Logging for Transparency

Speedment has a new logging system to allow us to see the exact SQL code being sent to the database. This is good for transparency and allows us to see precisely what is happening under the hood. We can easily enable logging of all CRUD operations like this:

HaresApplication loggingApp = new HaresApplicationBuilder()
    .withPassword("secretDbPassword")
    .withLogging(STREAM)
    .withLogging(PERSIST)
    .withLogging(UPDATE)
    .withLogging(REMOVE)
    .build();

Manager<Hare> hares = loggingApp.getOrThrow(HareManager.class);

long oldHares = hares.stream()
    .filter(Hare.AGE.greaterThan(8))
    .count();

System.out.println("There are " + oldHares + " old hares");

This will produce the following log:
2016-10-19T20:50:21.957Z DEBUG [main] (#SELECT) - 
    SELECT COUNT(*) FROM `hares`.`hare` WHERE (`hares`.`hare`.`age` > ?), values:[8]

There are 30 old hares


Improved User Interface

The graphical tool has been improved in many ways. Now, we get warnings and tips that gives us better guidance. Several code generator configuration options have been added and we also see more relevant information when we select different configuration objects.

New Maven Goals

There are two new Maven goals; “clear” and “reload”, that can be used to automate and simplify the building process. The goal “clear” removes all generated code (that is not manually changed) and “reload” reloads the domain model directly from an existing database (metadata).

Take it for a Spin

Check out open-source Speedment on GitHub where there also is a Wiki and a quick start guide. Feel free to give feedback and join the discussion via Gitter.

Drive safely!

Friday, August 12, 2016

The Need for Speed in Web Applications

Often, web applications are slower than we would like them to be. Companies like Google and Facebook have in-house solutions for speeding up their applications. There is a need for a third-party tool that we developers can use to achieve something similar, without needing to spend hours to optimize the code and the database.

The last couple of months, I have been busy contributing to a project that speeds up the response times and also makes it much easier to develop the back end parts of web applications. The project is named Ext Speeder and was developed together with Sencha, the company behind Ext JS. It allows Ext JS developers to speed up their data grids more than 10 times.

Automatically Generated Back End 

All back end developers know that there is a lot of work to connect a front end application to the back end. Some of the tasks are to model the database, secure connections, parse http command, deserialize parameters, manage database connections, convert into SQL, optimize queries, parse database response, format into JSON, write XML config, deploy in Java EE and finally verify all the code. Depending on project this may take a couple of days or even several weeks

We have created a tool that connects to an existing database and extracts the schema model so that back end code can be generated automatically. Indeed, there is no need for writing a single line of back end code in most situations. If we have special requirements (like adding our own models to the existing data), it is easy to add or modify the code that was generated by the Ext Speeder tool.

Checkout this 1.5 minute video by a guy that holds the current world-record in developing and deploying a Sencha Ext JS application with the tool (he does it in less than 1.5 minutes). Can it be done faster?

How Much Faster Does it Get?

When an Ext Speeder application is started, it can pull in data we have selected into an in-JVM-memory store so that data can be accessed and processed much faster. Data is also organized in a column oriented way. Thanks to that, sorting and filtering on a column can be done in nanoseconds rather than in seconds. Because Ext Speeder can use an off-heap storage engine, we can pull in an almost unlimited amount of data. An Ext Speeder application can easily handle one hundred million elements. Ext Speeder can also refresh the in-memory data periodically in the background, so that we will see the latest data in the database.

Giving fair benchmark figures is always hard. To give an idea, we took an existing public database containing a large number of medical doctors in the US with over 40 million elements and stored them in a standard MySQL server (version 5.6.29) with indexes added to the relevant columns. We then compared typical web access patterns containing sorting, filtering and paging with Ext Speeder versus using the MySQL database directly. On average, Ext Speeder was more than 100 times faster.

Figure 1, Latency, Ext Speeder vs MySQL standard (less is better) for one of the sub-test

We used the following setup for the tests:

Property
Value
Computer
Lenovio
CPU
Intel i7-4720HQ CPU @ 2.60GHz
RAM
16 GB
OS
Windows 10
Database
MySQL Version 5.6.29 std. install
Test Tool
Apache JMeter

What is the real-life gain with such speed improvements, in reality? Well, imagine a web user that is used to waiting some seconds between each interaction. Now that person could suddenly get immediate feed back and the site would feel much more responsive. Check out this 1 minute video to see the difference.


The REST API

Request

The tool is using a standard REST API for querying. If we have a database table named 'doctor', then we can query it like this:

http://localhost:4567/MyProject/doctor?
    callback=cb&
    start=10&
    limit=100&
    sort=[{"property":"last_name","direction":"ASC"}]&
    filter=[{"property":"graduation_year","operator":"lt","value":"1970"}]

This will retrieve doctors that graduated before 1970 sorted by last name starting at the 10:th such doctors and limiting the result to at most 100 physicians. On my laptop, the round trip REST call was completed in less than 0.04 seconds (A human would not notice that kind of delay).

The "sort" attribute can contain several columns so that sorting can be done in many levels.

The 'filter' attribute can be composed of several filters so than several conditions can be applied. We can use the operators Equals ("eq"), Not Equals ("ne"), Less Than ("lt"), Less or Equal ("le"), Greater Than ("gt"), Greater or Equals ("ge") and Contains ("like").

Response

The response to the request above is a JSON string that contains all the matching doctors in the given order. This also makes it very easy to interface with other languages like Java Script, PHP or C#. This is an example of how a response might look like (with limit=2 to reduce size):

cb({
  "total": 50457,
  "data": [
    {
      "id": 1687657,
      "last_name": "AARON",
      "first_name": "JOHN",
      "suffix": "",
      "gender": "M",
      "credential": "",
      "medical_school_name": "OTHER",
      "graduation_year": 1966,
      "primary_speciality": "GASTROENTEROLOGY",
      "second_speciality": "",
      "organization": "ATLANTIC COAST GASTROENTEROLOGY ASSOCIATES",
      "organization_dba_name": "",
      "street_address_1": "1944 STATE ROUTE 33",
      "street_address_2": "",
      "supress_street_address_2": "Y",
      "city": "NEPTUNE",
      "state": "NJ",
      "zip_code": "077534863",
      "real_zips_ext_id": "RZ-US-07753",
      "claims_based_aff_CCN_1": "310038",
      "claims_based_aff_LBN_1": "ROBERT WOOD JOHNSON UNIVERSITY HOSPITAL, INC"
    },
    {
      "id": 258680,
      "last_name": "ABADEE",
      "first_name": "RASHEED",
      "suffix": "",
      "gender": "F",
      "credential": "MD",
      "medical_school_name": "OTHER",
      "graduation_year": 1968,
      "primary_speciality": "PHYSICAL MEDICINE AND REHABILITATION",
      "second_speciality": "",
      "organization": "",
      "organization_dba_name": "",
      "street_address_1": "1300 W 7TH ST",
      "street_address_2": "SAN PEDRO HOSP",
      "supress_street_address_2": "N",
      "city": "SAN PEDRO",
      "state": "CA",
      "zip_code": "90732",
      "real_zips_ext_id": "RZ-US-90732",
      "claims_based_aff_CCN_1": "050078",
      "claims_based_aff_LBN_1": "PROVIDENCE HEALTH SYSTEM - SOUTHERN CALIFORINA"
    }
  ]
});

The 'total' property in the response indicates how many of the rows actually matched the filter (in total) so that data grids can set the appropriate scroll bar location and size.

How Does it Look Like?

This is how an Ext JS data grid application might look like with an Ext Speeder back end:



Deployment

Deployment is easy. Either deploy an Ext Speeder application as a stand-alone application (just run its main Java method) or deploy it as a Java EE application (upload the self-contained WAR file to the server). Any Java EE server would do. For example Tomcat, Glassfish or Oracle WebLogic. This way, the application can automatically benefit from features such as company security policies, authentication, encryption, load balancing etc.

Try it for Free!

Go to http://www.extspeeder.com/ to request a free trial. The User's Manual can be found on the same web page. I would be happy to get feedback on the experience or improvement suggestions as a comment on this post.



Monday, April 11, 2016

Java 8: Use Smart Streams with Your Database in 2 Minutes

Streaming with Speedment

Duke and Spire Mapping Streams.

Back in the ancient 90s, we Java developers had to struggle with making our database application work properly. There was a lot of coding, debugging and tweaking. Still, the applications often blew up right in our faces to our ever increasing agony. Things gradually improved over time with better language, JDBC and framework support. I'd like to think that we developers also improved, but there are different opinions on that...

When Java 8 finally arrived, some colleges and I started an open-source project to take the whole Java/DB issue one step further by leveraging on Java 8's stream library, so that database tables could be viewed as pure Java 8 streams. Speedment was born! Wow, now we can do type-safe database applications without having to write SQL-code any more.

Speedment connects to existing databases and generate Java code. We can then use the generated code to conveniently query the database using standard Java 8 streams. With the new version 2.3 hitting the shelves just recently, we can even do parallel query streams!

Let's take some examples assuming we have the following database table defined:
 
CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(45) NOT NULL,
  `firstName` varchar(45) DEFAULT NULL,
  `lastName` varchar(45) DEFAULT NULL,
  `email` varchar(45) NOT NULL,
  `password` varchar(45) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `email_UNIQUE` (`email`),
  UNIQUE KEY `username_UNIQUE` (`username`)
) ENGINE=InnoDB;

Speedment is free for the open-source databases MySQL, PostgreSQL and MariaDB. There is also support for commercial databases, like Oracle, as an enterprise add-on feature.

Examples


Querying

Select all users with a ".com" mail address and print them:
        users.stream()
            .filter(EMAIL.endsWith(".com"))
            .forEach(System.out::println);
Select users where the first name is either "Adam" or "Cecilia" and sort them in username order, then take the first 10 of those and extract the email address and print it.
        users.stream()
            .filter(FIRST_NAME.in("Adam", "Cecilia"))
            .sorted(USERNAME.comparator())
            .limit(10)
            .map(User::getEmail)
            .forEach(System.out::println);

Creating Database Content

Create a new user and persist it in the database:
        users.newEmptyEntity()
            .setUsername("thorshammer")
            .setEmail("mastergamer@castle.com")
            .setPassword("uE8%3KwB0!")
            .persist();

Updating Database Content

Find the user with id = 10 and update the password:
        users.stream()
            .filter(ID.equal(10))
            .map(u -> u.setPassword("pA6#nLaX1Z"))
            .forEach(User::update); 

Removing Database Content

Remove the user with id = 100:
        users.stream()
            .filter(ID.equal(100))
            .forEach(User::remove);

New Cool Stuff: Parallel Queries

Do some kind of expensive operation in parallel for users with 10_000 <= id < 20_000
        users.stream()
            .parallel()
            .filter(ID.between(10_000, 20_000))
            .forEach(expensiveOperation());

Setup

Setup code for the examples above:
       final Speedment speedment = new JavapotApplication()
            .withPassword("javapot") // Replace with your real DB password
            .build();

        final Manager<User> users = speedment.managerOf(User.class);

Get Started with Speedment


Read more here on GitHub on how to get started with Speedment.

Read more about the complete set of Java 8 features including Streams.