Commit | Line | Data |
065b45be |
1 | #TODO: Convert this to a string |
2 | package DBM::Deep::Engine::Sector::Index; |
3 | |
9c7d9738 |
4 | use 5.006_000; |
065b45be |
5 | |
6 | use strict; |
7 | use warnings FATAL => 'all'; |
8 | |
9 | use DBM::Deep::Engine::Sector; |
10 | our @ISA = qw( DBM::Deep::Engine::Sector ); |
11 | |
12 | sub _init { |
13 | my $self = shift; |
14 | |
15 | my $engine = $self->engine; |
16 | |
17 | unless ( $self->offset ) { |
18 | my $leftover = $self->size - $self->base_size; |
19 | |
20 | $self->{offset} = $engine->_request_index_sector( $self->size ); |
21 | $engine->storage->print_at( $self->offset, $engine->SIG_INDEX ); # Sector type |
22 | # Skip staleness counter |
23 | $engine->storage->print_at( $self->offset + $self->base_size, |
24 | chr(0) x $leftover, # Zero-fill the rest |
25 | ); |
26 | } |
27 | |
28 | return $self; |
29 | } |
30 | |
31 | #XXX Change here |
32 | sub size { |
33 | my $self = shift; |
34 | unless ( $self->{size} ) { |
35 | my $e = $self->engine; |
36 | $self->{size} = $self->base_size + $e->byte_size * $e->hash_chars; |
37 | } |
38 | return $self->{size}; |
39 | } |
40 | |
41 | sub free_meth { return '_add_free_index_sector' } |
42 | |
43 | sub free { |
44 | my $self = shift; |
45 | my $e = $self->engine; |
46 | |
47 | for my $i ( 0 .. $e->hash_chars - 1 ) { |
48 | my $l = $self->get_entry( $i ) or next; |
49 | $e->_load_sector( $l )->free; |
50 | } |
51 | |
52 | $self->SUPER::free(); |
53 | } |
54 | |
55 | sub _loc_for { |
56 | my $self = shift; |
57 | my ($idx) = @_; |
58 | return $self->offset + $self->base_size + $idx * $self->engine->byte_size; |
59 | } |
60 | |
61 | sub get_entry { |
62 | my $self = shift; |
63 | my ($idx) = @_; |
64 | |
65 | my $e = $self->engine; |
66 | |
67 | DBM::Deep->_throw_error( "get_entry: Out of range ($idx)" ) |
68 | if $idx < 0 || $idx >= $e->hash_chars; |
69 | |
70 | return unpack( |
71 | $e->StP($e->byte_size), |
72 | $e->storage->read_at( $self->_loc_for( $idx ), $e->byte_size ), |
73 | ); |
74 | } |
75 | |
76 | sub set_entry { |
77 | my $self = shift; |
78 | my ($idx, $loc) = @_; |
79 | |
80 | my $e = $self->engine; |
81 | |
82 | DBM::Deep->_throw_error( "set_entry: Out of range ($idx)" ) |
83 | if $idx < 0 || $idx >= $e->hash_chars; |
84 | |
85 | $self->engine->storage->print_at( |
86 | $self->_loc_for( $idx ), |
87 | pack( $e->StP($e->byte_size), $loc ), |
88 | ); |
89 | } |
90 | |
91 | 1; |
92 | __END__ |