Tuesday, November 25, 2008

better automagic java collections

A few years ago, I started writing java code like this to automagically initialize collections of junk and stuff:

private Collection< String > values_;

public Collection< String > getValues() {
return (
null == this.values_
? this.values_ = new ArrayList<>()
: this.values_
);
}

public void setValues( Collection< String > values ) {
this.values_ = values;
}

Nowadays you can find a lot of code like this in places like JAXB generated code, etc. Where you want the consumer of the class to be able to start doing stuff like:

Wizzle wuzzle = new Wizzle();
wuzzle.getValues().add( "ok" );

But there are a few problems with this. For one thing it assumes that there is no value to having the getValues call return null. Which impacts code like:

int sum = 0;
int count = 0;
for ( Wizzle wuzzle : wuzzles ) {
if( null != wuzzle.getValues() ) {
sum += wuzzle.getValues().size;
count++;
}
}
if ( 0 != count ) {
System.out.println(
"average is "
+ ( sum / ( double ) count )
);
}

Of course, I also suddenly have created a bunch of ArrayLists I really don't need.

Now you might say: so what? And OK, but the fact is, a collection being unset (ie: null) is used in a fair number of places to perform logic or calculations.

Notice how the coolio automagic collection trick throws off my averages in this code that assumes null == wuzzle.getValues() mean "undefined."

Now I am writing (ok, generating) code like this instead:

private Collection< String > values_;

public Collection< String > getValues() {
return (
this.valuesUnSet()
? this.setNewValues()
: this.values_
);
}

public boolean valuesUnSet() {
return ( null == this.values_ );
}

protected Collection< String > setNewValues() {
return ( this.values_ = this.newValues() );
}

public Collection< String > newValues() {
return new ArrayList< String >();
}

public void setValues( Collection< String > values ) {
this.values_ = values;
}

But in order for this to really work, the code to do the average has to be changed to:

int sum = 0;
int count = 0;
for ( Wizzle wuzzle : Wuzzles ) {
if( !wuzzle.valuesUnSet() ) {
sum += wuzzle.getValues().size;
count++;
}
}
if ( 0 != count ) {
System.out.println(
"average is "
+ ( sum / ( double ) count )
);
}

The nice thing about this refactored code is that it doesn't make the assumption that "null" for a collection means uninitialized.

Instead the decision as to whether or not the Collection has been initialized is left up to the model object's implementation.

This approach removes a potentially dangerous assumption while allow automagic collections to be used without penalty.

It is a small incremental improvement on the basic design.

Friday, November 21, 2008

generating serializable classes with jaxb-maven2-plugin

So I told my pal Danny about the power and the glory that is the JAXB plugin for Maven2 and the sly way you can generate an xsd from an xml exemplar.

He had a lot of fun then he said: "how can I make the generated classes implement serializable?"

To which I responded "..."

Mystery!

Turns out, it is super easy! You can use an xjb file like so:

<jxb:bindings
version="1.0"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
jxb:extensionBindingPrefixes="xjc"
>
<jxb:bindings schemaLocation="myCool.xsd" node="/xs:schema">
<jxb:globalBindings>
<xjc:serializable uid="-6026937020915831338"/>
</jxb:globalBindings>
</jxb:bindings>
</jxb:bindings>

I ripped this off from here...

Just dump it in yer src/main/resources directory and modify yer pom.xml to look something like:

<plugin>
<groupId>com.sun.tools.xjc.maven2</groupId>
<artifactId>maven-jaxb-plugin</artifactId>
<version>1.0</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<configuration>
<generatePackage>com.cashcow.payme.xml</generatePackage>
<extension>true</extension>
</configuration>
</plugin>

The end! Go, JAXB! Go, Maven!

Wednesday, November 19, 2008

jar-czar's cse is up!

Jar-Czar's Custom Search Engine is up and kicking!

Give it a shot!

Unfortunately... something changed on the google side and now www.jar-czar.com always comes back with a 404... or it shows you the google home page...

So for now it's back to http://jar-czar.appspot.com/...

Sigh... >.<

Before I had the CSE integrated so the results were displayed in the page... have to try to get that working again, but at least it is finally working!

Monday, November 17, 2008

haxe: bresenham's line drawing algorithm

Here is quick port I did of Bresenham's famous line drawing algorigthm I did in haxe

public function bresenhamInt(
bitmapData : BitmapData
, x0 : Int
, y0 : Int
, x1 : Int
, y1 : Int
, c : UInt
) {
var steep : Bool = Math.abs( y1 - y0 ) > Math.abs( x1 - x0 );
var tmp : Int;
if ( steep ) {
// swap x and y
tmp = x0; x0 = y0; y0 = tmp; // swap x0 and y0
tmp = x1; x1 = y1; y1 = tmp; // swap x1 and y1
}
if ( x0 > x1 ) {
// make sure x0 < x1
tmp = x0; x0 = x1; x1 = tmp; // swap x0 and x1
tmp = y0; y0 = y1; y1 = tmp; // swap y0 and y1
}
var deltax : Int = x1 - x0;
var deltay : Int = Math.floor( Math.abs( y1 - y0 ) );
var error : Int = Math.floor( deltax / 2 ); // this is a little hairy
var y : Int = y0;
var ystep : Int = if ( y0 < y1 ) 1 else -1;
for ( x in x0 ... x1 ) {
if ( steep ) {
bitmapData.setPixel( y, x, c ) ;
} else {
bitmapData.setPixel( x, y, c );
}
error -= deltay;
if ( error < 0 ) {
y = y + ystep;
error = error + deltax;
}
}
}

The pseudo code on wiki pedia made it pretty painless.

Here is a little demo comparing a really crappy floating point version I did, the above and a version like the one show, but using floating point.



It draws 20k lines, so it takes it a few seconds depending on yer rig.

You can find the source code here.

Sunday, November 16, 2008

is the neko vm too slow to be used?

So I've been having a lot of haxe fun lately, but mostly in the flash direction.

But of course, haxe has another face, the server / fat-client side which is neko vm (or php).

Since I think haxe is neat, and I have been playing with the idea of a small abstraction layer to write stuff to use flash apis or openGL I wanted to see what the neko vm was like.

Well... I was a little bummed that I couldn't find anything "official", but not really surprised since it's not exacty in the top 10 list.

I decided to try the olde "Sieve of Eratosthenes" test which is generally regarded as a very naive, worthless and very easy to implement benchmark.

At this point you probably see where this is going...

sieve.c 1.542s
Sieve.java 2.899s
Sieve.hx to Flash 7.404s
Sieve.hx to Neko 20.039s
Sieve.hx to JS* 22.799s

Ouch! Of course, we can't expect the neko vm to really compete with the Java 6 JVM, but a 7x spanking really makes it look bad!

Getting spanked by Flash a 2.5x is not too impressive either... or barely beating out Javascript...

As blackdog points out, a path from haxe to the JVM may just make a lot more sense.

Unfortunately, at this point there isn't a way to get from haxe to the JVM and getting to the neko vm doesn't seem worth the bother...

:-(

BTW, I generated the php version, but couldn't get it to crank up... May add in the results later.

Thursday, November 13, 2008

Chambliss: just add swift kick to the rear

December 2nd, 2008 is a good day to give Saxby that early Christmas present he's been wanting: the firm application of the collective food of the good people of Georgia to his back side he's been wanting.

Frankly, I didn't really know much about Chambliss before the bailout that put a gun to my head and forced me to invest in the floundering mess that is AIG with some vague promises of "getting me back" someday.

Can't say I wanted to either.

I realize he's a professional politician which puts his soul about 3 rungs down from grave robber or folks who scam little olde ladies out of their pensions... oh, wait! He is in that last group too.

Well, if they could I'm sure they'd want to boot him out of their club if they could.

Hyberpole? Ok, maybe.

Why not decide for yourself?

Here is what this our darling "representative"responded when I told him not to give my money to those con artists in the financial "services" industry (my mods in brackets with italics):

We have been betrayed by many people [to whom I plan to give billions of dollars more, secure in the knowledge we can trust them now for some reason TBD] and by abuse of the system [which I have no intentions of changing since they pay for my yacht ...] The bill that I voted for is not a bailout [oh, wait... yeah it totally is, my bad! ...] this is not a popularity contest [so please shut up, get back on your tractor and let the smart guys get their graft-on ...] My first reaction was one of anger and frustration [realizing I didn't get my kick back on this fraud in advance (you try collecting from these slicksters on the back-end... oh, yeah... you will try! hahahaha I gave your hard earned dough to the worst kind of grafters who are now going to loan it back to your at 24% interest! bwhahahaha! I am pure evil! pay me, biatch!]


Now I admit, the above is somewhat colored by my own perspective on the ridiculous, wrong-headed pompous nonsense Saxby "YAWB" Chambliss had to offer up in exchange for my hard earned cash which he gave to his friends in big bidness.

So, you can read the rest here in it's original form.

The only modification I made was to remove some slight information specific to my secret identity and replace it with what I am reasonably sure was the original name in the template.

Now, I'm not advocating for Martin.

I'm not partisan because I'm not silly enough to believe that big bidness would be dumb enuff to only buy off only half of the politician.

Nor am I naive enuff to think these guys are really trying to help me.

In my experience when someone you don't know is trying to get into your bidness and help you with the contents of your wallet, it is not going to be to put more money in there.

If you follow me... you do, right? I think you do.

I would just like to encourage you at least rattle the bar of the cage a little.

Yeah, the warden isn't going to let us go for banging our collective metal cup on the bars. The guards aren't going to release us for throwing down rolls of toilet paper lit on fire.

But sometimes you have to do what you can to say "Hey! I'll rochambeau you for it!"

So please, do what you can to boot Chambliss out. And when Martin sends me the same letter in a couple of years, let's do the same for that turkey too.

Oh, btw:


However, history warns us against inaction by hard lessons learned. Delaying to act would be a repeat of the mistakes of the 1920s, when thousands of banks failed before significant confidence was restored to our financial markets.


For all the experts, politicians and geniuses who repeat this tired refrain. We have no reason to think that propping up this corrupt financial system with some temporary injection of cash is going to do anything other than make it crash down that much harder when it does crash.

You are not the little dutch boy putting his finger in the dike (I know... in the modern world that sounds really derty!)

Let's just hope 2009 doesn't come to be known as the "Greater Depression."

I'd like to conclude with...

When you are having trouble paying the bills, it's not the right time to invest in the stock market.

When you are concerned about having a job in 6 months, maybe the best use of money is to save up what you can when you can.

When you are uncertain if the bank is going to foreclose one you, don't go buy shares in a failed corporation.

Too bad Chambliss is too damned smart to know that. Or maybe just too rich.

Maybe he should ask Clark Howard what he thinks next time.

Or maybe he could listen to me: keep your hands off my cash your damned, dirty politician!

Here is the deal, I offer to one and all. It is not a new deal: mind your own bidness and I will mind mine ; the administration of the horns is predicated on the molestation the bull.

Oops! Almost forgot! Always leave off with a joke! Unfortunately, the jokes on us, but hey...