Index: trunk/Nebulous-Server/Build.PL
===================================================================
--- trunk/Nebulous-Server/Build.PL	(revision 16354)
+++ trunk/Nebulous-Server/Build.PL	(revision 16565)
@@ -84,5 +84,8 @@
         'DBD::mysql'            => '3.0007',
         'DBI'                   => '1.53',
+        'Digest::SHA1'          => 0,
         'File::ExtAttr'         => '1.03',
+        'File::Path'            => '1.08',
+        'File::Spec'            => 0,
         'File::Spec::Functions' => 0,
         'Log::Log4perl'         => '0.48',
Index: trunk/Nebulous-Server/Changes
===================================================================
--- trunk/Nebulous-Server/Changes	(revision 16354)
+++ trunk/Nebulous-Server/Changes	(revision 16565)
@@ -2,4 +2,5 @@
 
 0.07
+    - add support for storing instances in multi-tier 'hashed' directories 
     - pickup test DB settings from the env.
     - add neb-ls -l|-1 option
Index: trunk/Nebulous-Server/lib/Nebulous/Server.pm
===================================================================
--- trunk/Nebulous-Server/lib/Nebulous/Server.pm	(revision 16354)
+++ trunk/Nebulous-Server/lib/Nebulous/Server.pm	(revision 16565)
@@ -1,5 +1,5 @@
 # Copyright (c) 2004  Joshua Hoblitt
 #
-# $Id: Server.pm,v 1.52 2008-02-07 22:18:51 jhoblitt Exp $
+# $Id: Server.pm,v 1.53 2008-02-21 23:20:39 jhoblitt Exp $
 
 package Nebulous::Server;
@@ -13,5 +13,8 @@
 
 use DBI;
+use Digest::SHA1 qw( sha1_hex );
 use File::ExtAttr qw( setfattr );
+use File::Path;
+use File::Spec;
 use Log::Log4perl;
 use Nebulous::Server::Config;
@@ -23,4 +26,6 @@
 
 __PACKAGE__->mk_accessors(qw( log sql config ));
+
+use constant SUBPATH_DEPTH => 3;
 
 sub new {
@@ -1229,12 +1234,16 @@
     my $log = $self->log;
     my $sql = $self->sql;
-    my $db  =$self->db;
-
-    my ($storage_filename);
-    my ($uri);
-    eval {
-        $storage_filename = $self->_generate_storage_filename($key, $ins_id);
-        # XXX put a hook for directory hashing here
-        $uri = URI::file->new("$vol_path/$storage_filename");
+    my $db  = $self->db;
+
+    my $uri;
+    eval {
+        my $storage_path = $self->_generate_storage_path($key, $vol_path);
+        my $storage_filename = $self->_generate_storage_filename($key, $ins_id);
+        unless (-d $storage_path) {
+            mkpath($storage_path)
+                or die "can't create storage path: $storage_path";
+        }
+        my $fqpn = File::Spec->catfile($storage_path, $storage_filename);
+        $uri = URI::file->new($fqpn);
         $log->debug("generated uri $uri");
         $self->_create_empty_file($uri->file);
@@ -1291,4 +1300,19 @@
 
 
+sub _generate_storage_path
+{
+    my $self = shift;
+
+    my ($key, $vol_path) = @_;
+
+    # taken and modified from Cache::File::cache_file_path()
+    # Copyright (C) 2003-2006 Chris Leishman.  All Rights Reserved.
+    my $shakey = sha1_hex($key);
+    my (@path) = unpack('A2' x SUBPATH_DEPTH, $shakey);
+
+    return File::Spec->catdir($vol_path, @path);
+}
+
+
 sub DESTROY
 {
