Collisions on a Switch on Strings

Today, I felt on a really nice blog post about how a switch is implemented for String under the hood.

It basically explains that the switch is implemented on the String hash code. Easy and efficient. But it made me wondering what would happen if the was a collision in the hash codes. By that I mean: What happen if you got two cases containing strings having the same hash code?

To test it, I've created such a switch. First I was needing to found two strings with the same hash code. The way the hash code of calculate for a string is quite simple. It loops over the characters, adding their value to the previous result multiplied by 31. So, doing a bit of algebra, the two characters strings below will be in collision.


int c1 = some_character, c2 = some_other_character;
int c3 = c1-1, c4 = 31*c1+c2-31*c3;

String s1 = new String(new char[] {(char)c1, (char)c2});
String s2 = new String(new char[] {(char)c3, (char)c4});
From where I just had to create a switch with the result. For instance "10" and "0O" both have a hash code of 1567.


switch (args[0]) {
case "10":
    System.out.println("Here");
    break;
case "0O":
    System.out.println("There");
    break;
case "123":
    System.out.println("Away");
    break;
}

Decompiling this code brings a surprising result.


String str1 = args[0];int i = -1;
switch (str1.hashCode())
{
case 1567:
  if (str1.equals("0O")) {
    i = 1;
  } else if (str1.equals("10")) {
    i = 0;
  }
  break;
case 48690:
  if (str1.equals("123")) {
    i = 2;
  }
  break;
}
switch (i)
{
case 0:
  System.out.println("Here");
  break;
case 1:
  System.out.println("There");
  break;
case 2:
  System.out.println("Away");
}

So, in case of collision, the compiler changes the strategy and add a redirection. It is worthy to mention that the redirection applies even to cases that are not in collision (like "123" in the example).

So, unless the JVM manage to optimize this at runtime (which is highly possible), if we are unlucky enough to have a collision in your switch, you code will be slower than if there wasn't any.

New file shortcut

There is no way to create a new file in Windows explorer using a shortcut. You can Ctrl+Shift+N to create a new folder but strangely nothing to create a file.

The solution is to use AutoHotKey and a script. This one works on Windows 8. It was adapted from here.

#IfWinActive ahk_class CabinetWClass

; Create new file in Explorer
^N::
NewTextFile()
return

#IfWinActive

NewTextFile()
{
WinGetText, full_path, A
StringSplit, word_array, full_path, `n
Loop, %word_array0%
{
IfInString, word_array%A_Index%, Address
{
full_path := word_array%A_Index%
break
}
}
full_path := RegExReplace(full_path, "^Address: ", "")
StringReplace, full_path, full_path, `r, , all

IfInString full_path, \
{
NoFile = 0
Loop
{
IfExist %full_path%\NewTextFile%NoFile%.txt
NoFile++
else
break
}
FileAppend, ,%full_path%\NewTextFile%NoFile%.txt
}
else
{
return
}
}

Windows hard links

As on Unix, it is also possible on Windows to create a hard link to a file. I'm using this feature to backup in Dropbox files that need to be placed in some other directory. For instance, my ssh config file.

Here's how you do it from a cmd:

mklink /h %USERPROFILE%\Dropbox\.ssh\config %USERPROFILE%\.ssh\config

Note that there is no way to visualy know that it is a hard link. You have to guess and confirm your intuition doing:

fsutil hardlink list config

Also, if you are wondering, delete one of the file doesn't delete the file. You need to delete all links to it to get rid of it.

Ctrl+V in cmd

I've been using this for a while in fact but thought it was useful enough to be told.

A really annoying thing on Windows is that you can't Ctrl+V in a cmd. You can anywhere else but not there.

A nice piece of software named AutoHotkey can solve this. It allows you to script (in a strange language sadly) hot keys anywhere in Windows.

For Ctrl+V, the following script does the trick:

#IfWinActive ahk_class ConsoleWindowClass
^V::
SendInput {Raw}%clipboard%
return
#IfWinActive

UPDATE: In fact SendIput has encoding issue. So I'm now using Send !{Space}ep which simulate an access to the system menu and then select the paste by typing 'e' and 'p'. Not that is works in English. You might have to change the letters to fit your OS language.

LiveReload

I’m not originally a web developer. But I’m doing more and more of it. I’ve discovered LiveReload some time ago and became addicted to it.

By that I mean that I’m putting it on pretty much every web page I’m working on. Getting instant feedback is great.

I’m using Grunt to launch it. So I’m now having two files that I’m copying around. They are pretty basic but could be useful so I thought I could share.

package.json

{
  "name": "livereload-gruntjs",
  "version": "0.1.0",
  "devDependencies": {
    "grunt": "~0.4.2",
    "load-grunt-tasks": "~0.3.0",
    "requirejs": "~2.1.11",
    "grunt-contrib-connect": "~0.6.0",
    "grunt-contrib-watch": "~0.5.3"
  }
}

Gruntfile.js

module.exports = function(grunt) {

  require('load-grunt-tasks')(grunt);

  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),

    connect: {
      options: {
        hostname: 'localhost',
        port: 9001,
        livereload: 35729
      },
      livereload: {
        options: {
          open: true,
          base: 'app'
        }
      }
    },

    watch: {
      livereload: {
        options: {
          livereload: '<%= connect.options.livereload %>'
        },
        files: [
          'app/{,*/}*.*'
        ]
      }
    }

  });

  grunt.registerTask('serve', [
    'connect:livereload',
    'watch'
  ]);

};

Playing with keytool

It's been a while since I played with certificate in Java. It's usually the kind of thing you do once in your project and never touch again.

So I played with the Java keystore. I wanted to do a self-signed Sha256RSA certificate. It feels a bit like coding in perl. You start by something really long like:


# Create the key with openssl
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -sha256 -keyout bar.key -out bar.crt

# Create a new keystore with a dummy key
keytool -genkey -alias foo -keystore keystore.jks

# Delete the dummy key
keytool -delete -alias foo -keystore keystore.jks

# Import the real key
keytool -import -alias bar -file bar.crt -keystore keystore.jks

to a happy one liner (that also prevent from having to answer a bunch of question and providing a password all the time)


# Generate a self-signed certificate and create the keystore
keytool -genkey -keystore keystore.jks -alias bar -dname "CN=octo.com, OU=, O=OCTO, L=Paris, ST=, C=FR" -storepass mypassword -keypass mypassword -keyalg RSA -keysize 2048 -validity 730

# Export the certificate (ok, yes, it's a two liner if I want to get back the certificate)
keytool -exportcert -keystore keystore.jks -alias bar -file bar.crt -storepass mypassword -keypass mypassword

Playing with numbers in JavaScript

Today I did a bit a JavaScript to test some librairies to manipulate numbers.


The first is BigDecimal. It is based on the GWT implementation of Java BigDecimal class. It works exactly the its Java counterpart. If your doing financial calculation in JavaScript, this library is a must.

Then, I tried Numeral.js. A library allowing to format numbers easily in a given locale. Easy to use and works perfectly.

The last one was Formula.js. This one is fun and useful. It re-implements all Excel functions in JavaScript. They are two drawbacks.

The first one is that you need to add a bunch of other libraries to use it. But depending on which function you are using, you might not need all of them but that's left to you to figure it out.

The second one is that it calls eval in some function parameters. Could be dangerous so beware.

My suggestion on this library is to copy & paste the code of the functions you are using to limit the required third-party libraries, tweak it a bit to remove the evals and possibly migrate it to BigDecimal ;-)

Provision Vagrant with a shell

To allow everyone to be able to replicate the benchmark from my previous post, I’ve played with Vagrant to be able to provide correctly configured virtual machines.

I ended up provisioning two virtual machines in a single Vagrant file using shell provisioning.

I learned loads of unexpected things doing so that you will see in the shell files and the Vagrant file

  • How to do a dist-upgrade bypassing the interactive questions about grub
  • How to install the latest NodeJS
  • How to provision using the vagrant user instead of the root user (:privileged => false)
  • How to specify the number of CPUs used by the VM
  • How to setup a private network with Vagrant

And that provisioning a Vagrant VM takes quite a long time (especially the dist-upgrade). My two VMs are 75% the same. It would be nice to be able to create a base VM that forks into the two final VMs.

Is there a way to do that apart from scripting to create a new box?

The art of benchmarking

Here is an article I wrote about benchmarking, their flaws and what you can do with it. Also available in French

EasyMock used in a reactive environment


I was asked today to fulfill the following use case with EasyMock.
  • The tested method emit an asynchronous call
  • The mocked method receive the call
  • Before continuing, we want to make sure the asynchronous call had time to finish
It's always nice to see new usage emerge with EasyMock. The solution to this one was to use an IAnswer and a CountDownLatch.

To do something like this:
final CountDownLatch latch = new CountDownLatch(4);
mock.asyncProcess();
expectLastCall().andAnswer(new IAnswer<Object>() {

@Override
public Object answer() throws Throwable {
latch.countDown();
return null;
}
}).times(4);
replay(mock);

tested.doSomething();

latch.await(10, TimeUnit.SECONDS);

// Do some verifications...
verify(mock);
That feels kinda nice. And, to be honest, the actual code was in fact in Scala using EasyMockSugar. So they can use an implicit converter to make the code shorter.
// implicit converter definition
implicit def convertFnToAnswer[T](fn: => T) :IAnswer[T] = new IAnswer[T] {
def answer(): T = fn
}

// Record expectations
mock.asyncProcess() andAnswer {latch.countDown}