Merged with master and am ready to merge back
[dbsrgits/DBM-Deep.git] / lib / DBM / Deep / Iterator / File.pm
CommitLineData
19b913ce 1package DBM::Deep::Iterator::File;
2
3use strict;
4use warnings FATAL => 'all';
5
6use base qw( DBM::Deep::Iterator );
7
8use DBM::Deep::Iterator::File::BucketList ();
9use DBM::Deep::Iterator::File::Index ();
10
350896ee 11sub reset { $_[0]{breadcrumbs} = []; return }
12
19b913ce 13sub get_sector_iterator {
14 my $self = shift;
15 my ($loc) = @_;
16
17 my $sector = $self->{engine}->load_sector( $loc )
18 or return;
19
20 if ( $sector->isa( 'DBM::Deep::Sector::File::Index' ) ) {
350896ee 21 return DBM::Deep::Iterator::File::Index->new({
19b913ce 22 iterator => $self,
23 sector => $sector,
24 });
25 }
26 elsif ( $sector->isa( 'DBM::Deep::Sector::File::BucketList' ) ) {
350896ee 27 return DBM::Deep::Iterator::File::BucketList->new({
19b913ce 28 iterator => $self,
29 sector => $sector,
30 });
31 }
32
33 DBM::Deep->_throw_error( "get_sector_iterator(): Why did $loc make a $sector?" );
34}
35
36sub get_next_key {
37 my $self = shift;
38 my ($obj) = @_;
39
40 my $crumbs = $self->{breadcrumbs};
41 my $e = $self->{engine};
42
43 unless ( @$crumbs ) {
44 # This will be a Reference sector
45 my $sector = $e->load_sector( $self->{base_offset} )
46 # If no sector is found, this must have been deleted from under us.
47 or return;
48
49 if ( $sector->staleness != $obj->_staleness ) {
50 return;
51 }
52
53 my $loc = $sector->get_blist_loc
54 or return;
55
56 push @$crumbs, $self->get_sector_iterator( $loc );
57 }
58
59 FIND_NEXT_KEY: {
60 # We're at the end.
61 unless ( @$crumbs ) {
62 $self->reset;
63 return;
64 }
65
66 my $iterator = $crumbs->[-1];
67
68 # This level is done.
69 if ( $iterator->at_end ) {
70 pop @$crumbs;
71 redo FIND_NEXT_KEY;
72 }
73
350896ee 74 if ( $iterator->isa( 'DBM::Deep::Iterator::File::Index' ) ) {
19b913ce 75 # If we don't have any more, it will be caught at the
76 # prior check.
77 if ( my $next = $iterator->get_next_iterator ) {
78 push @$crumbs, $next;
79 }
80 redo FIND_NEXT_KEY;
81 }
82
350896ee 83 unless ( $iterator->isa( 'DBM::Deep::Iterator::File::BucketList' ) ) {
19b913ce 84 DBM::Deep->_throw_error(
85 "Should have a bucketlist iterator here - instead have $iterator"
86 );
87 }
88
89 # At this point, we have a BucketList iterator
90 my $key = $iterator->get_next_key;
91 if ( defined $key ) {
92 return $key;
93 }
94 #XXX else { $iterator->set_to_end() } ?
95
96 # We hit the end of the bucketlist iterator, so redo
97 redo FIND_NEXT_KEY;
98 }
99
100 DBM::Deep->_throw_error( "get_next_key(): How did we get here?" );
101}
102
1031;
104__END__