Archive for January, 2012

06
Jan
12

Groovy is COOL

Of course Groovy is much more than Java, but for Java coders like myself, it can be seen as Java without its time-eating annoyances, the absolute top 3 of which, in my opinion, are:

1. Getters and setters are implicit

2. Lists, Maps and Regex are part of the syntax

3. Configuration is greatly simplified

Item 1 is self explanatory, I hope ūüôā¬†For the remaining two, here are some examples:

Working with collections:

def list = [5, 6, 7, 8]
for (i in list) println i
def map = [name:"Gromit", likes:"cheese", id:1234]
for (i in map) println "map[${i.key}] is ${i.value}"

Pulling Maven dependencies inline with your code, without any other configuration anywhere:

@Grab(group='mysql', module='mysql-connector-java', version='5.1.18')
driver = new com.mysql.jdbc.Driver()
Properties p = new Properties()
 p['username']='groovy-test'
 p['password']=''
conn = driver.connect('jdbc:mysql://localhost/groovy-test', p)
st = conn.createStatement()
for (i in 1..10) {
 st.executeUpdate("insert into test(name,value,version) values('name${i}','value for name${i}',0)")
}
st.close()
conn.close()

Of course Groovy is a dynamically typed language, and as such has its downsides. Since the compiler can’t type-check assignments, you get much more run-time errors like:

No signature of method: java.util.ArrayList.get() is applicable for argument types: (java.lang.String)

Or

Cannot cast object ‘x’ with class ‘java.lang.String’ to class ‘int’

Most of these errors are caught when you try out your code for the first time, though, and are easily fixable. It’s just a bit annoying at the beginning for someone used to getting these at compile time rather than at run time.

To me, Groovy is still a clear winner if you want to boost your coding productivity ūüôā

Oh yeah, and the performance of Groovy is not significantly worse than that of Java (if you don’t use too many dynamic features), as I confirmed in this post.

05
Jan
12

Motorola AP-7131 dependent mode?

It seems that not all AP-7131’s are the same. There are some that are meant to be used only together with a central controller like¬†RFS4000 or RFS6000.

This is called, in Motorola terms, ‘dependent mode’, and is hard-coded into the device. The “D” in the model ID stands for “dependent”, like in this example:

Motorola AP-7131-66000-D-WR

Such a device will not enable any radio unless directed to do so by a central controller.

One of the reasons this is done is to prevent theft of access points from public locations.

05
Jan
12

Detect MIME type of most popular Internet files

This code can detect among others PDF, Microsoft Word, Excel, Powerpoint & Visio, without even knowing the file extension.

 

sub detectMime(\$)
{
  my ($s)=@_;
  return 'text/html' if $$s =~ /^(\xEF\xBB\xBF)*\s*<(\!--|\!?doctype|html|head|body|title|h1)/is;
  return 'text/xml' if $$s =~ /^(\xEF\xBB\xBF)*\s*<\?xml/s;
  return 'application/rtf' if $$s =~ /^\{\\rtf/s;
  my @b=unpack('C520',$$s);
  return 'image/jpeg' if $b[0]==0xFF && $b[1]==0xD8;
  return 'image/gif' if $b[0]==0x47 && $b[1]==0x49 && $b[2]==0x46;
  return 'image/png' if $b[0]==0x89 && $b[1]==0x50 && $b[2]==0x4E && $b[3]==0x47;
  return 'image/bmp' if $b[0]==0x42 && $b[1]==0x4D;
  return 'image/tiff' if $b[0]==0x49 && $b[1]==0x49 && $b[2]==0x2A;
  return 'application/pdf' if $b[0]==0x25 && $b[1]==0x50 && $b[2]==0x44 && $b[3]==0x46;
  return 'image/x-icon' if $b[0]==0 && $b[1]==0 && $b[2]==1 && $b[3]==0 && $b[4]==1;
  if ($b[0]==0xD0 && $b[1]==0xCF && $b[2]==0x11 && $b[3]==0xE0 && @b>0x200) {
    return 'application/msword' if $b[0x200]==0xEC;
    return 'application/vnd.ms-excel' if $b[0x200]==0x09;
    return 'application/vnd.ms-powerpoint' if $b[0x200]==0x40;
    return 'application/vnd.visio' if $b[0x200]==0xFD;
  }
  for (my $i=@b-1;$i>=0;$i--) { return 'application/octet-stream' if $b[$i]<32 && $b[$i]!=9 && $b[$i]!=10 && $b[$i]!=13 }
  return 'text/plain';
}
05
Jan
12

SDBM hash implementation in PHP

The SDBM hashing function is a simple and fast function that provides surprizingly uniform distributions of the hash value even when applied to a series of relatively short strings (3-7 characters). This makes it an excellent algorithm for organizing multiple files in sub-directories, for example, but the possible applications are, of course, endless.

Implementing the SDBM hashing in PHP is not an easy task, however. The SDBM hash function relies on a 32-bit overflow, which doesn’t work well in PHP due to its built-in overflow handling and automatic type conversion, which is also implemented differently on different platforms.

After much trial and error, the following cute piece of code has been found to perform correctly in PHP 5.2/5.3 on 32-bit as well as 64-bit systems.

function sdbmHash($str)
{
	$hash = 0; $n=strlen($str);
	for ($i=0; $i<$n; $i++) {
		$h1 = $hash << 6;
		if ($h1<0) $h1+=0x100000000;
		$h2 = $hash << 16;
		if ($h2<0) $h2+=0x100000000;
		$h3=($hash>=0x80000000?0x100000000-$hash:-$hash);
		$hash = (int)((int)ord($str[$i]) + $h1 + $h2 + $h3);
		if($hash<0) $hash=$hash+0x100000000;
	}
	return $hash;
}
05
Jan
12

“MySQL server has gone away”

When you try to insert a BLOB that exceeds your server’s maximum packet size, even on a local server you will see “MySQL server has gone away” on the client side, and “Error 1153 Got a packet bigger than ‘max_allowed_packet’ bytes” in the server log. To fix this you need to decide what is the size of the largest BLOB you’ll ever insert, and set max_allowed_packet in my.ini accordingly, for example:

[mysqld]
 ...
 max_allowed_packet = 200M
 ...

 

05
Jan
12

PHP vs. Ruby/JRuby on Rails vs. Grails vs. Java performance comparison

In this write-up I captured my findings about the performance of various frameworks that I was considering for my next project…

Test setup:

  • One MySQL 5.1 table consisting of an ID and 2 string columns, 1000 rows (+5 for warm-up)
  • a simple web application that:
    • reads one record from the table
    • displays record data on a web page in table form
The page is accessed sequentially 5 times to warm up the caches, then 1000 times (timed). The time is captured below.

Test subjects:

  1. PHP 5.3.3 on Apache 2.2.21
  2. Ruby 1.8.7 + Rails 3.1.3 on mongrel 1.1.5
  3. JRuby 1.6.5 (emulating Ruby 1.8.7) + Rails 3.1.3 on mongrel 1.1.5
  4. Grails 2.0.0 (Groovy 1.8.4) on Tomcat 7.0.16
  5. Java 1.7 + Spring 3 on Tomcat 7.0.23

Everything was set to ‘production mode’. Test platform: win32.

Test results:

Framework Time per request
PHP 10.6ms
Ruby/Rails 14.1ms
JRuby/Rails 16.0ms
Grails/Groovy 7.4ms
Java 6.4ms

Java seems to be a clear winner here… too bad it’s by far the slowest of the 5 to develop in! :-[]

p.s. I know my JRuby setup is awkward… I just couldn’t get any sane performance out of it on a Tomcat. The perf I got in this post is the best I could achieve.