Commit | Line | Data |
065b45be |
1 | package DBM::Deep::Engine::Sector; |
2 | |
9c7d9738 |
3 | use 5.006_000; |
065b45be |
4 | |
5 | use strict; |
6 | use warnings FATAL => 'all'; |
7 | |
8 | use Scalar::Util (); |
9 | |
10 | sub new { |
11 | my $self = bless $_[1], $_[0]; |
12 | Scalar::Util::weaken( $self->{engine} ); |
a8d2331c |
13 | |
14 | if ( $self->offset ) { |
15 | $self->{string} = $self->engine->storage->read_at( |
16 | $self->offset, $self->size, |
17 | ); |
18 | } |
19 | else { |
20 | $self->{string} = chr(0) x $self->size; |
21 | } |
22 | |
065b45be |
23 | $self->_init; |
a8d2331c |
24 | |
065b45be |
25 | return $self; |
26 | } |
27 | |
28 | #sub _init {} |
29 | #sub clone { DBM::Deep->_throw_error( "Must be implemented in the child class" ); } |
30 | |
31 | sub engine { $_[0]{engine} } |
32 | sub offset { $_[0]{offset} } |
a8d2331c |
33 | sub type { $_[0]{type} } |
065b45be |
34 | |
35 | sub base_size { |
36 | my $self = shift; |
37 | no warnings 'once'; |
38 | return $self->engine->SIG_SIZE + $DBM::Deep::Engine::STALE_SIZE; |
39 | } |
40 | |
41 | sub free { |
42 | my $self = shift; |
43 | |
44 | my $e = $self->engine; |
45 | |
a8d2331c |
46 | $self->write( 0, $e->SIG_FREE ); |
47 | $self->write( $self->base_size, chr(0) x ($self->size - $self->base_size) ); |
48 | |
49 | $e->flush; |
50 | |
51 | # $e->storage->print_at( $self->offset, $e->SIG_FREE ); |
52 | # # Skip staleness counter |
53 | # $e->storage->print_at( $self->offset + $self->base_size, |
54 | # chr(0) x ($self->size - $self->base_size), |
55 | # ); |
56 | |
57 | #TODO When freeing two sectors, we cannot flush them right away! This means the following: |
58 | # 1) The header has to understand about unflushed items. |
59 | # 2) Loading a sector has to go through a cache to make sure we see what's already been loaded. |
60 | # 3) The header should be cached. |
065b45be |
61 | |
62 | my $free_meth = $self->free_meth; |
63 | $e->$free_meth( $self->offset, $self->size ); |
64 | |
65 | return; |
66 | } |
67 | |
a8d2331c |
68 | sub read { |
69 | my $self = shift; |
70 | my ($start, $length) = @_; |
71 | if ( $length ) { |
72 | return substr( $self->{string}, $start, $length ); |
73 | } |
74 | else { |
75 | return substr( $self->{string}, $start ); |
76 | } |
77 | } |
78 | |
79 | sub write { |
80 | my $self = shift; |
81 | my ($start, $text) = @_; |
82 | |
83 | substr( $self->{string}, $start, length($text) ) = $text; |
84 | |
85 | $self->mark_dirty; |
86 | } |
87 | |
88 | sub mark_dirty { |
89 | my $self = shift; |
90 | $self->engine->add_dirty_sector( $self ); |
91 | } |
92 | |
93 | sub flush { |
94 | my $self = shift; |
95 | $self->engine->storage->print_at( $self->offset, $self->{string} ); |
96 | } |
97 | |
065b45be |
98 | 1; |
99 | __END__ |