Commit | Line | Data |
2c70efe1 |
1 | package DBM::Deep::Sector::File; |
2 | |
3 | use 5.006_000; |
4 | |
5 | use strict; |
6 | use warnings FATAL => 'all'; |
7 | |
8 | use base qw( DBM::Deep::Sector ); |
9 | |
a4d36ff6 |
10 | use DBM::Deep::Sector::File::BucketList (); |
11 | use DBM::Deep::Sector::File::Index (); |
12 | use DBM::Deep::Sector::File::Null (); |
13 | use DBM::Deep::Sector::File::Reference (); |
14 | use DBM::Deep::Sector::File::Scalar (); |
2c70efe1 |
15 | |
16 | my $STALE_SIZE = 2; |
17 | |
18 | sub base_size { |
19 | my $self = shift; |
20 | return $self->engine->SIG_SIZE + $STALE_SIZE; |
21 | } |
22 | |
23 | sub free_meth { die "free_meth must be implemented in a child class" } |
24 | |
25 | sub free { |
26 | my $self = shift; |
27 | |
28 | my $e = $self->engine; |
29 | |
30 | $e->storage->print_at( $self->offset, $e->SIG_FREE ); |
31 | # Skip staleness counter |
32 | $e->storage->print_at( $self->offset + $self->base_size, |
33 | chr(0) x ($self->size - $self->base_size), |
34 | ); |
35 | |
36 | my $free_meth = $self->free_meth; |
37 | $e->$free_meth( $self->offset, $self->size ); |
38 | |
39 | return; |
40 | } |
41 | |
42 | =head2 load( $offset ) |
43 | |
44 | This will instantiate and return the sector object that represents the data |
45 | found at $offset. |
46 | |
47 | =cut |
48 | |
49 | sub load { |
50 | my $self = shift; |
51 | my ($engine, $offset) = @_; |
52 | |
53 | # Add a catch for offset of 0 or 1 |
54 | return if !$offset || $offset <= 1; |
55 | |
56 | my $type = $engine->storage->read_at( $offset, 1 ); |
57 | return if $type eq chr(0); |
58 | |
59 | if ( $type eq $engine->SIG_ARRAY || $type eq $engine->SIG_HASH ) { |
60 | return DBM::Deep::Sector::File::Reference->new({ |
61 | engine => $engine, |
62 | type => $type, |
63 | offset => $offset, |
64 | }); |
65 | } |
66 | # XXX Don't we need key_md5 here? |
67 | elsif ( $type eq $engine->SIG_BLIST ) { |
68 | return DBM::Deep::Sector::File::BucketList->new({ |
69 | engine => $engine, |
70 | type => $type, |
71 | offset => $offset, |
72 | }); |
73 | } |
74 | elsif ( $type eq $engine->SIG_INDEX ) { |
75 | return DBM::Deep::Sector::File::Index->new({ |
76 | engine => $engine, |
77 | type => $type, |
78 | offset => $offset, |
79 | }); |
80 | } |
81 | elsif ( $type eq $engine->SIG_NULL ) { |
82 | return DBM::Deep::Sector::File::Null->new({ |
83 | engine => $engine, |
84 | type => $type, |
85 | offset => $offset, |
86 | }); |
87 | } |
88 | elsif ( $type eq $engine->SIG_DATA ) { |
89 | return DBM::Deep::Sector::File::Scalar->new({ |
90 | engine => $engine, |
91 | type => $type, |
92 | offset => $offset, |
93 | }); |
94 | } |
95 | # This was deleted from under us, so just return and let the caller figure it out. |
96 | elsif ( $type eq $engine->SIG_FREE ) { |
97 | return; |
98 | } |
99 | |
100 | DBM::Deep->_throw_error( "'$offset': Don't know what to do with type '$type'" ); |
101 | } |
102 | |
103 | 1; |
104 | __END__ |