1 package DBM::Deep::Iterator;
6 use warnings FATAL => 'all';
8 use DBM::Deep::Iterator::BucketList ();
9 use DBM::Deep::Iterator::Index ();
17 This is an internal-use-only object for L<DBM::Deep/>. It is the iterator
18 for FIRSTKEY() and NEXTKEY().
28 The constructor takes a hashref of params. The hashref is assumed to have the
33 =item * engine (of type L<DBM::Deep::Engine/>
35 =item * base_offset (the base_offset of the invoking DBM::Deep object)
47 engine => $args->{engine},
48 base_offset => $args->{base_offset},
51 Scalar::Util::weaken( $self->{engine} );
58 This method takes no arguments.
60 It will reset the iterator so that it will start from the beginning again.
62 This method returns nothing.
66 sub reset { $_[0]{breadcrumbs} = [] }
68 =head2 get_sector_iterator( $loc )
70 This takes a location. It will load the sector for $loc, then instantiate the right
73 This returns the sector iterator.
77 sub get_sector_iterator {
81 my $sector = $self->{engine}->load_sector( $loc )
84 if ( $sector->isa( 'DBM::Deep::Sector::File::Index' ) ) {
85 return DBM::Deep::Iterator::Index->new({
90 elsif ( $sector->isa( 'DBM::Deep::Sector::File::BucketList' ) ) {
91 return DBM::Deep::Iterator::BucketList->new({
97 DBM::Deep->_throw_error( "get_sector_iterator(): Why did $loc make a $sector?" );
100 =head2 get_next_key( $obj )
108 my $crumbs = $self->{breadcrumbs};
109 my $e = $self->{engine};
111 unless ( @$crumbs ) {
112 # This will be a Reference sector
113 my $sector = $e->load_sector( $self->{base_offset} )
114 # If no sector is found, this must have been deleted from under us.
117 if ( $sector->staleness != $obj->_staleness ) {
121 my $loc = $sector->get_blist_loc
124 push @$crumbs, $self->get_sector_iterator( $loc );
129 unless ( @$crumbs ) {
134 my $iterator = $crumbs->[-1];
136 # This level is done.
137 if ( $iterator->at_end ) {
142 if ( $iterator->isa( 'DBM::Deep::Iterator::Index' ) ) {
143 # If we don't have any more, it will be caught at the
145 if ( my $next = $iterator->get_next_iterator ) {
146 push @$crumbs, $next;
151 unless ( $iterator->isa( 'DBM::Deep::Iterator::BucketList' ) ) {
152 DBM::Deep->_throw_error(
153 "Should have a bucketlist iterator here - instead have $iterator"
157 # At this point, we have a BucketList iterator
158 my $key = $iterator->get_next_key;
159 if ( defined $key ) {
162 #XXX else { $iterator->set_to_end() } ?
164 # We hit the end of the bucketlist iterator, so redo
168 DBM::Deep->_throw_error( "get_next_key(): How did we get here?" );