Thursday, March 12, 2009

Ultimate Checkers Showdown: Zombies vs. Sheep!

The thing I want you to have in your head at this moment is the vision of a checkerboard, but instead of little flat discs for pieces one side is using little sheep and the other side is using little zombies.

Now, how do you play a game? I'm going to contend for the sake of clarity that "play" is to do something in a limited abstraction of reality as a means of limiting risk while the "game" is a wholly-defined interactive structure which, as an effect of being wholly-defined, usually doesn't reflect reality. Put together, the wholly-defined nature of a game allows people to know what they're risking -- often nothing more than a bit of time and a bruised ego -- when they choose to play a game. Boundary conditions would be playing against undefined conditions -- the imagination-fueled exercise of cats, for example, or pursuing political gambits, or playing the stock market -- while not every game is entirely play -- a casino, for example, is full of games that compulsive gamblers cannot play because the compulsive gamblers have failed to limit their risks.

On a related note, Steven Johnsoon has made a case against Candyland that I'm particularly keen on. I suspect that I appreciate his line of reasoning for the same reason I'm increasingly disenchanted with conventional games as the ever-revisionist World of Warcraft becomes the unavoidable point of modern comparison, with "ever-revisionist" being where the game fails -- as soon as I became good at the game (in particular, playing a Paladin) the rules were changed and I had to, in effect, play the same old game with a new set of rules. Thus, even ignoring the addicts, its game-ness is called into question because the massive revisions to the rules make it impossible to say that it's clearly defined what is in the game. Warhammer Online doesn't have this problem per se (while new things are being added into the game, the game isn't being redefined to the point of new players seeing utterly separate rules from what original players were using), but instead runs into a problem of not being adequately abstracted such that the process of winning an objective simply comes down to a question of "does one side have more players and determination at this point in time?" -- there's scant value in being the only player trying to defend a keep.

But it's not like either not-a-game is difficult to "win" per se, as feeling successful is as nebulous online as it is in real life. Which brings us back to the case against Candyland, which can be summed up as "reliance on chance at the expense of rewarding skill makes for a non-compelling game." Or, put another way: just because you've limited your risk in a state of play doesn't mean that you want to cede control of what little you did risk. This is why skilled play, with games like chess or checkers or, heck, maybe even Starcraft (and not ignoring basic building blocks, particularly of the Lego variety) persists even against the cultural juggernaut that is Candyland of Warcraft.

So going back to the checkerboard with zombies on one side and sheep on the other. Yeah. I've never been big on checkers -- it always felt like the illiterate preschool version of chess. There is skill, yes, but not nearly so much of it because there simply aren't that many permutations since everything behaves the same way. And the icons on the board reflect this: the brainless zombies (with only enough feral capacity to need "buhRaaainsss...") would all be pursuing the practically brainless sheep in a routine and non-varying zombie shuffle. The sheep, for their part, would be shuffling around in a similar fashion, only maybe jumping away from predatory zombies or possibly clustering up for defense instead. The behavior of the zombies is effectively the same as the behavior of sheep within the confines of the game, even if an outside observer would say that the motivations are different: "Buh-Rains" instead of "Baa-Rains".

And this is where the checkerboard turns political. Now I'd like to refrain from comparing Republicans to zombies and Democrats to sheep in pretty much the same way I'd like to have a fund in my 401k that was a shining example of what to invest in by having a strong mix of forward-thinking and dividend paying stocks along with innovative small caps with huge amounts of growth potentials. But don't focus on that. Instead, check out Jonathan Krohn, a 14-year old "conservative" pundit that spoke at CPAC this year. Go clicky if you're not familiar with it -- I'll wait. ... Good, got all that? So in the same way that I'm not comparing Republicans to zombies and Democrats to sheep, I'm going to skip over this kid's HumptyDumptying (see Wharburton's Thinking from A to Z) which is the entire basis of his celebrity, avoid mentioning that kids advocating tax cuts is mere meme perpetuation, and instead stick on the point that when I was 14, I wasn't so bright either. Which I suppose is good in that at least they're not Ivy League-elitists... but on the flip side, has he even graduated from High School?

Regardless he's a big-shot speaker at this convention, telling them things that they don't want to disagree with despite the fact that he clearly hasn't a clue as to what he's saying. (I may write up a short diatribe on the subject for the use of debaters needing to argue against these points, but the crux of it would be that there is a psychotic break in wanting limited government on domestic issues and unlimited government on foreign issues, since the real lesson of 9/11 was that there are no foreign issues, there are just domestic issues in other jurisdictions. Besides, on the topic of "personal responsibility," kid, who drove you to this speaking engagement?) And the crowd hails his declarations as if those vile liberals are in favor of Death, Slavery and the Pursuit of Misery who tout Stalinism as a high ideal. As if there is some kind of clash in terms of the ideals of Americans at the 2-minutes-of -grandstanding level.

It's like looking at the pieces on a checkerboard and saying "Sheep don't eat brains, and that's good!" or "Zombies are a higher-evolved form of, um, life... and that's better!" while blithely ignoring that they're just going to go about jumping over each other in attempts to win the game even though, there's not much to win. But in politics, the winner always increases their power to alter the nation in the way that they see fit according to how they think they can make things good. But it's not like the pieces win the game, anyway -- there are players and one will win and one will lose.

I like to envision a goat as controlling the sheep pieces. As an all-consuming eating machine with attitude, I tend to think of goats as being fully aware of the fullness of chaos throughout the world -- and they respond to the chaos by trying to align everything within their sphere of influence, with "eat it" being a reasonable response to things that can't be otherwised aligned. On the zombie side of the board, I think a mummy would be an appropriate player. Nothing says "Old Money" like ancient Egyptian royalty that was buried with it so they could take it with them into the afterlife, and nothing says "conservative" like following a ritual process of organ removal and controlled dismemberment for improved corpse preservation, followed by bindings that inhibit future physical movement (but not the pronoucement of curses on looters). The goat should be wearing a leather jacket; the mummy should wear a smoking jacket. The ritualistic undead can't understand the cagey animal and vice versa, even though they both value winning and their pieces, within the abstraction of the game, all behave in the exact same fashion.

And that's the ultimate checkers showdown I want you to think about: A mummy versus a goat, moving zombies against sheep.

Sunday, February 22, 2009

BBQ'09 -- a Flaming Hot Start

Welcome to BBQ season! We just did our second round of BBQ and have two things to report:

First, despite their pleasing shape, Hardwood Briquettes just aren't that great. They disintegrate and lose their pleasing shape, making a mess in the process. They might do better if it weren't so damp, but I think I'm going back to more-natural unformed Hardwood Charcoal after I've cooked through this bag of Briquettes. So learn from my mistake and just go for the awkwardly un-uniform (would that just be "iform"?) lump stuff.

Second -- and I need to post my own photo of the bottle -- I did some really nice hot ginger-basil steaks to kick things off using freshly grated ginger and shredded basil in olive oil with some paprika and such (following the salt trick, of course). Where things got interesting was mixing that solution with Secret Aardvark Drunken Garlic Black Bean Sauce to form a scrape-off 5-minute marinade. Some New Seasons locations have it; read other Portland folks talking about it here, here and here. Then the steaks go on the grill and there's a last drizzle of olive oil, pepper and paprika (also provoking the fire to get a better searing effect) and voila, we had shred-it-with-a-fork tender buffalo steaks with a eye-popping tang, perfect for knocking the chill off on a February day. That said, I'm not sure what kind of wine I'd pair those steaks with -- but it was a 3pm dinner, so it's probably just as well that we weren't getting into the wine there. (Besides, I'd be surprised if the stuff I put on the steaks didn't kill all of the bacteria just for fun.)

We followed it up with some of the mistress' dark chocolate brownies, modified to contain more fresh-grated ginger (plus a bit of the powdered stuff for better dispersion). Yeah. I say "some" but I mean "the whole pan." I guess this is where I admit that I'm one of those metabolisms where I can get away with that sort of thing even at my age. Is this the part where I innocently go "tee hee hee?"

Saturday, August 30, 2008

Works for Me: Beating Windows Vista Into Submission

My little laptop which will be doing Warhammer Online has been barfing up larger and larger chunks of Windows Vista, starting with refusing to run chkdsk on corrupt bluetooth drivers and moving on to Windows Explorer crashing whenever I right-click on executables or launch iTunes or, well, any variety of things. I've made progress beating these problems into submission; here's what worked for me:

The Right-Click Crash: This became way easier to diagnose (I think) as soon as I realized that it was just crashing on executables and their ilk -- text files were unaffected. Above and beyond that, there's a related crash message in the Event Viewer (in Control Panel > Administrative Tools) helpfully informing me
Faulting application explorer.exe, version 6.0.6001.18000, time stamp 0x47918e5d, faulting module ntdll.dll, version 6.0.6001.18000, time stamp ..., exception code 0xc0000374, fault offset 0x000b015d, process id 0x11c, application start time ....
A tiny bit of digging later and I've discovered ShellExView and a reference to reassure me that it's Not Evil. The thinking is that there's something in the context menu for executables that it seriously hosing things up. Okay. So we download ShellExView, scroll to the right to find the dates when things were installed/modified and which files they're affecting and lo and behold, there's something creepy in there called "cmdlineext.dll" which wouldn't be spooky except for the "Sony" in the publisher name. You may recall something about Sony and RootKits... Anyway, disable that, nuke that, figure that it came with BioShock -- that's the shock part -- or maybe C&C3. Don't know, don't care, getting it the f--- off my system. And wow, I can right-click on stuff now! Works for me!

Corrupt BlueTooth drivers tell me to run ChkDsk which Vista refuses to do: Okay, so there was a hole in my hard drive. That's the easy part. The hard part was actually running chkdsk because Vista was refusing to run it at boot -- it was skipping it and all the beating on autochk.exe in the world wasn't helping. Well I've got a 4-year warranty on this thing (my previous laptop cooked itself after two years of World of Warcraft) so I e-chat with Dell support and get a workaround. If you've got a bootable Vista install disc (may work with any other bootable disk, don't know -- but this is your #1 reason to get actual Vista discs which I'm pissed that OEMs aren't providing anymore; it's like selling a car that has its tires fused to the wheels...) slap that in and reboot your machine, telling your bios to boot from the optical drive (that's F12 on the Dell XPS 1530 line). Then Vista core will load from the disc and you can tell it "yes, that's fine" when it initially asks if you're going to install. Then, on the second screen, there's a bunch of options and the last one is "Repair" -- click on that, and there's more options with the last one being "Command Prompt." You want Repair, you want Command Prompt. Once you've got the prompt, type in "chkdsk c: /r" and walk away for an hour or two. The Dell support guy suspended our chat session for 20 minutes... yeah, that's not hardly enough. Anyway, Windows is no longer complaining about a hole in the Bluetooth stack directory (I uninstalled and reinstalled it), and despite having fresh problems with the Jabra I got working with my business-oriented ThinkPad, I can safely say chkdsk works for me.

Bonus -- Pwning Files:
Along the way, I encountered files that I didn't own, even as an administrator. Which is bullsh|+. So here's the simplest and prettiest form of how to pwn those files...

And big thanks to NirSoft while we're at it. Now, anybody got a list of mods that need to be made to the secuRom-killing instructions to work properly with Vista?

Thursday, August 21, 2008

Breaking SharePoint: Lists.GetListItems via XML Corruption

So inconvienently timed after a production release, we started getting errors on all of our XML-running processes -- from the RSS builder to a search-appliance index file. The index file was thankfully generated by a batch job and was logging out an error to the effect of "hexadecimal value 0x0B, is an invalid character" from, astoundingly, a call to the Lists web service (against GetListItems, which returns an XmlNode).

I am utterly amazed to report that it wasn't lying.

What happened was a user uploaded a document with a "vertical tab" -- that's ASCII #11, or 0x0B, in the title and every request we made of MOSS resulted in that vertical tab going into the XML which is something that System.Xml apparently just can't handle. I can't really blame System.Xml on that count. But I have no qualms about blaming SharePoint -- it takes the metadata, ignores the known-XML-invalid characters, saves them to a database that we really just need to stay the heck away from, and then kills any XML-based request (including its own) for that data, usually without clear reason because data is requested in batches and any property corruption will result in this kind of obtuseness being the only thing the Black Box spits out of its foul heart.

So there are two lessons here: First, don't trust SharePoint to validate your users' data. And therefore, second, don't discount the possibility that SharePoint will have functions and functionality that seems to spontaneously choke and die based on user-input data.

I honestly cannot believe the amount of money we've effectively burned trying to use SharePoint because it is a vendor-supplied platform as opposed to just having a couple of senior devigners build something from the ground up. (But I freely admit that this is following on the heels of searches for something along the lines of "IT+Fortune500" not returning the data because the search engine was treating + as a word breaker and then treating IT as "it" which is just a noise word to be discarded, so the search was really just looking for Fortune500 and thus returning stuff like "Fortune500 Rainbows" and "Bunnies and Fortune500 Flowers" and, more importantly, working as intended by the vendor.)

Saturday, July 19, 2008

Naked Silvia and Riesberries plus Eddie, God and Zeus

If the double-shot basket isn't adequately (fully) packed, the flow rate is going to be too high and result in underextraction even if the grind is finer than usual. The basket should be groomed to the brim before tamping.

That said, here are some almost-good-enough-to-post-but-I'm-impatient-and-posting-them-anyway shots of why bottomless portafilters are dead sexy:
The grind was both finer than usual and ever so slightly overpacked. But I do love catching the individual droplets in mid-air...

On a related note, we found a bottle of Montinore Semi-Dry Riesling. This used to be our bar-none favorite white wine because it smacked of pineapple and other summery things. It doesn't do that anymore, which made me a bit sad -- so I added some raspberries to it!
The raspberries added just the extra bit of fruit flavor the wine needed and, when left to soak in the riesling long enough, were the most astoundingly and iconickly -- it's a word now! -- delicious raspberries I've ever tasted. And the spouse agrees.

Diverging from the food topic, seeing Eddie Izzard on his Stripped tour in which he stakes out a theological position more humanist than Kurt Vonnegut (who actually did know stuff about the Bible beyond the abject basics -- read the last chapter of Palm Sunday, it's brilliant) evidently based on the long-standing narrative that God is some old euro-guy with a big white beard. And what clearly stuck me about this narrative, what with so much of Eddie's schtick being history-based (and on this point Stripped was barely adequate; Dressed to Kill is still my favorite performance of his -- but it's still worth seeing live), was that the old-man-God narrative that has been propigated up not necessarily from the Judeo-Christian God, but rather from the polytheistic religions, especially the Greeks with old-man-Zeus transferring to the Romans with old-man-Jupiter claiming to adopt Christianity some three centuries after the core facts and then imperializing up to the British, by Jove. If you doubt this, then ask yourself why some people, especially young Christians, expect God to smite heretics and blasphemers with lightning -- the weapon of choice for Zeus/Jupiter -- when, as near as I can tell, the Bible contains no record of God smiting anybody with lightning per se. So the short of this issue comes down to: Are many Christians worshipping Zeus by mistake? Is that why the core gospel of the religion can make it the most popular religion in the world and yet the full and complex tradition of the religion incites intellectual backlash? If anybody's seen deeper research or hypothesis on this, please post it otherwise I may have found a historical niche I want to dig into later on in life...

Thursday, May 8, 2008

How To Cook Like A Man

Okay, sorry about the retrograde title but the spouse loves it when I do the whole cooking-red-meat-with-fire thing, so it really does fit with what's going to be written. And now that I've got a pretty solid and replicatable technique for grilling steak, I'm ready to share it.

First of all, you're going to need meat. We prefer buffalo, like the meat that gets sold by ranches like this one. It's generally much leaner, more intense and also easier to digest than cattle. We buy our buffalo wholesale, a quarter of a beasty at a time -- which compromises the quality of the meat a bit as we're eating it out of our freezer for quite some time, but overall it's not bad, it saves a lot of money, and is delightfully organic-enough meat.

Besides, never mind the freezer, step two is Improve the Steak with Salt. It's a brilliant little trick that even works. Before you start your grill, lay out the steaks you're going to cook and encrust them with a hefty layer of rock salt. The magic chemistry does wonderful things to the meat. When you're ready to start grilling 25+ minutes later, thoroughly rinse the salt off, pat the steaks dry (or rather less-wet) with a paper towel or somesuch and toss them on.

But we're not ready to toss them on yet because we've not started the BBQ. So let's get some hardwood lump charcoal, a BBQ grill for two, a few eggs' worth of cardboard egg carton, and a chimney starter. You'll also need matches or a lighter, take your pick. Now it's time to play with fire...
  • Open the bottom vent of your grill at least halfway. Make sure you can see through it. We need air to get through there to creat a nice updraft.
  • Take the top grill off of your BBQ to access the charcoal pit. If there's charcoal already in there, load it into your chimney starter. (I use tongs for that because I don't like getting my paws all sooty.)
  • Top off your chimney starter with fresh charcoal. You'll probably want it full or almost full, but that really depends on how big your starter is compared to how small your grill is. I go up to about 90% full on my starter, which is just a cheap little thing that looks like it was made by a high schooler in metal shop -- but it still works great.
  • Separate the egg-cups of your egg carton and tuck them up in the bottom of the chimney starter as your kindling. Egg carton works better than newspaper because it's heavier and less likely to blow away, is covered with rather less greasy ink, and has a nice shape to ensure that pockets of air exist for the fire to consume.
  • Set your loaded chimney starter vertically in the BBQ charcoal pit, egg cartons at the bottom and charcoal at the top.
  • Light the egg carton in several places around the base of the chimney starter. What's going to happen, in short, is that the heat from the fire is going to be travelling upwards but will be contained by the chimney and thus focused on the charcoal such that they'll have a nice long-starting burn. As the heat rises and take the air up and out with it, air from below -- remember those open vents? -- will be sucked up to replace it such that the fire has a source of air to keep heating the charcoal.
  • About 20+ minutes later, the heat should've ignited all of the charcoal. You'll know it's ready when the charcoal on top starts turning white. At this point, very carefully pick up your chimney starter just by the handle and spill out the flaming hot charcoal into your BBQ. Set the chimney starter aside.
  • Put the top grill (it is clean, right?) on the BBQ to start heating up.
  • Close the bottom vent 40-60% of the way -- we still want an updraft, but only a very little one. Too much air will result in our charcoal burning faster, but now that we've got the charcoal started, our goal is to maintain its temperature. You may want to partially lay the BBQ on top of the BBQ (with its vents open) to further reduce the amount of air that's fanning the flames. I do not recommend fully putting the lid on at this point. Just lay it on at a jaunty angle or something.

You'll notice that there was no lighter fluid used, either on or in the charcoal. This is because lighter fluid is a chemical abomination that adds a very nasty sharp flavor to the meat. The fantastic physics of the chimney starter trump the mediocre chemistry of the lighter fluid. Really they do.

Okay, so now we go inside and rinse our salty meat because we want to taste great meat, not salt. Stick it with a fork a few times so you know how it feels raw and then take it out and slab it on the grill. Close the grill lid, but leave the vents open. Rotate the lid so that the vents are as close to directly above the meat as possible -- if you visualize the air going from the bottom vents to the top vents, you want it going straight through the meat, not escaping off to the side.

Now you may want to add some grill effects to your steak. For our season opener, here's what I did:

  • Take a shotglass. Because shotglasses are fun.
  • Fill it halfway with olive oil. This is sticky and fatty without being unhealthy, and olives have a good flavor to go with meat -- though you wouldn't really know it until you've had a green olive relish on a steak sandwich.
  • Add a bit of Worschester sauce. This is our augmented salt above and beyond what minor residue was left over from salting your steak.
  • Put a lot of garlic powder in. It goes well with the olive oil.
  • Put even more oregano in. I'm an oregano fanatic. Feel free to substitute whatever leafy herb you prefer -- I suppose basil or rosemary would also be popular choices.
  • Grind a dash of black pepper on the top (or use more of it if you're a black pepper fanatic).
  • Stir the shotglass with a toothpick or somesuch.
  • Now drink that nasty mix and... wait, no, take it outside for the meat. Don't actually drink it at all. Really. Don't.

Pour about 2/3rds of your mixture on the top of your meat which should be turning a nice shade of brown and making pleasing "sizzle" noises. When the meat is mostly brown, turn it over to finish cooking and pour the rest of your mixture on the already mostly-done side. Then close the lid and go get a knife and a fork. The next time you see your meat, you'll be cutting it open to ensure that it's done well enough to your liking. If it's not adequately done, turn it one last time to let it finish up. You should never have to turn your steak more than twice.

Please note that the amount of time meat needs to cook in this manner is based primarily on its thickness so I can't really advise on how long the actual cooking takes. If you want a quicker-cooking steak that gets more done and chewy, go thin. But ever since I've gotten the coals to behave themselves consistently, I've been going for thicker steaks with rarer cookings -- the goal is to sear the outside of the steak to seal in the juices while getting the whole thing hot enough to kill anything nasty that's festering inside of it. And if you're anywhere close to getting a good searing, then you won't have to turn your steak more than twice in the process of getting it cooked.

So there's your steak. Offload it to a platter, put the lid back on top of the grill but don't close the vents yet. Take your steak in and enjoy a proper meal. Things that go well with steak would include:

  • Red wine. I'm a big fan of Australian wines, but they've kind of flooded the market. As a result, we're picking up more wines from South Africa lately. I'm particularly keen on Indaba's reds as I've had their Shiraz, Merlot and now Pinotage and they're all quite lovely. (Just to clarify, they're the bottles with the swirled logos.)
  • Bread, either a white baguette or a ciabatta (with olives!), maybe a sourdough. The bread soaks up the extra tasty juices that would otherwise make a mess of your plate.
  • Cheese, the sharper the better -- though this varies by taste. I've only recently acquired a taste for Stilton cheese, but it was brain-bendingly good with the Indaba Pinotage.
  • Green olives, stuffed with either blue cheese (in leiu of the cheese directly) or garlic (if you're skipping the cheese to stay kosher). But really, if it's just you and the mistress (really, what did you think "Mrs" was compressed from?), go for the potent cheese -- as far as I know the original kosher law was regarding not boiling baby critters in their mothers' milk, and we're just eating cheese with our fantastically BBQ'd steak from a buffalo which is hardly the same thing.

You'll notice that there isn't much in the way of salad with this meal. That's because we're cooking like a man and frankly steaks and salads don't do well together. If you want more plant matter, try any of the following: orange bell pepper (before the meal), roma tomato (before or after the meal), or a mango (after the meal).

This is the part where you go nom nom nom nom nom.

Okay, now that you're well-fed, it's time to step back outside and close the BBQ vents now that they've pretty well sterilized and carbonized the grill.

Unless you want to toast marshmallows over the coals for s'mores -- or just toasted marshmallows --which is the other thing we do a lot of. But that's more of a grilled-burger kind of activity. Grilled burgers are very similar to steaks, except that they need to really cook until done, only get turned once, go on very tasty ciabatta rolls, use fresh basil leaves -- not frikkin' lettuce! -- as greens, has cheese melted right onto it... and might use a raspberry ale instead of red wine.

Anyway, that's what works for me. You can probably get more and possibly better information by digging around any of the links I've included, or going and seeing what Ronnie Shewchuk does. After all, it was from reading about his penchant for hardwood charcoal that I got started on my path of using fire as a proper cooking tool.

Update: Now with pictures from my last BBQ!

Monday, March 17, 2008

Works for Me: Purging abandoned files in SharePoint 2007

Hah.

So regarding the problems I was facing in the previous post, I think I have a solution -- and all I had to do was slack off playing Super Smash Bros Brawl over the weekend which, I was amazed and delighted to discover, includes a fairly extensive platformer game featuring co-op multiplayer and some astoundingly good (and really dang funny) cutscenes.

But you're probably here for the solution. Okay, so where we started was with "get the document library by name as a list from the web from the site, the files are items in the list" and that wasn't working for items that had never been checked in and didn't belong to the person running the process. Well it turns out that there's a SPDocumentLibrary type that has a CheckedOutFiles property that returns an IList of SPCheckedOutFiles and you can see the files that you might be looking for in there. That could look something like this:

SPDocumentLibrary srcLibrary = (SPDocumentLibrary)srcList;
List<SPCheckedOutFile> suspectFiles = srcLibrary.CheckedOutFiles as List
<SPCheckedOutFile>;


Now you might be a bit confounded about the srcList being cast over to an SPDocumentLibrary and so might your runtime, so checking compatibility on that (ahead of time!) is probably a good idea. That line looks like this:

SPList srcList = site.Lists[_listName];
if (srcList.BaseType != SPBaseType.DocumentLibrary) { throw new Exception(); }


So now we've got our Document Library and our list of Checked Out Files which does include all of the files that our careless users have abandoned and also does include all of the checked out files that our careful users are editing at the moment. So to make sure that we purge only the right files, we're going to compare our Checked Out Files to the list of files we can see in srcList.Items. It's not wildly performant, but if we toss the names of all of the valid files into a list declared as such:

List<string> validItemNames = new List<string>();

They'll all be there when we need them. No, it's not great, it's what I did while I was sitting in a meeting this morning. That said, the performance isn't going to be awful because the goal is to get the valid files (which are the overwhelming majority) into a list so we can compare against them with our abandoned files (better darned well be the overwhelming minority) to see if it's time to delete our abandoned files.

Now I have to admit that our implementation made my job easy -- we can't have two files with the same name, so I'm able to compare FileLeafRef (from the Items) to LeafName (from the SPCheckedOutFile) to determine whether or not the file has never been checked in. Remember, if it's not in the items but has been checked out, then it's never been checked in and we can delete it. I think. That said, there are ID fields on both the Items and the SPCheckedOutFile and I suspect that they will also work for this comparison.

There's one other bit of performance we can improve upon against that list of strings, and that is to have our purgeable date threshhold checked (against our SPCheckedOutFile's TimeLastModified) before we go and -- or rather, && -- check to see if the file has a check-in history visible to the world. So that'll help a bit too. And we could've skipped the whole thing if the library's CheckedOutFiles returned null or 0 results. So there's lots of minor performance enhancers that require no algorithmic effort here; just following an appropriate order of operations.

The one bizarre behavior of this comparison is that the Items list will retrieve any content that the current user has created (which is how we missed that it wouldn't pick up stuff that had never been checked in in the first place) with the net result of that being that if you run this kind of tool as an actual user, that user won't be able to purge their own checked-out files because they'll be able to see their files on the valid file list. Whee.

That's how I spent my Monday, how was yours?

Update: And how I spent my Tuesday, excepting a very long meeting which continually looks ahead to the work we won't get done as opposed to addressing the work we should be doing instead of looking ahead, was discovering that this process described above tends to fail. It tends to fail because apparently the SPCheckedOutFile's Delete() method will always fail if it's called by anybody who isn't the file's owner. Even a site administrator that can take the file over in the blink of an eye. Yeah. They get a big fat exception, too. So the net effect is that if you're going to delete somebody else's checked-out file (with no check-in history on it at all), then you're going to need to take it over like this:

myFile.TakeOverCheckOut();
myFile.Delete();