Act IV, Scene I

- what wizardry is this!? svn supports symlinks? A dark Filesystem. In the middle, a Repository boiling. Thunder.                  Enter the three  Programmers.        1 P ROGRAMMER.   Thrice the padded buf hath oe'r runn'd.        2  P ROGRAMMER .   Thrice and once, the platter spun.        3  P ROGRAMMER .   Hexate cries:—'tis time! 'tis time!        1  P ROGRAMMER .   Round about the repo go;     In spaghetti'd source code throw.—     Functors, that on blackest ARM,     Caused a user grievous harm;     Refactor'd business logic got,     Compile first i' the charmed pot!        A LL.   Double, double toil and trouble;     Cycles burn, and repo bubble.        2  P ROGRAMMER .   Mock-up of an inode struct,     In the repo run amock;     Superblock, corrupt extent,     File flat, and file bent,     Meta data, magic prop,     B-tree hash, and sign that's dropped,—     For VCS of powerful trouble,     Like a hell-broth boil and bubble.        A LL

Multithreaded Python, extensions, and static data

The GIL The GIL and Context Switching I use Boost.Python to write some C++ extensions for Python. I work on an I/O-bound Python program; Python has a global interpreter lock ("the GIL") which means that in a multi-threaded program, only one thread can be executing code inside the Python interpreter at once. Now, a thread can drop the GIL, and the built-in Python read and write routines do this so that while one thread is doing I/O, another thread can run. However, due to a peculiarity in how the GIL is implemented, 1 even though the actual I/O takes place during system calls that drop the GIL, the need to re-acquire the GIL after every I/O operation was killing our performance. For instance, one of the things that the application does a lot of is logging. Doing the logging synchronously -- as the code is executing and it wants to write something to its log, it needs to wait for the write to the logfile to finish before it can continue going about its business -- turned

Sloppy Graph, Sloppy Design

I was spending time trying to fine-tune a graphviz file documenting the call graph of a piece of code and describing some of the critical functions. graphviz isn't really designed for the kind of long node labels I wanted to give it, so it would do things like put nodes in places which made it have to draw arrows reaching clear across the page. Finally I realized that rather than trying to talk graphviz into reordering its nodes, I could just refactor the thing I was graphing so that the flow wasn't so darned convoluted in the first place. Before (image links to full size version): After (image links to full size version): Corollary? If it's hard to get your call flow graph to look pretty, well, the graph isn't the only thing that's ugly...

An Avocado in the Snow

An avocado, found in the snow near Portland St and Broadway, Cambridge, MA An avocado in the snow. Who left it there? I do not know. Not Father, Son, nor Ghost so holy, Rebirths you into guacamole. Did leaping from some wretched fate Allow you to feel special, great? Or did, cast down like ancient foe, You weep from terror, weep from woe? But lie here now, near Portland Street, And rest, green flesh and tasty meat.

Switching Finks

One of the open-source projects I contribute to is Fink , a package manager for OS X; if you've used apt-get or yum on Linux, it provides a similar facility, allowing you to install, say, GnuPG by running fink install gnupg . It installs things into its own directory tree, rooted at /sw by default, to avoid interfering with things shipped by Apple ( / , /usr ) or manually installed by the user ( /usr/local .) That is, if you have Fink installed, your system will have /sw/bin , /sw/lib , /sw/etc , /sw/share/man , &c. So that you can run things installed in these nonstandard locations, Fink provides some shell commands in /sw/bin/ which edit environment variables like PATH and MANPATH to include the /sw/* directories. Most Fink users have . /sw/bin/ in their ~/.profile , so these commands will be invoked when their shell starts. Having my shell automatically pull in Fink at startup doesn't work for me, though. It's important to me to have a clea

For All Your Finger-Pointing Needs

While working with a large codebase, I often want to find the origin of a particular line. Subversion offers a tool, annotate (aka blame , aka praise ), which displays the author and revision for every line in a file, indicating who made the last change to a line. However, the last change is often not very useful; it was a minor change as a result of some other change you're not interested in, or the code was moved around due to refactoring, and you need to go back even further. When I need to do this, I find myself doing a sequence of: 1. svn blame FILE | less ; find the revision N where the line was last changed 2. svn log -r N FILE | less ; if the change is interesting, read the commit log for the file 3. svn blame FILE @ N-1 | less ; using Subversion's little-known pinned revision syntax, find the previous time the line was changed 4. Using N-1 as the new N , return to step 2. : Pretty much any Subversion command that takes a path argument can be given PATH @ REVIS

Wrong Dates in iCal Birthday Calendar

To keep track of people's birthdays, I use Mac OS X's Birthday Calendar feature of Address Book/iCal. I was going through my calendar the other day, and I noticed that a birthday which I knew was sometime in January wasn't showing up. It was on the corresponding Address Book contact, though. I deleted the birthday from this contact and reentered it, which fixed that entry, but on the suspicion that more birthdays might be missing, I flipped through my calendar and found: The Address Book birthday field has the misfeature that it forces a year to be specified. What a rude thing for Address Book to be asking! Anyway, I'd arbitrarily picked year 1 for the year for any contacts whose birth years I didn't know. Maybe, I thought, the Gregorian reform was throwing things off. However, changing the year to 1900 didn't help matters, and in fact made them worse: Turning the birthday calendar off (which wipes out iCal's backing store for the calendar) an