Started refactoring of Iterator hierarchy
Rob Kinyon [Fri, 25 Dec 2009 22:55:05 +0000 (17:55 -0500)]
lib/DBM/Deep/Engine.pm
lib/DBM/Deep/Engine/DBI.pm
lib/DBM/Deep/Engine/File.pm
lib/DBM/Deep/Iterator.pm
lib/DBM/Deep/Iterator/DBI.pm [new file with mode: 0644]
lib/DBM/Deep/Iterator/File.pm [new file with mode: 0644]
lib/DBM/Deep/Iterator/File/BucketList.pm [moved from lib/DBM/Deep/Iterator/BucketList.pm with 97% similarity]
lib/DBM/Deep/Iterator/File/Index.pm [moved from lib/DBM/Deep/Iterator/Index.pm with 97% similarity]

index 6e6147e..999a65c 100644 (file)
@@ -243,7 +243,7 @@ sub get_next_key {
     # XXX Need to add logic about resetting the iterator if any key in the
     # reference has changed
     unless ( $prev_key ) {
-        $obj->{iterator} = DBM::Deep::Iterator->new({
+        $obj->{iterator} = $self->iterator_class->new({
             base_offset => $obj->_base_offset,
             engine      => $self,
         });
index 39e7246..7d28615 100644 (file)
@@ -11,6 +11,7 @@ use DBM::Deep::Sector::DBI ();
 use DBM::Deep::Storage::DBI ();
 
 sub sector_type { 'DBM::Deep::Sector::DBI' }
+sub iterator_class { 'DBM::Deep::Iterator::DBI' }
 
 sub new {
     my $class = shift;
index d40b51e..cda6128 100644 (file)
@@ -14,6 +14,7 @@ use DBM::Deep::Sector::File ();
 use DBM::Deep::Storage::File ();
 
 sub sector_type { 'DBM::Deep::Sector::File' }
+sub iterator_class { 'DBM::Deep::Iterator::File' }
 
 my $STALE_SIZE = 2;
 
index 26e81a2..4dfe3e0 100644 (file)
@@ -5,8 +5,8 @@ use 5.006_000;
 use strict;
 use warnings FATAL => 'all';
 
-use DBM::Deep::Iterator::BucketList ();
-use DBM::Deep::Iterator::Index ();
+use DBM::Deep::Iterator::DBI ();
+use DBM::Deep::Iterator::File ();
 
 =head1 NAME
 
@@ -63,110 +63,24 @@ This method returns nothing.
 
 =cut
 
-sub reset { $_[0]{breadcrumbs} = [] }
+sub reset { $_[0]{breadcrumbs} = []; return }
 
 =head2 get_sector_iterator( $loc )
 
-This takes a location. It will load the sector for $loc, then instantiate the right
-iteartor type for it.
+This takes a location. It will load the sector for $loc, then instantiate the
+right iteartor type for it.
 
 This returns the sector iterator.
 
 =cut
 
-sub get_sector_iterator {
-    my $self = shift;
-    my ($loc) = @_;
-
-    my $sector = $self->{engine}->load_sector( $loc )
-        or return;
-
-    if ( $sector->isa( 'DBM::Deep::Sector::File::Index' ) ) {
-        return DBM::Deep::Iterator::Index->new({
-            iterator => $self,
-            sector   => $sector,
-        });
-    }
-    elsif ( $sector->isa( 'DBM::Deep::Sector::File::BucketList' ) ) {
-        return DBM::Deep::Iterator::BucketList->new({
-            iterator => $self,
-            sector   => $sector,
-        });
-    }
-
-    DBM::Deep->_throw_error( "get_sector_iterator(): Why did $loc make a $sector?" );
-}
+sub get_sector_iterator { die "get_sector_iterator must be implemented in a child class" }
 
 =head2 get_next_key( $obj )
 
 =cut
 
-sub get_next_key {
-    my $self = shift;
-    my ($obj) = @_;
-
-    my $crumbs = $self->{breadcrumbs};
-    my $e = $self->{engine};
-
-    unless ( @$crumbs ) {
-        # This will be a Reference sector
-        my $sector = $e->load_sector( $self->{base_offset} )
-            # If no sector is found, this must have been deleted from under us.
-            or return;
-
-        if ( $sector->staleness != $obj->_staleness ) {
-            return;
-        }
-
-        my $loc = $sector->get_blist_loc
-            or return;
-
-        push @$crumbs, $self->get_sector_iterator( $loc );
-    }
-
-    FIND_NEXT_KEY: {
-        # We're at the end.
-        unless ( @$crumbs ) {
-            $self->reset;
-            return;
-        }
-
-        my $iterator = $crumbs->[-1];
-
-        # This level is done.
-        if ( $iterator->at_end ) {
-            pop @$crumbs;
-            redo FIND_NEXT_KEY;
-        }
-
-        if ( $iterator->isa( 'DBM::Deep::Iterator::Index' ) ) {
-            # If we don't have any more, it will be caught at the
-            # prior check.
-            if ( my $next = $iterator->get_next_iterator ) {
-                push @$crumbs, $next;
-            }
-            redo FIND_NEXT_KEY;
-        }
-
-        unless ( $iterator->isa( 'DBM::Deep::Iterator::BucketList' ) ) {
-            DBM::Deep->_throw_error(
-                "Should have a bucketlist iterator here - instead have $iterator"
-            );
-        }
-
-        # At this point, we have a BucketList iterator
-        my $key = $iterator->get_next_key;
-        if ( defined $key ) {
-            return $key;
-        }
-        #XXX else { $iterator->set_to_end() } ?
-
-        # We hit the end of the bucketlist iterator, so redo
-        redo FIND_NEXT_KEY;
-    }
-
-    DBM::Deep->_throw_error( "get_next_key(): How did we get here?" );
-}
+sub get_next_key { die "get_next_key must be implemented in a child class" }
 
 1;
 __END__
diff --git a/lib/DBM/Deep/Iterator/DBI.pm b/lib/DBM/Deep/Iterator/DBI.pm
new file mode 100644 (file)
index 0000000..3b8f1c8
--- /dev/null
@@ -0,0 +1,9 @@
+package DBM::Deep::Iterator::DBI;
+
+use strict;
+use warnings FATAL => 'all';
+
+use base qw( DBM::Deep::Iterator );
+
+1;
+__END__
diff --git a/lib/DBM/Deep/Iterator/File.pm b/lib/DBM/Deep/Iterator/File.pm
new file mode 100644 (file)
index 0000000..d2d5437
--- /dev/null
@@ -0,0 +1,102 @@
+package DBM::Deep::Iterator::File;
+
+use strict;
+use warnings FATAL => 'all';
+
+use base qw( DBM::Deep::Iterator );
+
+use DBM::Deep::Iterator::File::BucketList ();
+use DBM::Deep::Iterator::File::Index ();
+
+sub get_sector_iterator {
+    my $self = shift;
+    my ($loc) = @_;
+
+    my $sector = $self->{engine}->load_sector( $loc )
+        or return;
+
+    if ( $sector->isa( 'DBM::Deep::Sector::File::Index' ) ) {
+        return DBM::Deep::Iterator::Index->new({
+            iterator => $self,
+            sector   => $sector,
+        });
+    }
+    elsif ( $sector->isa( 'DBM::Deep::Sector::File::BucketList' ) ) {
+        return DBM::Deep::Iterator::BucketList->new({
+            iterator => $self,
+            sector   => $sector,
+        });
+    }
+
+    DBM::Deep->_throw_error( "get_sector_iterator(): Why did $loc make a $sector?" );
+}
+
+sub get_next_key {
+    my $self = shift;
+    my ($obj) = @_;
+
+    my $crumbs = $self->{breadcrumbs};
+    my $e = $self->{engine};
+
+    unless ( @$crumbs ) {
+        # This will be a Reference sector
+        my $sector = $e->load_sector( $self->{base_offset} )
+            # If no sector is found, this must have been deleted from under us.
+            or return;
+
+        if ( $sector->staleness != $obj->_staleness ) {
+            return;
+        }
+
+        my $loc = $sector->get_blist_loc
+            or return;
+
+        push @$crumbs, $self->get_sector_iterator( $loc );
+    }
+
+    FIND_NEXT_KEY: {
+        # We're at the end.
+        unless ( @$crumbs ) {
+            $self->reset;
+            return;
+        }
+
+        my $iterator = $crumbs->[-1];
+
+        # This level is done.
+        if ( $iterator->at_end ) {
+            pop @$crumbs;
+            redo FIND_NEXT_KEY;
+        }
+
+        if ( $iterator->isa( 'DBM::Deep::Iterator::Index' ) ) {
+            # If we don't have any more, it will be caught at the
+            # prior check.
+            if ( my $next = $iterator->get_next_iterator ) {
+                push @$crumbs, $next;
+            }
+            redo FIND_NEXT_KEY;
+        }
+
+        unless ( $iterator->isa( 'DBM::Deep::Iterator::BucketList' ) ) {
+            DBM::Deep->_throw_error(
+                "Should have a bucketlist iterator here - instead have $iterator"
+            );
+        }
+
+        # At this point, we have a BucketList iterator
+        my $key = $iterator->get_next_key;
+        if ( defined $key ) {
+            return $key;
+        }
+        #XXX else { $iterator->set_to_end() } ?
+
+        # We hit the end of the bucketlist iterator, so redo
+        redo FIND_NEXT_KEY;
+    }
+
+    DBM::Deep->_throw_error( "get_next_key(): How did we get here?" );
+}
+
+1;
+__END__
similarity index 97%
rename from lib/DBM/Deep/Iterator/BucketList.pm
rename to lib/DBM/Deep/Iterator/File/BucketList.pm
index 577b5c2..d23a8ca 100644 (file)
@@ -1,4 +1,4 @@
-package DBM::Deep::Iterator::BucketList;
+package DBM::Deep::Iterator::File::BucketList;
 
 use 5.006_000;
 
similarity index 97%
rename from lib/DBM/Deep/Iterator/Index.pm
rename to lib/DBM/Deep/Iterator/File/Index.pm
index cdc28df..6c7f815 100644 (file)
@@ -1,4 +1,4 @@
-package DBM::Deep::Iterator::Index;
+package DBM::Deep::Iterator::File::Index;
 
 use 5.006_000;