Measuring Wins

January 10th, 2012 Comments off

As a follow-up to Saturday’s post and last night’s BCS title game, I was asked about RPI rankings for this year.  Strength of schedule and RPI are particularly important for NCAA football where, in this era of “buy games” and weak conferences, win-loss records must be taken with a grain of salt.  It’s not just about how you play, but also who you play.

So I gathered 2011 NCAA data and ran it though the RPI programs we coded as Friday Fragments this time last year; see: http://derekwilliams.us/fragments/rpi.html.  The top 10 teams by RPI are:

Rank Name Record Win % RPI
1 LSU 13-1-0 0.929 0.701
2 Alabama 12-1-0 0.923 0.676
3 Oklahoma St. 12-1-0 0.923 0.670
4 South Carolina 11-2-0 0.846 0.643
5 Arkansas 11-2-0 0.846 0.638
6 Kansas St. 10-3-0 0.769 0.634
7 Baylor 10-3-0 0.769 0.633
8 Oklahoma 10-3-0 0.769 0.631
9 Michigan 11-2-0 0.846 0.630
10 Oregon 12-2-0 0.857 0.626

Teams like Stanford, Boise State, and Wisconsin aren’t in this top ten.  That’s because, with their low strength of schedule ratings, the computer just doesn’t like them.

Share This:
  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Bookmarks
  • Google Buzz
  • RSS
Categories: Programming Tags: ,

Playoff Prognostication

January 7th, 2012 Comments off

“Prediction is very difficult, especially about the future.”

Niels Bohr

It’s NFL playoff time again, and seemingly everyone’s prognosticating.  Last year’s late rise of the Packers (6th seed who won it all) proved again that “past performance does not guarantee future results.”  But since a calculated guess is better than a wild one, I thought I’d run my own numbers using the power ranking tools we developed as Friday Fragments this time last year.

I gathered fresh data (2011 NFL regular season results) and ran it through http://derekwilliams.us/fragments/tourney.html.  Of the resulting top 12 teams (by power ranking), 11 are in the playoffs:

Rank Team Power
1 Packers 90
2 49ers 86
3 Saints 83
4 Steelers 83
5 Ravens 70
6 Bengals 68
7 Texans 67
8 Patriots 67
9 Giants 64
10 Lions 63
11 Falcons 61
12 Raiders 56

The Raiders (#12) didn’t make the playoffs; instead we have the Broncos who won the AFC West, but rank #22 (power 41).

This has the Packers winning it all again.  But with my Falcons at #11, I’m hoping for a few surprises, starting with tomorrow’s game against the Giants.

Share This:
  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Bookmarks
  • Google Buzz
  • RSS

Just Concentrate

December 14th, 2011 Comments off

In most cases (at least for OLTP systems), using SQL parameter markers instead of literal values improves performance, adds consistency, reduces CPU overhead, and makes the database easier to monitor.  SQL parameters let DB2 cache the access plan so that compilation only happens once and execution counts are combined for the same statement.

A transaction system that carelessly uses literals can often be improved by converting literals to markers wherever possible.  But since this recoding takes time, it would be nice to predict the performance impacts (hopefully benefits) of such a change without having to just code it all and then measure.

Fortunately, DB2 9.7 offers the new Statement Concentrator to do just that.  Enabling it at the database level is easy:

db2 update db cfg for DATABASE using stmt_conc literals

And you can see if it’s enabled with:

db2 get db cfg for DATABASE | find /i “stmt_conc”

I suggested this new feature to a colleague today, and did some experiments myself.  It was nice to see the statements combined in the Dynamic SQL Snapshots, and also see the (zero-execution) literal versions separated out.  This means I’ll have to update my snapshot analysis tools which combine similar SQLs.

But the nagging feeling remains that this might be too broad a change.  For some SQLs, those unique (literal-driven) access plans are necessary.  But it may be possible to reach a good balance by enabling the statement concentrator at just the right level and by using optimization profiles for those exceptions to the rule.  That’s something worth concentrating on.

Share This:
  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Bookmarks
  • Google Buzz
  • RSS
Categories: DB2 Tags:

Wait for it

November 22nd, 2011 Comments off

“If there are enterprise beans in the application, the EJB deployment process can take several minutes. Please do not abandon all hope while the process completes.”

WebSphere deployment message (paraphrased)

Of all the many ills of EJBs, slow deployments are among the most chronic.  New products like JRebel attempt to reduce this time impact, but with inconsistent results.  And hot-swapping code while debugging often fails for all but the most trivial changes.  So if each significant code change requires a long wait for redeployment, it at least better work.

That’s why today’s deployment failures were so annoying.  I could see from console logs that RMIC was running and there were no errors, but the EJB stub classes were missing from the resulting JARs.  This was a new MyEclipse workspace (Blue edition, version 9.1), but I had never had this problem before.  I re-checked my configuration and verified that I had enabled EJBDeploy for my WebSphere 6.1 target server (Properties – MyEclipse – EJB Deploy).  Yet in the process of poking around and checking things, I stumbled on the problem.  While there, I kicked off a manual run by clicking “Apply and run EJB Deploy” and finally got an error message: it could not create the files because it needed the .ejbDeploy sub-folder under my workspace path.  I manually created that folder and it worked.

I don’t know why MyEclipse or ejbdeploy couldn’t just create the folder, nor why it wouldn’t report the error to the console during normal deployments.  But since this manual work-around resolved the problem, I’ll know what to do next time it happens.

Problem solved, and back to waiting on deployments again.  Thanks… I think.

Share This:
  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Bookmarks
  • Google Buzz
  • RSS
Categories: Programming Tags: , ,

DB2 in Cygwin

September 29th, 2011 Comments off

I often use Cygwin with ssh and putty to remote into various Windows servers. It’s a lot quicker than Windows Remote Desktop and, well, I’m a command line junkie.  But since db2cmd defaults to launching a new window/session, it doesn’t play nicely with ssh.  Sure, I could remotely attach or catalog the node and database, but that defeats the purpose of being quick and simple.

To work around this, I add the following alias to my .bashrc:

alias db2=’db2cmd -i -w -c db2′

It’s imperfect (it works only for isolated commands or scripts), but it’s great for quick commands.

Share This:
  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Bookmarks
  • Google Buzz
  • RSS
Categories: DB2 Tags: , ,

Please Design Responsibly

September 26th, 2011 Comments off

Handled correctly, loose typing can be a powerful thing , but with great power comes great responsibility.   The license to enjoy the benefits of dynamic typing comes with the responsibility to actually design with real objects.  If one just strings together collections of simple types, weaker typing can lead to some very confusing code.

I was reminded of this today in an improbable way.  I uplifted some old, unfamiliar code to a modern Java version, which included adding in generics: taking untyped collections toward strongly-typed ones.  This meant grokking and stepping through the code to infer data types where nested collections were used, and it smoked out what the design really looked like.  One commonly-used structure came to this, and there were several others like it:

 HashMap<String, HashMap<String, HashMap<String,
                           HashMap<String, HashMap<String, Vector<String[]>>>>>>

Wow.  I wish I was joking.

This just screams, “make objects!”  It reminded me of perhaps why the “everything in triplicate” crowd fears dynamic typing.  If you aren’t designing with objects, then strong typing partly saves you from yourself.  In this case, the addition of crazy nested generics actually made the subsequent code easier to understand and less error-prone.

But a much better approach, of course, is to create new classes to handle what these nested collections do, with the added benefit of factored behavior.  In this case, the real objects exist very plainly in the problem domain; just follow the nouns.  A truly object-oriented design usually doesn’t need strong typing to clarify the design.

This does require diligence and I’ve often been guilty of missing objects, too.  Yet perhaps this example reveals a new code quality metric: if you need more than two adjacent angle brackets to make the “raw type” compiler warnings go away, it’s time to step back and look for objects.

Share This:
  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Bookmarks
  • Google Buzz
  • RSS
Categories: Programming Tags: , ,

Merging Git and CVS

September 15th, 2011 Comments off

Today I found myself needing to run ahead of the current stream of development and code some things to be merged in later.  I needed the flexibility of easy branching and merging atop a code base that’s maintained in CVS.   CVS branches are overkill and Eclipse/CVS change set grouping is too limited.  What I really wanted was Git, but migrating wasn’t an option, and doing a full git cvsimport would take forever.  I just needed simple local changesets atop the shared CVS repository.

Fortunately, I stumbled across a simple workflow by Kris Johnson that met my needs perfectly.  I used it with a few minor variations, such as synching (cvs update) differently, using TortoiseCVS for a few operations, and doing the final commit via Eclipse (so that I could get one last look at the changes in the Synchronize view).  But it’s a very helpful process that I’ll hang on to.

While I’m jotting things down, here’s the .gitignore I created for the Eclipse/Java projects I’m working on.

CVS/

bin/
*.class
*.jar
*.zip

*.~
*.dat
*.cache
*.lock
*.log
*.out
*.swp
Share This:
  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Bookmarks
  • Google Buzz
  • RSS
Categories: Programming Tags: , ,

Tricky Wiki

September 14th, 2011 Comments off

A key agile principle is to do the simplest thing that could possibly work.  So it seems paradoxical that as Agile grows, so does the number of increasingly-complex tools to manage the process.  Yet a great way to manage Scrum artifacts (backlogs and burndowns) remains the simple wiki.  To this end, ComSwiki has worked well for me, as it is lightweight, flexible, and fast.

But new corp-rat standards require that I use SharePoint to the degree that “if it’s not in SharePoint, it doesn’t exist.”  So I had the admins create a SharePoint Wiki for my team, and started filling it up with backlogs, how-to’s, and other content.

Frustration soon followed as simple editing often requires deleting text and starting over.  The SharePoint Wiki’s WYSIWYG editor (only available in Internet Explorer) tries to be useful, but often just gets in the way.  For example, try adding a row or column to an existing table: it can’t be done.

Not to be deterred, I turned SharePoint’s limitation into a feature.  The WYSIWYG editor doesn’t work in Chrome and instead pops up a simple text box with the raw, ugly, generated HTML.  Yet I can edit this HTML to do things that the WYSIWYG editor won’t.  So, I now typically keep both Chrome and IE open on the same page and switch back and forth depending on what sort of editing I need to do.

It’s a stone-age approach, but then again, SharePoint is a stone-age tool.  Hopefully, the WYSIWYG editor will be improved and expanded in future releases, but until then, it would have been better for Microsoft to take a “simplest thing” approach.  That is, support the simple markup language of ComSwiki and other wikis rather than attempt a (mostly broken) WYSIWYG editor.

Share This:
  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Bookmarks
  • Google Buzz
  • RSS
Categories: Programming Tags: ,

Not Listening

August 10th, 2011 Comments off

DB2 9.7 seems to have brought back an old problem: DB2 servers that are deaf to TCP/IP connections.  In today’s action, my JDBC connections on a new Windows DB2 9.7 configuration were hanging for several minutes and then eventually failing with a “connection refused” error.  Since such problems are usually due to configuring the wrong port, I verified it:

db2 get dbm cfg | find “SVC”

type %WINDIR%\system32\drivers\etc\services | find /i “db2″

I had specified the right port: the standard 50000 default for the first instance.  And all the standard DB2 tools connected to the database just fine, including CLP and CLI connections.  After checking all the wrong places, I finally looked to see if DB2 was actually listening on this port:

netstat -an | find “500″

telnet localhost 50000

It wasn’t: I got no relevant matches on the netstat and telnet gave the “connect failed” error.  I checked DB2COMM and found it didn’t include TCP/IP.  Weird.  So I quickly remedied that with:

db2set DB2COMM=tcpip & db2stop & db2start

And verified with:

db2set -all db2comm

I’m not sure why some recent new DB2 9.7 installs didn’t have TCP/IP connections enabled by default.  Usually, it’s the setup/db2setup default.  But it’s something I’ll watch for, with a quick solution next time.

Share This:
  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Bookmarks
  • Google Buzz
  • RSS
Categories: DB2 Tags:

The Flash Cache Flush

July 30th, 2011 Comments off

We all endure software that seems to grow worse with each upgrade; for me, that includes Ubuntu, the Weather Channel App, and Flash.  I try clinging to the “oldies but goodies” for as long as I can (for example, I use my 9.10 Ubuntu VM far more than my 11.04 one), but forced upgrades are usually inevitable.  Flash is one very necessary evil that must be kept current: it’s either upgrade or stop using some sites.

After a brief period of continually-improving releases, Flash is giving me fits again, at least with the 10.3 version.  I’m again getting bizarre behavior with sites like Nike+, requiring periodic work-arounds.  One often effective fix for Flash problems is to clear its cache.  Fortunately, that’s a quick process:

  1. Open the Flash Settings Panel by hitting this URL: http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager07.html.
  2. Scroll through the Websites list to locate and select the site with “issues.”
  3. Click Delete Website.

This often clears things up.

This handy URL shows the installed flash version.

Share This:
  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Bookmarks
  • Google Buzz
  • RSS
Categories: Lifehacks Tags:

Summer Running

July 26th, 2011 Comments off

“Heat, hills, and humidity.  Welcome to Atlanta.”

Run Atlanta slogan

While summer adds heat to the challenge of running, it also brings time in the schedule for racing.  My daughter Lydia and I ran several races over the past couple of months; here are a few of them.

Celebrate America 10K

For Memorial Day, we ran the Celebrate America race at Alpharetta’s Northpoint Mall.  This 16th annual event was well organized and equipped, making for a smooth race of nearly 900 runners.  The course was pleasant – a loop on tree-lined streets around the mall area, with a few rolling hills.  The 10K was a double loop, which provided an extra benefit for me: I was able to watch Lydia cross the 5K finish line as I started my second time around.  Lydia won her age group in the 5K at 25:00; my 10K time was 53:02.

There were several Memorial Day races in the area, and I’m pleased that we chose this one.  We’ll watch for it again next year.

ATC Fathers Day 4 Miler

The Atlanta Track Club (ATC) held its annual Fathers Day 4-Miler on Saturday, June 18, the day after Tina and I returned from our 25th anniversary trip.  It had the benefits of being free for ATC members and ending inside Turner Field: the Braves home plate area makes a great place for the finish line.

The course was well-planned, through the historic neighborhoods of downtown Atlanta, past Grant Park and the Atlanta Zoo.  There were some challenging uphills, but good downhills to recover.  I enjoyed running alongside Lydia the entire time and crossing the finish line together.  I was proud of her for doing well on the 4 mile distance and hilly course.  Our team finished 22nd overall at 36:47.

Peachtree Road Race

No other race matches the excitement of the world’s largest 10K.  And with 60,000 runners, the 42nd annual Peachtree Road Race was the largest yet.   On July 4, Stephen and Lydia ran the Woodstock Freedom Run, while I headed downtown for the Peachtree.  Getting there is the hardest part: waking in the darkness of 4:00 am and driving to the nearest Marta rail station before the parking lots fill up.

The new time groups make the crowds manageable: it becomes more like 22 serial races of about 3,000 runners each than a mob of 60K.   I was in corral C which, fortunately, is one of the four start waves with access to the starting line area.  This provided more space to relax and explore and enjoy the pre-race activity and wheelchair division start.

Another first this year was a flyover by three F-16s to close the national anthem – a flyover at a 10K – how cool is that?  That added to the excitement of the start, which continued throughout the race.  The entire course is lined with bands, giveaways, spectators (over 100,000), TV and radio stations, costumes, and some unique Independence Day celebrations.  As my college “stomping grounds”, the route also brought back many memories.  All this carried me along so that it felt more like a celebration than a race.  I hardly noticed the heat and “cardiac hill.”

There’s quite a bit of “sideways running” to weave around crowds and dodge fire hoses, so the Peachtree isn’t a race for PRs.  I kept an even pace and finished at 54:01, par for the Wave C course.

This race just gets better every year, and the current ATC leadership is doing a great job of implementing smart improvements.  Taking the AJC’s post-race poll revealed a lot of popular suggestions: tweak the start waves for groups, switch to a technical T-shirt, start earlier.  But, even if nothing changes, I’ll be back next year: me and 60,000 fellow runners.

Etowah River Run

The annual Etowah Swelter River Run balances the benefit of a fast course with the challenge of late July heat.  This year, like last, was certainly no exception: race time weather was at 77 degrees with 91% humidity, but that was offset by the signature opening downhill run and flat-as-a-pancake route.  This was the third year running it for Lydia and me; she finished first in her age group at 25:06, while I came in at 24:23.

The race held many familiar positives: fast course, helpful volunteers, good local turnout (about 500 runners, including a few cross country teams), nice T-shirt design (a repeat of last year’s popular art), valuable and plentiful door prices, and close proximity to home.   This year’s introduction of D-tag chip timing was a nice improvement.  I’d like to see the race start earlier to beat some of the heat, and a technical (rather than cotton) T-shirt would be nice.  As in years past, a few runners complained that the course was a little long (from 3.18 to 3.22 miles), but that narrow discrepancy is really only a concern to folks looking for new PRs.  We’ll be back again next year, pushing the pace against the heat.

Share This:
  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Bookmarks
  • Google Buzz
  • RSS
Categories: Family, Running Tags:

Node.js

July 18th, 2011 Comments off

A lingering sense of abandonment dating back to Netscape’s LiveWire leaves me leery of server-side JavaScript (SSJS).  Not that it’s a bad idea, it just didn’t gain traction.  JavaScript as a language is great but, by design, it lacks built-in I/O support and other things required for writing servers.  And with no standard platform to fill these holes, JavaScript remained relegated to sandboxes, mainly browers and system extensions.

That’s all been changing as SSJS proponents have rallied around Node.js, a toolkit for easily building scalable event-driven servers running atop Google’s V8 JavaScript Engine.  It was easy to ignore Node’s initial hype, but when I found myself needing to serve up some new REST APIs, I thought I’d check it out.  Besides, my AJAX calls can point anywhere, so there was really no risk in trying.  If it didn’t work out, I could always abandon Node and fall back to something more conventional, maybe even EventMachine.

Getting started was quick and easy.  Cloning and building takes only a few minutes; even faster, binaries are just a sudo apt-get install away.  There are many online tutorials, so I worked through the obligatory web server and other examples.  There’s not a lot going on in my services, so I couldn’t factor them into many event-driven/parallel fragments.  But I quickly got a feel for doing things the Node way: spinning off handlers, writing callbacks, and even running multiple node processes.  With help from Node’s non-blocking libraries, that single-threaded event loop wasn’t a bottleneck.

It didn’t take long to complete my work, so I quickly got to the question of deployment.  Sure, I have VMs out there where I can run whatever I want, but I needed this running under my jailed hosting service.  The awesome Heroku service now supports Node, but I stopped short of rolling it out there.  So I’m keeping it local now as I build out the other pieces.

Node has come a long way fast and appears to have a bright future.  It has a rich and growing ecosystem of basic modules and frameworks for web apps/MVC, content management, blogs, comet, etc.  Time will tell how pervasive Node becomes, but for shops wanting JavaScript all the way down, it’s a very nice platform choice.

Share This:
  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Bookmarks
  • Google Buzz
  • RSS

Implicit Casting

July 13th, 2011 2 comments

Co-worker Bob and I were surprised to find today that DB2 9.7 accepts SQLs like the following:

select count(*) from syscat.tables where tbspaceid = ’0′

In all prior DB2 versions, comparing an integer column with a string constant (or anything similar) would yield the error:

SQL0401N  The data types of the operands for the operation <operator> are not compatible or comparable.

The source of this new flexibility is DB2 9.7′s implicit casting, yet another feature added in the quest for greater Oracle compatibility.  The DB2 documentation clumsily introduces it:

Version 9.7 introduces support for implicit casting. Implicit casting is the automatic conversion of data of one data type to data of another data type based on an implied set of conversion rules.

Automatic type conversions (yea, duck typing even) are a good thing, but require care when arriving late to an installed base.  We developers are now on DB2 9.7, but have to support DB2 versions as far back as 9.1.  It’s now too easy to write SQL that will “work on my machine” but not on the older versions of DB2 that our customers run.

Once everyone is at DB2 9.7 and higher, this will be a non-issue.  IBM’s usual policy with breaking DB2 compatibility is to provide registry settings or other means of disabling the change, often leaving it disabled by default for some time.  But that doesn’t seem to be the case here.  I couldn’t find a mechanism to turn off implicit casting for now; if you know of one, please pass it on.

Share This:
  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Bookmarks
  • Google Buzz
  • RSS
Categories: DB2 Tags:

Solarized

May 4th, 2011 Comments off

The standard syntax highlighting in gvim is fine for short stints, but it can grow tough on the eyes after awhile.  At just the right moment last night (after a long day that brought eyestrain to a peak), Douglas Putnam’s most excellent blog pointed me to Solarized, Ethan Schoonover’s well-designed color scheme alternative.  I browsed the screen shots and then wasted no time adding it to gvim, like so:

git clone https://github.com/altercation/vim-colors-solarized.git

Copy files to my Vim folder

Edit _vimrc to add the following:

syntax enable
set background=light
colorscheme solarize

The Linux setup is similar; just copy to .vim and edit .vimrc.

I used the menu to switch between light and dark backgrounds whenever I needed an eye-relaxing change of pace, and for some languages.  I like it so much that I’ll probably add it to my terminals soon.

If life in gvim Technicolor is wearing you out, I suggest giving the Solarized color scheme a try.

Share This:
  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Bookmarks
  • Google Buzz
  • RSS

More DB2 Snippets

May 3rd, 2011 1 comment

To paraphrase David Byrne, you may find yourself behind the wheel of a large database in another part of the world asking, “how do I work this?”  Such was the case today with a customer database suffering a performance hiccup.  It had the symptoms of improper tablescans, but there was no time to enable snapshots, run explains, or do detailed analysis.  It needed a quick sanity check of statistics, indexes, and organization.  A few basic commands flushed out the problem: a required index was missing.

I’ve recorded various common DB2 Snippets here before, but had not yet included today’s common mantras.  So, I’ll extend my DB2 pastebin with these useful snippets…

Check for missing indexes

This will give you a quick index inventory to compare with your expectations.  Substitute for MYSCHEMA and MYNAMES.

select tabname, indname, colnames from syscat.indexes where tabschema = ‘MYSCHEMA‘ and tabname like ‘MYNAMES%’ order by tabname

Check for recent runstats

See when statistics were updated for your tables, if at all.  Substitute for MYSCHEMA.

select ‘   ‘ || substr(rtrim(tabschema) || ‘.’ || tabname, 1, 40), stats_time from syscat.tables where type = ‘T’ and tabschema = ‘MYSCHEMA‘ order by stats_time

If statistics are out of date or missing, then runstats is the obvious remedy.  If you only have CLI/ODBC access (no CLP), you can call runstats via the admin_cmd proc; substitute for MY.TABLE and tweak the statistics options if needed:

call admin_cmd(‘runstats on table MY.TABLE with distribution and indexes all’)

Generate a runstats script

Don’t let outdated statistics fool you more than once – automate and change-proof the process.  One option is to enable DB2′s auto runstats, but that has its limits.  Another common solution is a cron job or scheduled task kicking off a fixed set of runstats commands.  Good idea, but you must update the script each time you add a table.  You can go one step further with a script to generate the runstats commands for all tables matching a certain criteria, and then call the generated script, all from a cron job.  Something like this:

db2 -x “select ‘runstats on table ‘ || rtrim(tabschema) || ‘.’ || tabname || ‘ with distribution and indexes all allow write access;’ from syscat.tables where type = ‘T’ and tabschema in (‘MYSCHEMA‘ ) order by tabname with ur” >> %GeneratedScriptName%

db2 -tvf %GeneratedScriptName% >> %GeneratedScriptName%-out.txt

You may want to reduce runstats frequency for the more static tables.  If so, add name, time, and other criteria like the following:

db2 -x “select ‘runstats on table ‘ || rtrim(tabschema) || ‘.’ || tabname || ‘ with distribution and indexes all allow write access;’ from syscat.tables where type = ‘T’ and tabschema in (‘MYSCHEMA‘ ) and tabname like ‘MYNAME%’ and ((stats_time is null) or (stats_time < current timestamp – %SinceMinutes% minutes)) order by tabname with ur” >> %GeneratedScriptName%

Perhaps you’ll find these incantations (or variations of them) useful as the days go by.

Share This:
  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Bookmarks
  • Google Buzz
  • RSS
Categories: DB2 Tags:

Reiser and Run

April 27th, 2011 Comments off

While working through today’s code and test to-do list, I ran out of space on a required SLES 10 file system.   Fortunately, it was LVM-managed, and there was plenty of room in the volume group to stretch this thing.  I vaguely recalled just enough LVM command names (lvdisplay, lvresize) to look up the process.

Extending the logical volume was super-fast, but resize2fs failed with “can’t resize a mounted filesystem!” No way!  This was a 2.6.16 kernel: not exactly hip, but current enough to allow online resizing.

I checked mount points and saw that this was a reiserfs file system.  ReiserFS?!  Sure, that was once the SLES way, but I thought it had been deprecated since the arrest, if not for murder-related reasons, then for security and/or functional ones.  Fortunately, the LVM HOWTO rescued me: it told me to use resize_reiserfs instead, and that worked like a charm.

I’ll try to remember this in case there’s a next time.  If not, this blog post will remind me. :-)

Share This:
  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Bookmarks
  • Google Buzz
  • RSS
Categories: Programming Tags: , , ,

Find a Bug, Code an xUnit

April 18th, 2011 Comments off

In today’s travels, I ran into an important bug in a new feature that had been missed in test.  One reason for the late discovery was that setting up and re-creating the problem in “black box” mode was time-consuming: change profiles, load and decision new work, complete a full processing cycle, create end of day files, and so on.  Yet at its core, it boiled down to only four possible permutations of inputs through a single business object method, and one of these four behaved badly.

This was, of course, the perfect opportunity for an xUnit: a short method could test all four permutations and prove the bug.  So, in classic TDD fashion, I coded the test case first and then fixed the business object to turn yellow to green.  This bug had escaped not because creating a SUnit was difficult, but because it had been overlooked.

In any system, there are lots of test scenarios (such as deep integration) that cannot be approached by xUnits.  But there are usually many more valuable xUnits that could be written than actually are.  Like refactoring, there’s never time to go back and add xUnits to old code just to do it.  But bug discovery is the perfect opportunity, and xUnits here are not only good policy, they help with coding and verifying the fix.  So, find a bug, code an xUnit.

Share This:
  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Bookmarks
  • Google Buzz
  • RSS
Categories: Programming Tags: ,

In Words of One Syllable

April 13th, 2011 Comments off

The Windows CMD shell is a primitive language, particularly when compared to unix scripts or even PowerShell.  But it’s still the only guaranteed-available common denominator for Windows servers (no, WSH doesn’t count), so I have to target it for setup scripts delivered to customers.  When it comes to database activities, I limit this as much as possible by writing portable DB2 CLP SQL files, but that runs out of steam when I need loops, parameters, etc.  So I found myself this morning once again bumping up against CMD’s limited vocabulary.

In this case, I needed a multi-line block of SQLs to run in a loop.  The begin-end construct for CMD scripts is a pair of parentheses.  But my SQLs themselves needed parentheses (as SQLs often do), and I found that Windows doesn’t support nesting them; it failed with a the error message: <statement> was unexpected at this time.  No nested parens: just wow.  At least the workaround was simple – just move these commands into a sub-script and call it, like so:

   for /l %%i in (1,1,9) do (
      echo.  ==Pass %%i >> %OutputFilename%
      call ReplicatePass.cmd %%i >>%OutputFilename%
      if errorlevel 1 goto failure
   )

I look forward to the day when I can count on PowerShell or a similar robust scripting environment to be available on all Windows platforms I target.  Perhaps attrition alone will accomplish this; after all, it has only taken three decades.  Until then, I’ll speak slowly to Windows, in words of one syllable.

Share This:
  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Bookmarks
  • Google Buzz
  • RSS
Categories: Programming Tags:

Run at the Mill

April 9th, 2011 Comments off

Racing today was an easy decision, with a rare Saturday off from coaching (compliments of spring break), a race just 4 miles from my dad’s house, and cool half marathon medals with Hebrews 12:1 on the back.  And the first annual Run at the Mill (part of the Run for God series) was a winner!

Lydia and I rode up together the night before and spent the evening at my dad’s home.  We made a Pizza Hut stop on the way: “carb loading,” we said, but any excuse would do.  After arriving, we enjoyed a nice evening just chatting and hanging out.

My half marathon start time was 90 minutes before Lydia’s 5K start, so Dad was gracious enough to shuttle Lydia over, dropping her off just before her race, and even bringing over my dropped race bib earlier.  Did I mention how nice it was to be only 4 miles away?  It was so humid I had to use the car wipers while driving, but at least the temps were in the low 60s.  Pollen counts were off the scale, but that’s a small price to pay for a very beautiful wooded setting.

Combination race, ministry, and country fair

Prater’s Mill is out of the way, but I can hardly imagine a better place to hold a half marathon.  The course was scenic, along country roads past pastures, homesteads, and rocky streams.  Since this is a mountainous area (north of Dalton and very near the Tennessee line), I expected many steep climbs, but it was actually quite flat: mostly gently rolling hills with just a couple of long uphills.  This run in the country was so pleasant that I spent the first several miles with the MP3 player off, listening to singing birds and other morning sounds.

At 9:46, the first mile was my slowest, as I navigated through running traffic.  I kept thinking I should have started closer to the front, but at least it forced me to start at a measured pace.  In the end, I definitely negative-split this thing.

T-shirt, 1/2 marathon medal, and bib

Miles 1-3 took us up some of the longer climbs and past the aptly-named Strain Road.  Around mile 4, the fog began lifting, leaving very low clouds with sunlight streaming through, painting the countryside in bright gold.  If only Tina could have been there with her camera!  Shortly afterward, we were chased by some yap dogs, but they were all bark and no bite, succeeding only in adding humor and speed motivation.

After about the 10K mark, we were treated to some nice downhills, and then mostly level territory until about mile 11.  Mile 8 was a turnaround: not my favorite, but it offered the chance to see where I stood against other runners.

I had recently recalibrated my Nike+ on a flat course, which left it confused on these hills.  On average, it reported nearly 10% too much distance, since it did not account for my shorter uphill strides.  But the course’s consistent, well-marked milestones helped me adjust.

Lydia finished first in her age group

After mile 11, we hit another uphill stretch, which troubled my left knee.  So once I cleared mile 12, I checked my time and, seeing I was in great shape to finish at my sub-2 goal, dropped my pace significantly, perhaps a little too much.  As I approached the final tenth, I could see the race clock and hear a volunteer shout, “hurry and you’ll beat 2 hours!”  So I kicked into a final dash (a sub-6:00 pace) and finished at 1:59:50.  Lydia had just finished her 5K and met me at the finish line.

Looking around, I could see the post-race activities in full swing.  The grounds around the river and historic buildings were filled with bounce houses, booths, concessions, and a talented praise band playing in the pavilion.  Joining the racers were many families and other visitors, giving the place the feel of a combination race, ministry, and country fair.

Cornbread: another reason to recycle

Lydia was excited about her strong running, so we checked and found she ran the 5K in 25:57, finishing first in her age group!  She received a very nice award for that.

Lydia takes on the 5K

Overall, this race had a lot going for it: scenic course, nice venue, valuable ministry, abundant post-race activities, small town hospitality, plenty of helpful volunteers, top-notch timing system, and great execution.

For all the promotion and activities, this was still a small race: just over 600 runners.  I would like to see it grow, and I have a feeling that once the word gets out, it will.  There was a registration cap for this first annual race; I hope they can expand and accommodate a larger group next year.

Share This:
  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Bookmarks
  • Google Buzz
  • RSS
Categories: Family, Running Tags: ,

Git It

April 4th, 2011 Comments off

I recently received a request to push some of my recent Friday Fragment code out to github to make it simple for folks to pull it.  Not a bad idea, so I did that tonight.  If you’re interested, see https://github.com/derekwlms and clone away.  If/when Friday Fragments resume, I’ll probably use github as yet another means of sharing solutions.

Share This:
  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Bookmarks
  • Google Buzz
  • RSS