Improving PutIfAbsent…

Since Java 5 we have ConcurrentMap interface with a couple new methods, one of which is:

public V putIfAbsent(K key, V val);

This essentially replaces the following code:

if (!map.containsKey(key))
    return map.put(key, value);
else
    return map.get(key);

Although this method is useful sometime I found several nagging problems with similar methods:

  1. It doesn’t allow chaining as it returns null if value was actually added, and
  2. It forces me to create value (to pass as a parameter) every time even though it will be ignored all times except for the first time when it’s added.

In GridGain we’ve remedied this problem (setting aside atomicity of the putIfAbsent – our version requires outside synchronization) by having a utility method that, by the way, will be publicly available as part of new functional APIs added to GridGain 3.0:

public static <K, V> V mapGet(@NotNull Map<K, V> map, @Nullable K key, @Nullable GridFactoryClosure<V> c) {
    assert map != null;

    // 'null' values are allowed...
    if (map.containsKey(key) == false) {
        V v = c == null ? null : c.apply();

        map.put(key, v);

        return v;
    }
    else {
        return map.get(key);
    }
}

Now this version have several clear advantages:

  1. It has name mapGet to reflect that it is in fact a getter with an option to handle the key-miss;
  2. It allows for chaining as it always returns whatever value is in the map after this method completes, and
  3. It utilizes factory-closure to avoid unnecessary object creation (see below for example).

Factory-closure is a simple closure that takes no parameters and returns new value every time its apply method is called. The same class that contains this mapGet method (GridLang.java) contains other routines that allow for very terse creation of various factory-closures. So, the final usage of mapGet method may look something like that (using typedefs from GridGain 3.0 as well):

Map<String, List<Integer>> map = ...

// Getting list value from the 'map' with the 'key' (inserting a new empty list if 
// one is not present already) and adding '2010' to the final list.
G.mapGet(map, "key", G.<Integer>newList()).add(2010);

Comparing to the usual boiler-plate code:

Map<String, List<Integer>> map = ...

// Getting list value from the 'map' with the 'key' (inserting a new empty list if 
// one is not present already) and adding '2010' to the final list.
List<Integer> list = map.get("key");

if (list == null) {
    list = new ArrayList<Integer>();

    map.put("key", list);
}

list.add(2010);

That looks pretty neat, type safe and almost “clean” except for the Integer type qualification due to limitations of Java type inferencing. And it is pretty efficient too – since method newList(...) returns a constant static factory-closure allowing to fully avoid any unnecessary object creation.

Enjoy!

Groovy vs. Scala – We Need a Closure…

Disclosure: politically incorrect rant ahead from someone with Grid/Cloud computing perspective…

There was a recent outburst in blogs on the topic of Groovy and how it compares to Java. Although I respect the youthfull entusiasim of Groovy and Co. working on this little exercise I’m just perplexed by the “WHY?” in this whole discussion. Let me just say again: W H Y ?!?!

1. Practically no one cares about Groovy (let alone Groovy++ strap-on) beyond Grails community. So this language just as “widely accepted” as Ruby (at least for enterprise software development)

2. If you know Java it’s equally “challenging” to pick up either Groovy or Scala. Don’t let anyone insult your intelligence by claiming that Scala syntax is somehow more complex than Groovy. In both languages you will need to adapt to functional thinking – and that’s where you will have to spend a couple of weekends…

3. If you know Groovy – you already know 90% of Scala (different syntax and few extra features can be picked up in the evening)

4. Scala is designed by people who have proper academic background, experience and talent in the area of language design – Groovy has never been that way (and anyone who dares to look inside of Groovy runtime or history of changes in it will attest to that). NOTE: it did come out rather strong – but that’s how I feel about it and after some thinking I’ll leave as is. Nothing personal to anyone reading it…

5. Scala as a post-functional language is years ahead of Groovy (static typing with best-in-business type inference, highly tuned mix of imperative and functional styles, powerful and done-right generics, etc.)

6. Groovy will ALWAYS be slower than Scala or Java (latest benchmarks put even Groovy++ about 50 times slower than Java) just by its nature unless someone changes the language and rebuilds the runtime from the ground up.

7. Once we get decent integration with Eclipse, NetBeans and IDEA for Scala, the Groovy will lose its only serious advantage

8. Scala is developed and maintained in Academia (i.e. endless supply of post-docs and plenty of free time to research) – the vey rare case when it is not only appropriate but even desired. While two guys in garage working nights out until we literally pass out off exhaustion was perfectly fine for something like GridGain at the beginning – this is not enough for the general-purpose language development. And, no, VC will rarely if ever touch a language development business…

It really baffles me why would someone pick Groovy (or Groovy++) over Scala these days for non-Grails related work. Most of us will either stay with Java 7, use PHP or Python for quick’n’dirty web thingy, switch to .NET/C# or move to… Scala (all of which are sensible options in their own way). Groovy/Groovy++ just doesn’t fit anywhere in this picture in my humble opinion.

Rant’s over – enjoy!

ResultSet as Iterable…

It’s funny that I keep finding some simple utilities in core Java libraries that are not part of standard JDK after almost 15 years working with Java…

We are adding A LOT of functional APIs to GridGain 3.0 and many of the functional processing of collections works with Iterable interface. Yet – there’s no standard way to convert JDBC ResultSet to Iterable which is really just a few lines of code. Go figure why this was omitted…

The code below provides such conversation. Keep in mind that it is not 100% compatible with Iterator contract as you can’t call hasNext() more than once as it has side effect of advancing the result set. Other than that – you can use it with any functional constructs in GridGain 3.0 that require Iterable.

public static Iterable<ResultSet> asIterable(final ResultSet rs) {
    return new Iterable<ResultSet>() {
        @Override public Iterator<ResultSet> iterator() {
            return new Iterator<ResultSet>() {
               public boolean hasNext() {
                    try {
                        return rs.next();
                    }
                    catch (SQLException e) {
                        throw new RuntimeException(e);
                    }
                }

                public ResultSet next() {  return rs; }

                public void remove() { 
                    throw new UnsupportedOperationException(); 
                }
            };
        }
    };
}

Enjoy!