Alan Gutierrez

Alan Gutierrez blogs on software, social networks, and himself.

Subscrive Via RSS Feed

Cyberduck

Cyberduck File Browser

Picture of the Cyberduck file browser by Cyberduck.

With all the catch up reading that I was able to do over the holidays, I was able to read about my Macintosh and came across Cyberduck. Cyberduck is an FTP and SFTP (file transfer via SSH otherwise known as SCP) utility for OS X released under the GNU Public License. It now replaces Fugu as my GUI SCP tool, which I rarely used because it felt slow. It even replaces the command line SCP which I always use because I’m familiar with the shell.

Sheaf

Sheaf Toss

Sheaf Toss by Ian Langworth.

Last Saturday morning, on my way to Fair Grinds for my morning coffee, something occurred to me about persistent object storage. I’m less certain as to why. I’ve not thought about that component of my application development in a long time. I implemented persistent storage using the basics of the malloc algorithm in a project that I called Bento.

Pages of Blocks with Identifiers

When I got to Fair Grinds I began to exchange instant messages with Brian Kerr or Ann Arbor, Michigan. I described the idea as follows.

A fixed page length, 8k or 16k. The address is a file position plus a short. It is a big address, I know. The blocks are stored in a page with a number to identify the blocks followed by the object length followed by the block data. To find a block, to the file position, load the page into memory, skip through the blocks until you find the one with the matching block number.

Within a page the block is sought so that within a page blocks can be relocated within the page. If a block is deleted, the contents following the block are shifted up. The moved blocks can still be found because we are skipping through the page form an offset.

Then Brian started asking questions and sorting out details. It was good to have someone think about the problem.

If you have a block larger than a single page, you break it up among pages. You use however many empty pages necessary to hold the block and put the remainder in a page that contains many blocks.

The file format supports journaling, so there is a concept of isolation. Isolation is modeled with a Mutator object. Changes to the file are called a mutation, rather than a transaction, since transaction implies a lot more hocus-pocus.

While the file format can handle concurrent requests, it cannot handle concurrent requests on the same block. It is up to the application developer to ensure that no two threads mutate the same block at the same time. It is up to the application developer to ensure that no thread reads a mutating block. The only manipulation that is permitted concurrently is read. Block allocations are going to be visible only to the thread that allocated them. Writes and frees are going to require synchronization on the part of the application.

In memory, a sorted map of lists of blocks with free space remaining is kept sorted on the amount remaining rounded down to an alignment. When a block is allocated it is rounded up to the next alignment and we search for the block with the smallest amount remaining that can fit the block. That block is used.

Separately, there is a list of pages that have been entirely emptied through deallocations.

The file format uses ByteBuffer objects kept in memory as buffers that represent the contents on disk. The ByteBuffer objects indicate what the disk will look like when the contents of the page are journaled. They can be out of sync with the file, but that is OK. This discrepancy between our in memory representation of the file and the on disk representation of the file allow us to implement journaling.

Commits to this file format are journaled. There are two journals available, an external file journal and an internal journal that uses pages in the file. For the internal journals the file format keeps a block of pointers in the header of the file. The default number of pointers is 64. To create a journal, one of the pointers is set to the address of the first page in a linked list of pages. This is set in the ByteBuffer that is in memory, however and not on disk. The address of the start of the linked list of journal pages is now written out until the journal commits. It is written out last and the file channel is forced to flush. Thus, on disk the pointers will only ever point to a complete journal.

In addition to a linked list of journal pages of journal actions, like allocate, write and free, the journal needs to allocate temporary blocks where the mutation can write changes without disturbing the actual block in memory or on disk. The temporary block contains the applications intent. It is copied over to the actual block during commit.

Delete Makes the File Grow

I set out to implement the file format. I’d hoped to have tests running on Monday. I begged off engagements. I sat before my computer and worked through each next logical task. I was not finished on Monday, so I forced myself to stop and resume my civic pursuits, while fiddling with the code and the concepts in my free time.

By Friday, the idea of the block identifier has run it’s course, before the code was complete.

An external journal meant that this file format would create a nice and compact file format. An internal journal would fill the file with empty journal pages. What really tripped me up was when I realized deletion could not be implemented as simply shifting the blocks following a deleted block up if I wanted the deletion to be journaled. The destination and the source of the copy were on the same page. If the page were to be corrupted their would be no way to recreate it. I would have to allocate copies of blocks following the deleted block in the journal. They would be safely on disk as part of the journal commit. The delete would then copy the blocks over from the journal.

This meant that a delete would actually cause the file to grow and grow large. If the first block on a page is deleted, a temporary block has to be allocated for all the other pages in the block. I couldn’t imagine myself very happy with a larger file.

Can the file ever shrink? Sure. If the pages at the end of the file empty, then we can truncate the file. We can always be on the lookout for empty pages at the end of a mutation and rewind the file.

But then, imagine a case where an application deletes a very large collection of objects. These deletions consume all the free pages for the journal. Then the deletions begin to create new journal pages at the end of the file. If another thread allocates a new object, the other thread couldn’t make use of all the free space created in isolation so it would have to allocate a block from a new page at the end of the file. When the thread with the deletions completes, it will free all of the journal pages, but the file cannot be rewound because there is a user page following all the freed journal pages.

The file would have a huge swath of empty pages just before the last page in the file. They would be reused eventually, but how counter-intuitive to delete objects and have the database grow in size on disk. That would be so hard to explain to people. It feels wrong.

I started to think about indirection, and a name for a new project.

Not a Blog Post, Not a Wiki Page, I Want An Ongoing Conversation

Lance Hill sent me a link to another article by Adam Nossiter in the New York Times. Nossiter is off drinking at the trough of Uptown’s conventional wisdom in his article Whites Take a Majority on New Orleans’s Council.

There is a post at Think New Orleans called Is Adam Nossiter a Tool? That question stands. I don’t want to write a new article about the matter, but rather have people continue to discuss the issue under the existing article. What I really want is a website that will allow me to feature this article once again, or rather bring this subject up in the context of the conversations that took place before. It is very important to preserve both the existing discussion and the timeline of events.

Which is something that is common to most of my civic writing. I do want to encourage participation in the conversation, so I want to resurrect the existing conversation, with the exisiting participants. Most people subscribe to email notifications of comments of a particular post. To notify them that Adam Nossiter is banging on about race and quoting Greg Rigamer, I need to continue the discussion under the previous post.

Although, I’m pleased that WordPress is now performing acceptably, both blogs and Wikis fail to make my efforts in New Orleans easier.

PLEAC-Groovy

I came across this resource months ago. I forgot about it until I recently discovered an email that I sent to the author expressing my awe. It is a translation of the Perl Cookbook into Groovy.

ArborWiki Style and Forms

In an IM exchange with Matt Hampel of ArborWiki, we discussed how I’m using the ArborWiki theme to create a new, database driven implementation of the List of New Orleans Bloggers. I asked Matt about forms and he pointed me toward work that he’d done at Ann Arbor’s Community High School, specifically the form guidelines for the school’s website. Moreover, he sent a link to a blog called Functioning Form where I found a post called Web Form Design Best Practices which has a presentation in PDF that is a great start in understanding form design.

WordPress Is Working at Think New Orleans

I removed a hack that I’d thrown in to implement asides. Think New Orleans has been slow. It is now performs acceptably. I’d not feel like posting much lately, since I couldn’t imagine anyone wanting to read a website that took 30 seconds to load.

Expert Networking Techniques from a Playground-Savvy 9-Year Old

I was reading Christopher Johnston today and he linked to this very lovely story Expert networking techniques from a playground-savvy 9-year old.

How to Cull You RSS Feeds: Eliminate the Douche Bags

Michael Arrington publishes an email from a college student distraught because his Facebook account was revoked. He then goes on to say. “And frankly, I don’t care all that much, ’cause the last thing I want is for everyone with a Facebook customer service issue to start emailing me.” That whiff of self-importance was too pungent. He made an article of this kid’s email, but then has to make a backhanded statement. Honestly, who really needs to read TechCrunch anyway? Update: Same post at TechCrunch; what a bunch of idiot comments. Both Arrington and his readers miss the point entirely.

« Previous Entries Next Entries »