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