Class: PEROBS::FreeSpaceManager
- Inherits:
-
Object
- Object
- PEROBS::FreeSpaceManager
- Defined in:
- lib/perobs/FreeSpaceManager.rb
Overview
The FreeSpaceManager keeps a list of the free spaces in the FlatFile. Each space is stored with address and size. The data is persisted in the file system. Internally the free spaces are stored in different pools. Each pool holds spaces that are at least of a given size and not as big as the next pool up. Pool entry minimum sizes increase by a factor of 2 from pool to pool.
Instance Method Summary collapse
-
#add_space(address, size) ⇒ Object
Add a new space with a given address and size.
- #check(flat_file) ⇒ Object
-
#clear ⇒ Object
Clear all pools and forget any registered spaces.
-
#close ⇒ Object
Close all pool files.
-
#get_space(size) ⇒ Array
Get a space that has at least the requested size.
-
#has_space?(address, size) ⇒ Boolean
Check if there is a space in the free space lists that matches the address and the size.
-
#initialize(dir) ⇒ FreeSpaceManager
constructor
Create a new FreeSpaceManager object in the specified directory.
- #inspect ⇒ Object
-
#open ⇒ Object
Open the pool files.
Constructor Details
#initialize(dir) ⇒ FreeSpaceManager
Create a new FreeSpaceManager object in the specified directory.
43 44 45 46 |
# File 'lib/perobs/FreeSpaceManager.rb', line 43 def initialize(dir) @dir = dir @pools = [] end |
Instance Method Details
#add_space(address, size) ⇒ Object
Add a new space with a given address and size.
66 67 68 69 70 71 72 73 |
# File 'lib/perobs/FreeSpaceManager.rb', line 66 def add_space(address, size) if size <= 0 PEROBS.log.fatal "Size (#{size}) must be larger than 0." end pool_index = msb(size) new_pool(pool_index) unless @pools[pool_index] push_pool(pool_index, [ address, size ].pack('QQ')) end |
#check(flat_file) ⇒ Object
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
# File 'lib/perobs/FreeSpaceManager.rb', line 138 def check(flat_file) @pools.each do |pool| next unless pool pool.open pool.each do |entry| address, size = entry.unpack('QQ') unless flat_file.has_space?(address, size) PEROBS.log.error "FreeSpaceManager has space that isn't " + "available in the FlatFile." return false end end pool.close end true end |
#clear ⇒ Object
Clear all pools and forget any registered spaces.
100 101 102 103 104 105 106 107 108 109 |
# File 'lib/perobs/FreeSpaceManager.rb', line 100 def clear @pools.each do |pool| if pool pool.open pool.clear pool.close end end close end |
#close ⇒ Object
Close all pool files.
59 60 61 |
# File 'lib/perobs/FreeSpaceManager.rb', line 59 def close @pools = [] end |
#get_space(size) ⇒ Array
Get a space that has at least the requested size.
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/perobs/FreeSpaceManager.rb', line 78 def get_space(size) if size <= 0 PEROBS.log.fatal "Size (#{size}) must be larger than 0." end # When we search for a free space we need to search the pool that # corresponds to (size - 1) * 2. It is the pool that has the spaces that # are at least as big as size. pool_index = size == 1 ? 0 : msb(size - 1) + 1 unless @pools[pool_index] return nil else return nil unless (entry = pop_pool(pool_index)) sp_address, sp_size = entry.unpack('QQ') if sp_size < size PEROBS.log.fatal "Space at address #{sp_address} is too small. " + "Must be at least #{size} bytes but is only #{sp_size} bytes." end [ sp_address, sp_size ] end end |
#has_space?(address, size) ⇒ Boolean
Check if there is a space in the free space lists that matches the address and the size.
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'lib/perobs/FreeSpaceManager.rb', line 116 def has_space?(address, size) unless (pool = @pools[msb(size)]) return false end pool.open pool.each do |entry| sp_address, sp_size = entry.unpack('QQ') if address == sp_address if size != sp_size PEROBS.log.fatal "FreeSpaceManager has space with different " + "size" end pool.close return true end end pool.close false end |
#inspect ⇒ Object
157 158 159 160 161 162 163 164 165 166 167 168 |
# File 'lib/perobs/FreeSpaceManager.rb', line 157 def inspect '[' + @pools.map do |p| if p p.open r = p.to_ary.map { |bs| bs.unpack('QQ')}.inspect p.close r else 'nil' end end.join(', ') + ']' end |
#open ⇒ Object
Open the pool files.
49 50 51 52 53 54 55 56 |
# File 'lib/perobs/FreeSpaceManager.rb', line 49 def open Dir.glob(File.join(@dir, 'free_list_*.stack')).each do |file| basename = File.basename(file) # Cut out the pool index from the file name. index = basename[10..-7].to_i @pools[index] = StackFile.new(@dir, basename[0..-7], 2 * 8) end end |