Monday, June 29, 2009

Breach

I am an IT Consultant. Exactly what I do depends on who I'm working for because I'm capable of doing many things. The reason I'm being explicit about being a consultant is because I want you to understand that I don't have a single employer. I have clients, and depending on the contract sometimes their problems become my problem. This weekend was one of those times.

A system was compromised and for a brief period of time bad things may have happened in a client's name. Though the process of identifying, diagnosing, and fixing the problem took me less than an hour the ramifications were more far reaching than I could have imagined. It could have been a Titanic moment.

I really want to write about the who, what, where, when, and why of this experience but I'm not at liberty to do so. But one day I will be, so I'm putting this out there now as a reminder to myself to finish this conversation.

Monday, June 22, 2009

Eli's Dirty Jokes

The, Eli's Dirty Jokes, videos on YouTube are absolutely hilarious.

Monday, June 15, 2009

Stuck!

Even though the bulk of my professional writing is technical, meaning the data is mostly available I just need to put it into a format understandable by my audience (aka, the people writing the check), I still sometimes encounter writer's block. Like right now. What the hell does that mean exactly? Because here I am writing this blog entry and I'm not having any trouble finding the words to express my frustration. Maybe I'm just naive in my understanding of what technical writing demands of an author. Maybe it requires the same level of access to the creative mind as a non technical work? Who knows? Today I'm not offering answers. I'm just putting pen to paper in an attempt to find my way.

Thursday, June 04, 2009

Quote of the Day, 4 June 2009

Me? I'm going back to running the browser on my UNIX box. It's way too frustrating trying to be a UNIX Engineer via the Windows platform.

Tuesday, June 02, 2009

PGCon2009 Summary

I'm back from PGCon2009. No, I didn't just get back. I've been back for a smidgen over a week now. When I first got there I decided I would blog daily about it, but time didn't permit me to write in any detail. So I decided I would make notes and summarize it all when I got back. The notes thing didn't pan out thanks to twitter. It was simply easier to tweet my thoughts as I thought them than collecting them in little text files and revisiting them later. The summary idea didn't work out either because (a) I didn't have any notes, and (b) all the good stuff was already said on Planet PostgreSQL. But it's been more than a week since the conference and people are still posting summaries so now I feel like I have to say something. Here goes!

Great conference, awesome people, awesome community, and PostgreSQL is really cool technology that I'm confident in trusting my [clients'] data with.

My only gripe with the conference was the keynote address. It's nobody's fault really. The original speaker couldn't make it so they had to slap something together at the last minute. It showed. At the time, my thought was, if the rest of the conference is like this it's going to suck!

...

As I write this I've just realized that the keynote incident is a metaphor for the larger PostgreSQL project. If you attended or watched the "How to Get Your Patch Accepted" talk, it is apparent that quickly slapping something together is not how the PostgreSQL code base is developed or maintained. So I shouldn't have been surprised that the keynote was not a valid indicator about the rest of the conference. I hope I haven't disparaged any of the speakers. They did their best and everyone else in the auditorium enjoyed their keynote.

Wednesday, May 27, 2009

My Apologies to opensolaris.org Blogs

For the last three years all my blog posts have been showing up at http://opensolaris.org/os/blogs/, even though a big chunk of them had nothing to do with Solaris. At the time, I had no idea how to filter just the Solaris specific entries. Now that I think about it, I don't think Blogger even supported tagging back then, and without tags, filtering would have been impossible. Nevertheless, I apologize.

Yesterday I learned how to filter blog posts and today I've finally rectified the problem. There will be no more posts about how to make a great hot dog, book reviews, cloud computing notes, a rant about twitter, and other silliness.

Tuesday, May 26, 2009

PGCon2009 Postscript: Unit Test Your Database!

I started watching some of the PGCon2009 videos that I didn't attend while at PGCon. Last night I watched, Unit Test Your Database!, by David Wheeler. I have had my come to Jesus moment on unit testing years ago, so I'm really happy that there is a solution for testing strictly at the database level without depending on the application layer.

Some developers make the mistake of treating the database as a glorified file system and therefore assume it doesn't need any testing. They are wrong! From the application's point of view, the database should be a black box and application level testing of the database should be limited to the interaction between the application and the interfaces the database exposes, like stored procedures and views. In this development paradigm the database is an independent entity and therefore needs its own set of tests to ensure that it's self consistent. This is where the speaker's own testing framework, pgTAP, excels. It's not limited to just testing the public interfaces the database exposes. It allows you to validate the database itself, i.e., verify the structure of the tables in the database and their relationships, verify triggers, verify the existence of indexes, verify the existence of functions, verify the behavior of functions, etc.

If you are still on the fence about whether unit testing your database is a worthwhile endeavor then watch the video, it may convince you. But if you've already got unit testing religion and are looking for a tool for testing your PostgreSQL database then pgTAP is going to be hard to beat.

Tuesday, May 19, 2009

The Nail in the Coffin

My experimentation with Solaris/OpenSolaris is over. Amid the uncertainty that the Oracle purchase of Sun Microsystems has introduced I got some advice at PGCon2009 today that put the nail in the coffin. I asked someone, what OS was the best for running PostgreSQL? His response was, "The OS you are most familiar with". That OS is GNU/Linux.

In recent years Sun has tried really hard to change the image of Solaris from old Unix to Linux killer (specifically RedHat Linux) to Linux like. To drive the point home, the newer releases of OpenSolaris use bash as its default shell. But it's not enough. The biggest problem Sun had with shaking it's legacy image is that it's still legacy. For example, there are about 5 different flavors of the ps command in a default Solaris install. Sun was fanatic about maintaining backwards compatibility. The problem with that kind of religious fervor is that all the mistakes of the past become a permanent part of the system and haunts it in the present. So if you are a newcomer to Solaris and there is no one there to hold your hand, it is difficult to figure out what is the best way to accomplish a task or the best flavor of a particular tool to use. In essence Solaris newcomers are acutely susceptible to The Paradox of Choice.

So for all the great technology that is in Solaris, the investment in trying to learn it just isn't worth the return right now because I can do everything I need to do in Linux in a fraction of the time and with less frustration (i.e., Solaris still doesn't have a decent package manager). And in all the cases that are important to me, Linux and it's applications run faster than the Solaris equivalent.

But although the nail is in the coffin I'm not going to say goodbye. Who knows, one day I may have to call upon the Cruel Tutelage of Pai Mei and once again embrace the way of the Sun (err ... Oracle).

Choking on Birdseeds

Five days ago I joined twitter. Today I deleted my account. So called micro blogging is just not for me. It just seems totally pointless and I'm way too old to care about being hip. As far as I'm concerned if a technology doesn't make you more productive, entertain you, or help you express yourself, it's a waste of time. Twitter may be great for everybody else, it's just not for me. I'll stick to plain old blogging. It may not be sexy anymore, but it feels just right.

Friday, May 15, 2009

Going To PGCon2009

It's official. I'm going to PGCon2009. I just registered and booked my flight. It will be my first conference in quite some time. About 3 years ago me and a buddy attended a Sun Developer Day event in Atlanta. Loved the city and it's people. The event was okay. The key insight I walked away with was I should give OpenSolaris a serious look.

The fog of uncertainty that has enveloped the MySQL community and its code is the perfect opportunity to look at other solutions. So I'm going to check out what the PostgreSQL community has to offer. Does that make me some sort of database slut?

Thursday, April 02, 2009

Aspect Ratio & You

There are no shortages of libraries and toolkits available to programmers for scaling images. But if you ever find yourself in a position, as I recently have, where you need to roll your own (or maybe you are just curious) I'll explain everything you need to know about maintaining the aspect ratio of a scaled image.

When the issue of scaling images landed on me, the first thing I did was to google it. The search results were not very satisfactory, thus this blog entry.

So what are we talking about when we use the term "aspect ratio"? It's the relationship between an image's height and its width. From a programmatic point of view, the aspect ratio can tell us how much the width of an image should change if the height changes and vice versa. Aspect ratios are normally expressed in the form H:W (i.e., 1:1, 7:3, 4:5, etc). It can also be expressed as a fraction (i.e. 1/1, 7/3, 4/5, etc) and finally, for programmatic purposes, a decimal. The formula for the aspect ratio is:

A = H/W
where A is the aspect ratio, H is the height of the image, and W is the width of the image. Using a bit of algebra we can rewrite the formula to solve for any of the variables. So given that A = H/W then H = A*W and W = H/A.

Lets assume we have an 485px x 1024px image that we need to generate a thumbnail for. The first thing we need to do is determine the aspect ratio of the image:

A = H/W => A = 485/1024 => A = 0.4736328125
Lets also assume that we have this rule that says a thumbnail image must be no more than 140 pixels high. We now have enough information to figure out what the width must be in order to maintain the image's aspect ratio:
W = H/A => W = 140/0.4736328125 => W = 295.587628866
We know the new width maintains the aspect ratio because 140/295.587628866 = 0.4736328125. Now let's look at some code:
/** 
 * Scale <tt>src</tt>'s dimensions to <tt>max</tt> pixels starting w/ the largest side. 
 * 
 * @param image      The source image. 
 * @param max        The maximum number of pixels in each dimension(HxW). 
 * @param heightOnly Indicates that only the image's height should be scaled. 
 * 
 * @return The scaled image. 
 */ 
public static BufferedImage scale(BufferedImage image, final int max, boolean heightOnly) 
{ 
    if (heightOnly) 
        image = scaleByHeight(image, max); 
    else if (image.getHeight() > image.getWidth()) 
    { 
        image = scaleByHeight(image, max); 
        image = scaleByWidth(image, max); 
    } 
    else 
    { 
        image = scaleByWidth(image, max); 
        image = scaleByHeight(image, max); 
    } 
    return image; 
} 
 
/** 
 * Scale <tt>src</tt> by <tt>height</tt>. 
 * 
 * @param image The source image. 
 * @param max   The value to scale the image down to. If the current height of the image is less than <tt>max</tt> then this 
 *              method does nothing. 
 * 
 * @return A (possibly) scaled image. 
 */ 
public static BufferedImage scaleByHeight(BufferedImage image, final int max) 
{ 
    int height = image.getHeight(); 
    if (height > max) 
    { 
        int width = image.getWidth(); 
        final float aspectRatio = height / (float)width; 
        do 
        { 
            height >>= 1; 
            if (height < max) 
                height = max; 
            int k = (int)(height / aspectRatio); 
            if (k > 0) 
                width = k; 
            image = scale(image, height, width); 
        } 
        while (height > max); 
    } 
    return image; 
} 
 
/** 
 * Scale <tt>src</tt> by <tt>width</tt>. 
 * 
 * @param image The source image. 
 * @param max   The value to scale the image down to. If the current width of the image is less than <tt>max</tt> then this 
 *              method does nothing. 
 * 
 * @return A (possibly) scaled image. 
 */ 
private static BufferedImage scaleByWidth(BufferedImage image, final int max) 
{ 
    int width = image.getWidth(); 
    if (width > max) 
    { 
        int height = image.getHeight(); 
        final float aspectRatio = height / (float)width; 
        do 
        { 
            width >>= 1; 
            if (width < max) 
                width = max; 
            int k = (int)(width * aspectRatio); 
            if (k > 0) 
                height = k; 
            image = scale(image, height, width); 
        } 
        while (width > max); 
    } 
    return image; 
} 
 
/** 
 * Scale <tt>src</tt> down to height x width pixels. 
 * 
 * @param src    The source image. 
 * @param height The scaled height. 
 * @param width  The scaled width. 
 * 
 * @return The scaled image. 
 */ 
private static BufferedImage scale(BufferedImage src, final int height, final int width) 
{ 
    int type = src.getType(); 
    if (BufferedImage.TYPE_CUSTOM == type) 
        type = src.getTransparency() == Transparency.OPAQUE ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB; 
    BufferedImage img = new BufferedImage(width, height, type); 
    Graphics2D gscale = img.createGraphics(); 
    gscale.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); 
    gscale.drawImage(src, 0, 0, width, height, null); 
    gscale.dispose(); 
    return img; 
}

Wednesday, February 11, 2009

Amazon's Cloud: What is EC2?

I'm doing research on Amazon's cloud computing platform. So I'll be jotting down notes here in case this information turns out to be useful to someone other than myself.

EC2 is part of Amazon's cloud computing platform. It enables one to run a full stack (operating system, applications, scripts, etc) on one or more compute nodes. There are different types of compute nodes. Compute nodes are organized into CPU capacity (1-8 CPUs), RAM (up to 15GB), and local storage. The user can programatically start and stop compute node instances to deal w/ increasing or decreasing demand. So in the case where a single compute node may not be sufficient in satisfying demand it is the responsibility of the user to deploy application(s) that are cluster aware.

Data stored via local storage does not persist across restarts. For persistent storage one must use Elastic Block Storage (EBS) or Amazon's S3 storage service.

Links: