# 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,
});
use DBM::Deep::Storage::DBI ();
sub sector_type { 'DBM::Deep::Sector::DBI' }
+sub iterator_class { 'DBM::Deep::Iterator::DBI' }
sub new {
my $class = shift;
use DBM::Deep::Storage::File ();
sub sector_type { 'DBM::Deep::Sector::File' }
+sub iterator_class { 'DBM::Deep::Iterator::File' }
my $STALE_SIZE = 2;
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
=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__
--- /dev/null
+package DBM::Deep::Iterator::DBI;
+
+use strict;
+use warnings FATAL => 'all';
+
+use base qw( DBM::Deep::Iterator );
+
+1;
+__END__
--- /dev/null
+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__
-package DBM::Deep::Iterator::BucketList;
+package DBM::Deep::Iterator::File::BucketList;
use 5.006_000;
-package DBM::Deep::Iterator::Index;
+package DBM::Deep::Iterator::File::Index;
use 5.006_000;