By popular demand, heads up 'tunes 0.4 There's a raft of new features, none cooler than the popup you get if you hover over an album cover when the window is too small to show any text. Pictured left.
Happy Matt? The big change is that it's now designed to stay running all the time. When you pause or stop iTunes, the hut window will tastefully fade away. When iTunes fires up again, it will come back. There are a number of new options in the prefs window to support that such as adding to your login items. 7 hours 36 minutes ago by Mark Aufflick Permalink | Comments (0) Brilliant way to schedule events with others
When you don't know which of a few meetup times will work for everyone a meeting request email isn't going to work. doodle.com lets you select a number of date/time options on a calendar and send an email to your friends/colleagues to indicate which ones suit them - then calculating the best option to maximise attendance is easy!
You can do simple polls as well. 7 hours 40 minutes ago by Mark Aufflick Permalink | Comments (0) heads up 'tunes Version 0.3
This release adds a new preference to stick the hud display to all spaces, as per Mr Barnes request.
I also changed the framework used by the prefs window, so let me know if there are any issues or raise a bug: http://mark.aufflick.com/software/heads-up-tunes/bugs 11:43 PM, 20 Nov 2008 by Mark Aufflick Permalink | Comments (2) heads up 'tunes Version 0.2The much awaited version 0.2 of my iTunes thingamy is now released! Version 0.1 installations should find the update automatically or go to the home page to download it yourself. You can now resize the window yourself, so it can be skinny or wide:
You can turn off the shadow if you wish, and it now remembers it's window position between runs. And that's about it :) No comments about my music selection please! 06:59 PM, 17 Nov 2008 by Mark Aufflick Permalink | Comments (0) Mankind is No IslandThis beautiful and touching short film was shot in Sydney and New York, on a camera phone. Incidentally, it won Tropfest New York, the New York chapter of the Tropfest short film festival started in Sydney. Fantastic thinking and story telling, and just maybe it will inspire some of us. 10:35 PM, 11 Nov 2008 by Mark Aufflick Permalink | Comments (0) heads up preview for iTunes
One doesn't normally have enough screen space to leave iTunes visible though, so I figured what I wanted was a heads up style panel, floating above all other applications, showing the current and upcoming songs. Something like the image on the right: Surprisingly, no such app existed. There are many heads up controllers (which I don't need since I control tracks and level from my Apple bluetooth keyboard media function keys), or artwork viewers that display the current track only. There was no alternative but to suspend my study plan for an evening and write my own. The result is heads up 'tunes. It's lightweight, nothing fancy (although I will add animation to it one day). You can download the current version at the software home page: http://mark.aufflick.com/software/heads-up-tunes/ Here's the blurb from the about box:
This is a preliminary version of heads up 'tunes. Oh, and it also sets its dock icon to the current track artwork. It's a Universal binary and has been tested on PPC (by me) and Intel (by Matt B and DB). Enjoy! 04:01 PM, 25 Oct 2008 by Mark Aufflick Permalink | Comments (2) Man I'm sick of DoS-ing spammers
It's been months since I set up reCaptcha and since then not a single spam comment has been accepted. But the spam-bots continue and eventually end up chewing up all available threads of the web server. Grr.
Sorry to anyone unable to acces the site for a few hours this morning. I have some plans for how to beat them that I'll gradually roll out, we'll have to see who wins! (For the uninitiated, DoS means Denial of Service.) Update: I'm not winning :( 09:41 AM, 24 Oct 2008 by Mark Aufflick Permalink | Comments (0) Stevie Wonder, Sydney 2008, Acer Arena
What a privilege it was to be at tonight's Stevie Wonder concert. Great man, great singer, great band :) The start of the night had me worried. There was way too much kick drum in the mix for the bass drivers which sounded bad itself and just exacerbated the problems with the arena echo. I kept looking at the sound engineer hoping to see him trying to resolve the situation, but no action. I had to put in my ear plugs. Mercifully though, after the solo's, where the levels of each band member was raised for their part, when the engineer reverted to the regular mix it was much better. How he didn't notice the problem before is beyond me. From then on the night was fantastic. Dancing in the aisles, singing along--awesome. Stevie's daughter did an amazing song. No encore, but Stevie promised to come back and floated the idea of doing a benefit gig for less than fully abled people. Count me in on that Stevie. 11:54 PM, 23 Oct 2008 by Mark Aufflick Permalink | Comments (0) Using Windows Update to find class action plaintiffs
Well this is interesting. A lawyer friend of mine sent me an excerpt from the Beard Group's Class Action Reporter newsletter (subscription required) about the "Windows Vista Capable" lawsuit.
You may have heard of it - in February this year a Washington court granted class action status to a suit brought against Microsoft for "unjust enrichment" by labelling PCs as "Windows Vista Capable" which no reasonable person could bear to run Vista on. Since then, Microsoft has "repeatedly said it cannot identify the people who bought PCs under its Vista Capable marketing campaign in 2006 and early 2007". The cunning lawyers, however, have suggested that Microsoft deploy a script via Windows Update which could identify relevant PCs and alert the user of their eligibility to join the class action suit. Genius! The Microsoft lawyers must be absolutely livid. A hired "expert" has suggested that it would take Microsoft no more than a few hours to develop and QA the update. I think that is on the low side, but there's certainly not more than a few days work in it -- which is still peanuts in the context of the case. One wonders what the update would do, and who would collect the data. Make the dialog incomprehesive enough and noone will be able to join the case :) Unless, of course, they own a copy of Dealing with Windows Dialog Boxes - for Dummies. 10:22 AM, 09 Oct 2008 by Mark Aufflick Permalink | Comments (0) Fibonacci Perl GolfThere are plenty of Perl golf O(N) implementations of Fibonacci generators (and in other languages also), but I wondered in the shower today if I could do it without either an explicit initialisation or explicit previous variables. While I feel tracking both values in a single string is kindof cheating, this is the best I have come up with so far: perl -le 'print$2while s/(\d*):?(\d*)/($1+$2||1).":$1"/e' |head -10 At 45 characters it's not a size winner (see this thread for implementations as short as 27 characters and 21 in Ruby) but I like it for a few reasons: it is complete (many other implementations skip the leading 1); it contains no initialisation (or indeed any implicit assigment operations); it uses only one state variable ($_). Update: Perl golf is addictive! I had to let go of my "no implicit assignment" rule, but here is a similar 37 character solution. A weakness this version suffers from is that since it requires both single and double quote characters it's tough to fit into a shell one liner: $_="$':".($'+$`||1),print$`while x./:/ Update 2: As pointed out on the related perlmonks thread, I can save a few chars with perl 5.10 using say: perl -E 'say$2while s/(\d*):?(\d*)/($1+$2||1).":$1"/e' |head -10 $_="$':".($'+$`||1),say$`while x./:/ 05:33 PM, 05 Oct 2008 by Mark Aufflick Permalink | Comments (2) We are the mighty mighty Hawthorn!! I've been waiting a while up here in Sydney, patiently following my beloved Hawks, and what a win :)
Our 10th premiership, the first in 19 years! I remember the 1989 grand final very well. It was a time when it seemed like it was our right to be in most grand finals. Now we're back! The huge MCG crowd of 100,012 was also in good form - it would have been amazing to be there. Geelong 5.3 6.12 9.18 11.23 (89) 05:25 PM, 27 Sep 2008 by Mark Aufflick Permalink | Comments (0) My friend Xervier is so clever!Here is a video of my little friend Xervier, reading and signing with his dad. Isn't he gorgeous :) Xervier has Down Syndrome, but he doesn't let that doesn't stop him. At 17 months this is really amazing - big props to Paul his dad! 11:15 AM, 23 Sep 2008 by Mark Aufflick Permalink | Comments (0) LinkedIn - how not to implement a site-down page
LinkedIn showing us how not to tell customers that their service is temporarily unavailable. It's down on an Australian Sunday afternoon, which is prime weekend upgrade time in the US, so I assume this is intentional (or semi-intentional) downtime. They might like to use this image I just made them at mine.icanhascheezburger.com Update: I don't know how long the site was down when I first posted, but about 50 minutes later the above error page was replaced with this one:
Update 2: Well the LinkedIn crew obviously agrees it was a non-optimal experience - less than a day later they had tracked down this post and left a comment. Nice work, and a good example of retrieving a positive experience out of an outage. 03:05 PM, 07 Sep 2008 by Mark Aufflick Permalink | Comments (2) Chrome a little disappointing I had high hopes for Google's new Internet browser Chrome becomming my "application" browser on Windows. You see I currently run two browsers at all times. Firefox for general browsing and development (can't beat plugins like greasemonkey), and Safari for windows for accessing web applications (like google apps).
The reason I do this is two fold. One, Safari is faster than Firefox and two, that lets me restart my application browser semi-regularly without losing all my browsing. I hoped Chrome would help in two ways. Firstly the V8 JavaScript VM comes from heavy hitters like Lars Bak of Strongtalk and Java HotSpot VM fame (per Avi) so you know it is fast; secondly it runs a separate process per tab, so the days of screwy javascript or flash crashing your other tabs are over. But to be honest, in practice it was underwhelming. On Windows XP with a 2.4 GHz Core 2 Duo processor the expense of windows process startup was noticable, and the startup time for google apps was easily 3 times that of the latest Safari nightly build. Safari on Windows can be a little clunky, but the combination of it plus Firefox continues to be a winning setup for me. 10:13 AM, 04 Sep 2008 by Mark Aufflick Permalink | Comments (0) Sexy thin client hardware
Forget a linux or other cpu+kernel+software based solution, a company called Teradici have an amazing chipset that encapsulates hardware compression/decompression of screen changes, encryption, usb etc. The problem seems to be that you need a 1:1 chip in your host for each client. That's going to have trouble scaling. 01:29 PM, 03 Sep 2008 by Mark Aufflick Permalink | Comments (0) Thin client for your virtual cloud desktop
I remembered a cheap thin-client company I saw at CeBIT Sydney this year: ThinLinX - an Australian company that makes cheap thin client devices that run the linux kernel (and thus nearly any remote desktop protocol you can imagine). They have full sound support so it's not impossible to imagine running your voice through the same device. 01:25 PM, 03 Sep 2008 by Mark Aufflick Permalink | Comments (0) Your desktop in the cloudDesktop cloud computing, Virtual desktop infrastructure... whatever you call it, it's a fairly obvious extension of data center based virtual desktops -- just using the cloud instead of your data center. For the un-initiated, many organisations use a central server (or servers) on which all their staff work. On your desk you might have a very simple PC or something like a Sun Ray device, but all the work and files are housed in the data center. So if anything goes awry with your local hardware, or you have to move (due to a disaster or whatever), you can access your "PC" from anywhere. It also works out cheaper to provide and support. So imagine that, but instead of your own server, you use the cloud - say Amazon Elastic Cloud Computing. Well tonight I did just that. Here is a screen shot of me using a Linux desktop installation on Amazon EC2 - and I'm doing all the things many people do at work: using a calendaring tool (in this case the much ballyhooed Chandler), working on a spreadsheet (using Open Office) and web browsing (Firefox).To access the desktop I am using VNC which means I could access it from my Mac, a Windows or DOS PC (yes, DOS :), just about anything. I'm in Sydney, and the Amazon servers are in the US, so the latency meant things were a little jerky, but just about useable. So with some tweaking and a slightly more advanced screen remoting technology and it could just about work. In the US I'm sure it is fine as it is. So there you have it - in one night I provisioned a server that could run the desktops for a small office, and thanks to EC2 you just pay for what you use. Note that for this solution to work you really need the Amazon Elastic Block persistent disk technology, which should be available real soon. Imagine - you start a new office in China, and all you need is an Internet connection, a firewall, a bunch of commodity hardware devices and a printer or two. As soon as you can get them there, you have the server ready to go. Or instead you need to relocate all your staff in a hurry and don't have a dedicated BCP location - internet and a few cheap PCs and your exact office environment is replicated. It's a good way to go for many offices, especially back and middle office etc. 12:12 AM, 03 Sep 2008 by Mark Aufflick Permalink | Comments (0) Faster JavaScript with Safari/WebKit SquirrelFishIn June, the project announced SquirrelFish, the oddly named next-gen JavaScript engine which includes bytecode compilation and a number of optimisations. The announcement indicates a 1.7 x speed increase over the engine in Safari 3.0. My perceptual testing on my (admittedly low baseline) G4 PPC powerbook suggests that startup time of JavaScript intensive applications such as Gmail improves only a little (saving 1 second off the 9 second startup time), but the ongoing performance is much snappier. Things like Flickr badges load in a snap. It is good to get closer to the performance Firefox 3.0 which has the maddening property that it starts out very fast (7 second Gmail startup), but a large amount of JavaScript intensive browsing brings it to its knees over time - something Safari suffers far less from. You can get a hold of the new engine by downloading the WebKit knightly build from http://webkit.org/ 07:59 PM, 24 Aug 2008 by Mark Aufflick Permalink | Comments (0) Testing database deadlock retry logicI just spent a *really* long time writing a test for automatic deadlock retry in a database api module I maintain. So you or I don't have to figure it out in the future, here's the recipe. So firstly you can't use transactions to build the deadlock situation. That would be easy, but it defeats our purpose since your auto-deadlock retry logic is not going to be able to retry intra-transaction statements (of course you could implement full transaction replay, but that's another story). So I did it using cursors. Here is a perl sub that builds Sybase TSQL. It returns two values only because Sybase requires the cursor declaration in a separate batch. sub deadlock_sql {
my ($table1, $table1_char_col, $table2, $table2_col) = @_;
"declare the_cursor cursor for select $table1_char_col from $table1 for update",
sprintf 'declare @col_value varchar(100)
open the_cursor
fetch the_cursor into @col_value
waitfor delay "00:00:04" -- wait 4 seconds
update %s set %s = %s
-- only need to go round once to cause deadlock
', $table2, $table2_col, $table2_col;
}
So we are taking out a write lock on the first table, waiting 4 seconds, then taking out a write lock on the second table. Do that
twice in opposite order and you have yourself a deadlock:
sub cause_a_deadlock {
my $child_pid;
my $parent_retries;
pipe(FROM_CHILD, TO_PARENT);
if ($child_pid = fork) {
# parent
close(TO_PARENT);
my $dbh = new_dbh();
my @sql = deadlock_sql('table1', 'a_char_col_from_table1', 'table2', 'any_col_from_table_2');
sleep 2; # sleep half of sql sleep to ensure overlap
$dbh->exec_sql($sql[0]);
lives_ok { $dbh->exec_sql($sql[1]) };
$parent_retries = $dbh->deadlock_retry_attempts;
} else {
# child
close(FROM_CHILD);
my $dbh = new_dbh();
my @sql = deadlock_sql('table2', 'a_char_col_from_table2', 'table1', 'any_col_from_table_1');
$dbh->exec_sql($sql[0]);
lives_ok { $dbh->exec_sql($sql[1]) };
print TO_PARENT $dbh->deadlock_retry_attempts . "\n";
exit;
}
my $child_retries =
Of course the exact code will depend on your database and database abstraction layer. 07:35 PM, 20 Aug 2008 by Mark Aufflick Permalink | Comments (0) 5 years and still blogging
August 2003 saw the start of this weblog. My first blog was in 2002 when I visited Denmark to do some work with my friend Lars, but when I shut that down after my travels I neglected to save the contents. So instead I will call this the fifth year of my blogging.
Who would have predicted that the SCO law suits I blogged about in that first month would still be going. Perhaps more predictably, the Be company, blogged about in my second month, would go under. Also predictably I have less time for blogging now that I have a "real" job and am also studying part time. Thanks to everyone who ever commented and all my regular readers (I count 3 - am I missing anyone?). I enjoy writing, so you'll be sure to keep hearing from me well into the future. I plan to list a few favourite posts a little later and thank some inspirations. Hey - any excuse! 07:52 PM, 09 Aug 2008 by Mark Aufflick Permalink | Comments (4) August == SkiingWell it's August and that means skiing :) Some of you will know that I had a day of blissful snow in NZ in June, but next week Kath and I head to Thredbo for nearly a full week of hounding powder - and there's stacks of it too! This was NZ - sounds like Thredbo will be just as good: 07:44 PM, 09 Aug 2008 by Mark Aufflick Permalink | Comments (0) Comment Spam & LiteratureI finally got fed up with manually monitoring the spam messages, but I didn't want to turn off anonymous comments. I figured captcha was the answer, but what was the easiest way? photo.net, the awesome photographry site built and run by Philip Greenspun is built on a similar platform to this site, and I knew it had captcha. Philip is true to his word on the importance of open source software, and the api and code of his site is publicly available. I discovered that photo.net uses a free service called reCAPTCHA - and it's brilliant! It gives you two words to type in. One that it knows the answer to (to check you're a human) and the other is a curly word that the OCR system at Carnegie Mellon University couldn't figure out while scanning books for the public good. I assume they run the unknown word through a number of captcha queries and pick the most popular interpretation. Now that's really crowd-sourcing! 09:52 PM, 26 Jul 2008 by Mark Aufflick Permalink | Comments (1) TWiki on FastCGII couldn't find much discussion of TWiki on FCGI. There is a beta project to make a standalone TWiki daemon which can also be run under FCGI, but I had already installed TWiki 4.2.0 so I was reticent to reinstall from a different branch. I only really needed to speed up the view cgi, so it shouldn't be too hard surely? I already had mod_fcgid installed on my Apache2 server. It turned out to really be very easy, and seems to be working fine so far. Here is my diff for twiki/bin/view: --- view~ 2008-01-22 14:18:52.000000000 +1100
+++ view 2008-07-20 18:40:33.000000000 +1000
@@ -27,6 +27,14 @@
require 'setlib.cfg';
}
+use FCGI;
use TWiki::UI;
use TWiki::UI::View;
-TWiki::UI::run( \&TWiki::UI::View::view, view => 1 );
+
+my $request = FCGI::Request;
+while ($request->Accept >= 0) {
+ eval {TWiki::UI::run( \&TWiki::UI::View::view, view => 1 );};
+ warn $@ if $@;
+ $request->Flush;
+ $request->Finish;
+}
And I added the following to the bin <Directory> section in my apache config: <FilesMatch "^view$"> SetHandler fcgid-script </FilesMatch> This seemed to work fine, but searches failed to spawn grep correctly. I think diffs would have also failed to spawn rcs. So I switched over to the pure perl versions by making the following settings in LocalSite.cfg: $TWiki::cfg{StoreImpl} = 'RcsLite';
TWiki::cfg{RCS}{SearchAlgorithm} = 'TWiki::Store::SearchAlgorithms::PurePerl';
Working a treat so far - Memory use seems ok. It rose from about 14000k up to about 15200k, and then hovered around that level indefinately. I'll let you know if I see any memory leaks or wierd issues. Update: I guess the pure perl search implementation isn't well used. It threw up a taint error when I tried to use it. No matter, the fix was as simple as replacing a horrible piece of string eval: --- lib/TWiki/Store/SearchAlgorithms/PurePerl.pm~ 2008-01-22 14:18:55.000000000 +1100
+++ lib/TWiki/Store/SearchAlgorithms/PurePerl.pm 2008-07-20 19:32:58.000000000 +1000
@@ -46,9 +46,14 @@
# Convert GNU grep \< \> syntax to \b
$searchString =~ s/(?]/\\b/g;
$searchString =~ s/^(.*)$/\\b$1\\b/go if $options->{'wordboundaries'};
- my $match_code = "return \$_[0] =~ m/$searchString/o";
- $match_code .= 'i' unless ($options->{casesensitive});
- my $doMatch = eval "sub { $match_code }";
+
+ my $doMatch;
+ if ($options->{casesensitive}) {
+ $doMatch = sub { $_[0] =~ m/$searchString/o };
+ } else {
+ $doMatch = sub { $_[0] =~ m/$searchString/oi };
+ }
+
FILE:
foreach my $file ( @$topics ) {
next unless open(FILE, "<$sDir/$file.txt");
I'll have to track down how to submit TWiki bugs... Update 2: Another search issue - in the persisted view, the search page never gets re-rendered (ie. after making one successful search, all future searches appear to have identical results).
I didn't have time to find if that was a problem in the view code or the pure pearl search, but it was easy enough to make sure a new cgi was spawned per search request by adding the following at the end of the VirtualHost: <LocationMatch "WebSearch">
SetHandler cgi-script
</LocationMatch>
Conveniently the FCGI script works fine as a regular one-shot cgi, and since LocationMatch is processed after FilesMatch by Apache, this overrides the fcgid handler setting.
06:51 PM, 20 Jul 2008 by Mark Aufflick Permalink | Comments (0) Queen's regulations overrule American GeneralIn this great story from the Telegraph our protagonist, Flight Leutennant Ball, didn't blindly obey the order from his commanding officer to trim his moustache. In true British fighting spirit, he
And made it stick! That's cool.
12:42 PM, 16 Jun 2008 by Mark Aufflick Permalink | Comments (0) Installing vmware tools on Ubuntu JeosIt's not as easy as you might think. Firstly, the official vmware tools won't install on kernel versions 2.6.24. Fortunately you can get some simple source patches from http://projects.tuxx-home.at/?id=vmware_updates Once you've got the modules installed, if you're beady eyed (or analy retentive) you will notice that the network interface is still using the legacy pcnet32 emulation. You see the vmware tools has tried to create a /etc/modules.conf file to configure the hardware, but Ubuntu shed that file a long time ago in favour of modules.d. You have two simple solutions from what I can see - either edit your .vmx file (the config file on your host machine) by adding the following line: ethernet0.virtualDev = "vmxnet" Or else you can force the kernel to never load the pcnet32 module: echo "blacklist pcnet32" >> /etc/modules.d/blacklist modprobe -r pcnet32 update-initramfs -u Easiest thing to do after that is reboot. You might notice your interface gets loaded as eth1 instead of eth0 (and thus not be configured). This is because vmware may have assigned your new interface a new mac address. Simply delete the ethernet interface lines from /etc/udev/rules.d/70-persistent-net.rules and then: /etc/init.d/udev restart Again a restart at this point is simplest. 09:31 PM, 26 May 2008 by Mark Aufflick Permalink | Comments (2) Start from the Heart
I have mentioned my friend Lars plenty of times before. Regular readers will know that he is not only the best software developer I have ever known, but a great thinker and all round good guy.
Well now he has re-invented himself, and is hoping to help you do the same.
Find what you love and everything else will fall into placeLars has been coaching people for a little while now, and Start from the Heart is a place where he is going to share some of his knowledge and help you to be a better, well, you! I really encourage you to check out his first online exercise, Heroes.
... we notice the things [in our heroes] that we ourselves are ... 10:43 PM, 09 May 2008 by Mark Aufflick Permalink | Comments (0) Lovethreads
My good friends Mike and Julie recently opened a clothing store that exclusively stocks ethical/environmentally sound fashion.
Anyway, this week they launched their online wardrobe / store, with a little help from Giles of This Is Yours™ design and PumpTheory software development. Anyway, it's pretty cool. You should check it out. http://lovethreads.com.au/ 08:04 PM, 09 May 2008 by Mark Aufflick Permalink | Comments (0) Race day
Well there was a little too much of this:
But in the end a good day was had by all*, especially the spectators:
* Except: Kimi Raikkonen, Robert Kubica, Timo Glock, Takuma Sato, Nelsinho Piquet, Felipe Massa, David Coulthard, Jarno Trulli, Adrian Sutil, Mark Webber, Jenson Button, Anthony Davidson, Sebastian Vettel, Giancarlo Fisichella, Rubens Barrichello Kimi ended up salvaging a point thanks to Barrichello's disqualification for exiting the pit lane against a red light. This also shifted Champ car champ Sebastien Bourdais to 7th rank (even though he didn't quite finish) and 2 points - not bad for your first f1 in a third tier car (which is why I included him in the list of people who *did* have a good day! 03:28 AM, 17 Mar 2008 by Mark Aufflick Permalink | Comments (0) RAAF Roulettes
The RAAF Roulettes performed their excellent brand of aeorbatics today at day 3 of the Grand Prix.
There was an even more awe inspiring FA/18 demonstration but I didn't get any still footage of that. I'll see if my phone-cam video is worth posting later. 08:44 PM, 15 Mar 2008 by Mark Aufflick Permalink | Comments (0) Obligatory Kimi Photos
Of course it's only practice, but notably current world champion Kimmi didn't show good pace. A final blast on a sticky track yielded only 6th fastest lap of the day.
01:55 AM, 15 Mar 2008 by Mark Aufflick Permalink | Comments (0) Webber looking fast
To the delight of fans (and, I'm sure, the ticket sellers), Australian F1 driver Mark Webber led the pace for nearly all of practice session two - being bested only by Lewis Hamilton at the end of the 90 minutes.
01:52 AM, 15 Mar 2008 by Mark Aufflick Permalink | Comments (0) F111 flyby
It wasn't all land-based power at the F1 today - four RAAF F111s did a flyby (no dump and burn unfortunately) and the Navy "Squirrel" helecopters put on a great acrobatic display.
01:49 AM, 15 Mar 2008 by Mark Aufflick Permalink | Comments (0) Trulli's Toyota on a Truck
Many people had minor offs in their newly traction-control-free cars, but Jarno Trulli's Toyota got beached and had to be hauled off on a truck after practice session 2.
01:45 AM, 15 Mar 2008 by Mark Aufflick Permalink | Comments (0) Nakajima coming to grief
There was some excitement at today's F1 practice sessions. I managed to snap this sequence of Williams #2 driver Nakajima spinning right in front of me.
01:42 AM, 15 Mar 2008 by Mark Aufflick Permalink | Comments (0) Convert XML to SQL
I thought it might be worth crossposting my reply to a recent perlmonks question asking for a generalised XML to SQL conversion.
You can transform your xml into sql using xslt. Stealing some bits of code from elsewhere on the net, I can use the following xslt to convert my del.icio.us bookmarks into a set of insert statements:
<?xml version="1.0"?> <!DOCTYPE rdf:RDF [ <!ENTITY rdf 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'> <!ENTITY rss 'http://purl.org/rss/1.0/'> ]> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:rdf="&rdf;" xmlns:rss="&rss;"> <xsl:output method="text"/> <!-- main template --> <xsl:template match="/rdf:RDF"> <xsl:apply-templates select="rss:item" /> </xsl:template> <xsl:template match="rss:item"> insert into links (url, title) values ( '<xsl:call-template name="sql-escape"><xsl:with-param name="text" select="rss:title"/></xsl:call-template>', '<xsl:call-template name="sql-escape"><xsl:with-param name="text" select="rss:link"/></xsl:call-template>' ); </xsl:template> <!-- utility functions --> <xsl:template name="sql-escape"> <xsl:param name="text"/> <xsl:variable name="tmp"> <xsl:call-template name="replace-substring"> <xsl:with-param name="from">'</xsl:with-param> <xsl:with-param name="to">''</xsl:with-param> <xsl:with-param name="value" select="$text"/> </xsl:call-template> </xsl:variable> <xsl:value-of select="$tmp"/> </xsl:template> <xsl:template name="replace-substring"> <xsl:param name="value" /> <xsl:param name="from" /> <xsl:param name="to" /> <xsl:choose> <xsl:when test="contains($value,$from)"> <xsl:value-of select="substring-before($value,$from)" /> <xsl:value-of select="$to" /> <xsl:call-template name="replace-substring"> <xsl:with-param name="value" select="substring-after($value,$from)" /> <xsl:with-param name="from" select="$from" /> <xsl:with-param name="to" select="$to" /> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:value-of select="$value" /> </xsl:otherwise> </xsl:choose> </xsl:template> </xsl:stylesheet>If I save that to a file called del2sql.xsl I can insert the links in the rss response like so:
wget -O - http://feeds.delicious.com/rss/aufflick | xsltproc del2sql.xsl - | psql links_dbPretty neat huh! Unfortunately xslt is even less decipherable than golf perl, but thems the breaks. The command pipeline above uses the postgres psql command, but you can just as easily use this approach with mysql, oracle, sybase, sql server or whatever. Most database vendors/projects these days have some sort of xml functionality built in, but this puts all the processing load on the part of your system that is most difficult to scale. Better, I think, to do as much processing as possible on your application server which you can more easily scale. You might also be better using xslt to convert to CSV and then using some simple script to slurp the csv into your database - you could then handle insert/update errors gracefully in your script. The utility sql-escape and replace-substring templates can be placed in a common file and included into your xsl stylesheets via an xsl:import statement. If you have an xsl 2 compatible xslt engine you can use the x:replace() function directly instead of the recursive replace-substring template.
11:41 PM, 03 Mar 2008 by Mark Aufflick Permalink | Comments (0) Machine learning for every man and his dog
Research by a team from Eötvös Loránd University in Hungary has used machine learning techniques to classify dog barks - differentiating the message (stranger, angry, etc.) and the individual dog. (Source: Science Daily)
This is awesome! Of course you could use this to detect potentially dangerous situations, or even for automatic dog training, but by far the best idea is to give your dog their own bark-operated doggie door that would operated only for their bark. Just the thing for teasing the neighbour's bigger dog then hiding safely behind the secure electronic security only dreamed about in the days of Looney Tunes! 04:22 PM, 19 Feb 2008 by Mark Aufflick Permalink | Comments (0) pipelines in Erlang
Showing again why erlang's super-lightweight concurrency rocks, David King posted code to simplify writing pipelined code in erlang.
You already think in terms of pipelines - how about "gzcat foo.tar.gz | tar xf -"? You may not have known it, but the shell is running the unzip and untar in parallel - the stdin read in tar just blocks until data is sent to stdout by gzcat. Well a lot of tasks can be expressed in terms of pipelines, and if you can do that then getting some level of parallelisation is simple with David's helper code (even across erlang nodes, ie. machines):
pipeline:run([pipeline:generator(BigList),
{filter,fun some_filter/1},
{map,fun_some_map/1},
{generic,fun some_complex_function/2},
fun some_more_complicated_function/1,
fun pipeline:collect/1]).
So basically what he's doing here is making a list of the steps - each step being implemented in a fun that accepts as input whatever the previous step outputs (the funs can even be defined inline of course). Go check out David's blog entry for the code and more detailed explanation.
09:30 PM, 27 Jan 2008 by Mark Aufflick Permalink | Comments (0) ThinkingWe can't solve problems by using the same kind of thinking we used when we created them. Via swiss miss. 11:31 AM, 24 Jan 2008 by Mark Aufflick Permalink | Comments (0) So small yet so big Well now I don't need to wonder what I'm going to do with my bonus...
Finally a worthy replacement of my 12" Powerbook - but perhaps I should wait for the next model when Apple can incorporate the recently released 128Gig solid state drives. 64Gig just isn't going to cut it, and a 4200rpm drive is somewhat unpalatable. Still not as cool as a Powerbook Duo though. 12:52 PM, 16 Jan 2008 by Mark Aufflick Permalink | Comments (2) Hosting outage
So much for "Between the hours of 7am and 10am you may experience some latency for a brief few minute period." for some "re-patching work" today...
Apparently the "AS/NZS7799 Information Security Management Systems certification" standard that the datacenter runs to somehow allows cables to be patched the wrong way and not tested for 3 hours :( 01:15 PM, 13 Jan 2008 by Mark Aufflick Permalink | Comments (0) Optimising Perl with Inline::C
I was discussing with someone today about a time I used Inline::C to massively speed up an inner loop in a Perl program. Thing is, in that case the real speedup wasn't any super smart C programming on my behalf, it was just making use of a very optimised vendor library that you could only access from C.
So I got to thinking - in normal every day code, is there any real speed benefit to be had by writing your inner loops in C. I found an old web page by Mitchell Charity discussing Inline and, interpreting his (slightly pathological) example a little, I got a surprising result:
use strict; use warnings; use Inline 'C'; use Benchmark qw(cmpthese); cmpthese( 50, { perl_method => sub { my $object = new Foo; for(my $i=0;$i<1_000_000;$i++) { $object->set_element($i,67); } }, all_in_one_c => sub { my $object = new Foo; set_all_with_c($object); } }); package Foo; sub new { my $self = " " x 1_000_000; return bless \$self, 'Foo' } sub set_element { my($self,$n,$value) = @_; substr($$self,$n,1) = pack("C",$value); } __END__ __C__ #define USING(object) unsigned char *ptr = SvPVX(SvRV(object)) #define SET_ELEMENT(IDX,VAL) ptr[IDX] = VAL void set_all_with_c (SV* object) { USING(object); int i; for(i=0;i<1000000;i++) { SET_ELEMENT(i, 67); } }
s/iter perl_method all_in_one_c
perl_method 4.16 -- -100%
all_in_one_c 8.60e-03 48321% --
ie. the C code was 48321% times as fast.But it's not really comparing apples with apples - the Perl code is doing a method call on each iteration, the C code is operating on the value directly. In addition, the C code (by way of Inline::C's magic) is basically copying the string into a temporary variable, operating directly on that, and copying back - so the dereferencing is not happening on each loop. We can make those changes in Perl too, and see how that compares.
... sub set_all_with_perl { my $tmp_str = ${ $_[0] }; substr($tmp_str, $_, 1) = pack("C",67) for 0..1_000_000; ${ $_[0] } = $tmp_str; } ... s/iter perl_method all_in_one_perl all_in_one_c perl_method 4.21 -- -62% -100% all_in_one_perl 1.61 161% -- -99% all_in_one_c 8.60e-03 48821% 18626% --So eliminating the method dispatch and dereference in the loop made our Perl code much faster, but the C code is still way faster. Obviously it's a contrived example, and 1 million iterations is one heck of an inner loop, but I am still surprised by how much difference it made.
01:38 AM, 11 Jan 2008 by Mark Aufflick Permalink | Comments (0) Compiling subversion for performance on Solaris
More for my future reference than anything else, if you want decent svn client performance on Solaris 8 (and probably other versions), you should compile Apache APR with the following arguents:
--with-devrandom=/dev/urandom Use non-blocking pseudo-random number device The nonportable-atomics option uses an atomic UltraSparc microcode instruction to replace an entire mutex algorithm (the same option works on modern Intel processors also). Update: Although, according to the APR-0.9 change notes the solaris specific atomic code was removed due to licensing concerns... Might try to track that down and reapply locally (it said it was licenced MPL 1.0 so no problem using it locally AFAICT). So here it is in the 0.9.3 tag: http://svn.apache.org/viewvc/apr/apr/tags/0.9.3/atomic/solaris_sparc/ but the build process has radically changed since then so I'll need to figure out how to port the assembler source into inline gcc asm for the unified unix/apr_atomic.c in current versions. I'll post when/if I get success! Update 2: Here's a patch for ISA independant Solaris 10 atomics, but that doesn't help me since I'm on Solaris 8. And here's another patch, this time for the x86 specific atomics for Solaris x86, which also doesn't help me since I'm on UltraSparc :( 05:37 PM, 07 Jan 2008 by Mark Aufflick Permalink | Comments (0) The circularity of IDEs and code proliferation
Use of text code* (eg. Java, C++) IDEs encourage non-dynamic code. Steve Yegge puts it perfectly:
The second difficulty with the IDE perspective is that Java-style IDEs intrinsically create a circular problem. The circularity stems from the nature of programming languages: the "game piece" shapes are determined by the language's static type system. Java's game pieces don't permit code elimination because Java's static type system doesn't have any compression facilities - no macros, no lambdas, no declarative data structures, no templates, nothing that would permit the removal of the copy-and-paste duplication patterns that Java programmers think of as "inevitable boilerplate", but which are in fact easily factored out in dynamic languages.* I say text code IDEs specifically to exclude the Smalltalk environment where perfect automated refactoring is entirely possible with very dynamic code. 11:46 PM, 02 Jan 2008 by Mark Aufflick Permalink | Comments (0) |
Archive
November 2008 October 2008 September 2008 August 2008 July 2008 June 2008 May 2008 March 2008 February 2008 January 2008 December 2007 November 2007 October 2007 September 2007 August 2007 July 2007 June 2007 May 2007 April 2007 March 2007 February 2007 January 2007 December 2006 November 2006 October 2006 September 2006 August 2006 July 2006 June 2006 May 2006 April 2006 March 2006 February 2006 January 2006 December 2005 November 2005 October 2005 September 2005 August 2005 July 2005 June 2005 May 2005 April 2005 March 2005 February 2005 January 2005 December 2004 November 2004 October 2004 September 2004 August 2004 July 2004 June 2004 May 2004 April 2004 March 2004 February 2004 January 2004 December 2003 November 2003 October 2003 September 2003 August 2003 Notifications Request notifications
Recent Comments | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There's a raft of new features, none cooler than the popup you get if you hover over an album cover when the window is too small to show any text. Pictured left.
When I'm listening to music I like to know what tracks are queued up. Call me a control freak.
I've been waiting a while up here in Sydney, patiently following my beloved
I had high hopes for Google's new Internet browser





Update: Oops, my brain slipped back in time! This post previously (and incorrectly) attributed this spin to Alex Wurz who no longer has an F1 driving seat.
Well now I don't need to wonder what I'm going to do with my bonus...
Request notifications