Friday, April 17, 2009

The Republic of Texas?

The governor of texas has been making noises about Texas seceding from the union. Because that worked out so well for them last time.

I'm actually in favor of a reduction in federal power. If secession is what it takes to achieve that, then maybe it's time the South rose again.

Thursday, April 16, 2009

The Derek Trucks Band in concert

Last night Scarlet and I went to San Francisco to see The Derek Trucks Band in concert. We took CalTrain and Muni to get to the venue, the Regency Center Grand Ballroom. Despite the pictures of the venue I found on the Internet, once you get inside, the place is a bit of a shithole, and the atmosphere of the concert had a lot more in common with the Primus concert I went to a few years ago than I would have expected. The air inside the hall was thick with smoke, likely none of which was made of anything legal. But all that was forgotten once the show started. The band led with the big single off their latest album, a cover of Bob Dylan's "Down In The Flood." It was a performance by the band of this song on Conan's show that got me interested in them.

The Derek Trucks Band is a bit like Van Halen, in that the leader of the band is not the lead singer. Derek Trucks is a guitar virtuoso of the first order. Many authorities, first among them Rolling Stone magazine, argue that he may be the best guitar player alive today. Tiger plays golf. Derek plays the guitar. What the two of them have in common is a mastery of their instrument that transcends the separation of the tool from its owner. Tiger shot a Nike commercial a few years ago that showed the level of virtuosity I'm talking about. The story of that ad was that they intended to shoot something entirely different, and while waiting around for the shooting to start, Tiger started noodling away with a ball, just for fun, doing exactly the sort of thing shown in the ad. He's so good that he just does things for amusement that are damn near impossible for anyone else. That's how good he is. If you get a chance to see Derek Trucks play the guitar, it becomes obvious in an instant that he has as close a connection to his instrument as Tiger has to his golf clubs.

The band played about 45 minutes worth of selections from their current album, as well as a few tunes I didn't recognize, but were still great.

Then the drummer announced, "We have a special guest joining us now. Please welcome, Mr. Carlos Santana!"

Oh my.

Carlos joined the band on stage and the drummer launched into a heavy latin rhythm while Carlos and Derek started a freestyle jam session, echoing each other's riffs back and forth. It was an awesome spectacle.

The pity was that at about 11:15 PM, we had to leave to go catch the last train home. I don't know how much longer it went on. All I can hope is that we didn't miss much of it.

We're going to bed now. It's about 2 AM. But it was worth it.

Wednesday, April 8, 2009

The bad beat of all time

Full Tilt Poker Game #_: 400 FTP Sat to Sun. Brawl Sat (_), Table 1 - 50/100 - No Limit Hold'em - 23:08:59 ET - 2009/04/08
Seat 2: hero (9,210)
Seat 5: villain (4,290)
villain posts the small blind of 50
hero posts the big blind of 100
The button is in seat #5
*** HOLE CARDS ***
Dealt to hero [2c 8h]
villain calls 50
hero checks
*** FLOP *** [Jh 2h Th]
hero bets 200
villain calls 200
*** TURN *** [Jh 2h Th] [9h]
hero checks
villain checks
*** RIVER *** [Jh 2h Th 9h] [Qh]
hero bets 100
villain raises to 900
hero raises to 2,000
villain raises to 3,990, and is all in
hero calls 1,990
*** SHOW DOWN ***
villain shows [7s Kh] a straight flush, King high
hero mucks
villain wins the pot (8,580) with a straight flush, King high
*** SUMMARY ***
Total pot 8,580 | Rake 0
Board: [Jh 2h Th 9h Qh]
Seat 2: hero (big blind) mucked [2c 8h] - a straight flush, Queen high
Seat 5: villain (small blind) showed [7s Kh] and won (8,580) with a straight flush, King high

Someone please kill me now.

Thursday, April 2, 2009

Gzipped JMS message bodies

If you want to send large messages with JMS, it is probably a good idea to compress them, assuming they contain data that's compressible (particularly effective with XML payloads). This is a natural fit for JMS BytesMessages, and compression is easily done with GZIPInputStream and GZIPOutputStream.

When I first did this, I used ByteArrayInputStream/ByteArrayOutputStream as the stream feeding the GZIP stream, but the problem with that is that you have to copy the underlying byte array into or out of the message in its entirety. This represents an extra buffer copy that in principle is not necesary. BytesMessage provides byte buffer I/O. Unfortunately, it doesn't conform to the InputStream / OutputStream interface directly.

So the fix is to shim BytesMessages using what I call BytesMessageInputStream and BytesMessageOutputStream. Once you shim the BytesMessage to a stream, you simply use that stream in the constructor of a GZIP stream and you're ready to go. Once the data has been written to the GZIP stream and that stream closed, the message can be sent or acknowledged, depending on which direction you're going.


public class BytesMessageInputStream extends InputStream {
private final BytesMessage message;
public BytesMessageInputStream(BytesMessage bm) { this.message = bm; }
public boolean markSupported() { return false; }
public int read() throws IOException {
try {
return this.message.read();
}
catch(MessageEOFException ex) { return -1; }
catch(JMSException ex) { throw new IOException(ex); }
}
public int read(byte[] buf) throws IOException {
try {
return this.message.readBytes(buf);
}
catch(JMSException ex) { throw new IOException(ex); }
}
}
public class BytesMessageOutputStream extends OutputStream {
private final BytesMessage message;
public BytesMessageOutputStream(BytesMessage bm) { this.message = bm; }
public void write(byte b) throws IOException {
try {
this.message.writeByte(b);
}
catch(JMSException ex) { throw new IOException(ex); }
}
public void write(byte[] buf) throws IOException {
try {
this.message.writeBytes(buf);
}
catch(JMSException ex) { throw new IOException(ex); }
}
public void write(byte[] buf, int off, int len) throws IOException {
try {
this.message.writeBytes(buf, off, len);
}
catch(JMSException ex) { throw new IOException(ex); }
}
}

Wednesday, April 1, 2009

java NVL function

NVL is a function in Oracle PL/SQL that is more or less this:

NVL(a,b) ==> (a == null)?b:a

And that's all well and good. The only problem occurs when the value of a either has side effects or either a or b are long and complex. You could write


foo a = ... long complicated code with possible side effects ...
foo b = ...yadda yadda yadda...
a = (a==null)?b:a;


But wouldn't it be easier to read as



a=nvl(... long complicated code with possible side effects ..., ... yadda yadda yadda ...)

?

Well, nvl() is easy to write, except that Java wants the arguments to be strongly typed.

Or does it?

You can declare the arguments are return as Object, but then you have to cast the return, and the compiler will not protect you from type mismatches.

The solution is generics. Write nvl like this:


public <T> T nvl(T a, T b) {
return (a == null)?b:a;
}


Mischief managed. The compiler will guarantee that there can be no type clashes, and so long as the same type is used for the two args and return, you're good to go.

iPhone 3.0 firmware update released early

Looks like Apple has released the iPhone 3.0 firmware a bit early. Now we can finally use Stereo Bluetooth headsets to listen wirelessly to music! Check out Apple's iPhone page for all the juicy details.