Class: Omnizip::Formats::Rar::Rar5::MultiVolume::VolumeSplitter
- Inherits:
-
Object
- Object
- Omnizip::Formats::Rar::Rar5::MultiVolume::VolumeSplitter
- Defined in:
- lib/omnizip/formats/rar/rar5/multi_volume/volume_splitter.rb
Overview
Volume splitter for multi-volume archives
This class handles splitting compressed data streams across multiple volumes while respecting size boundaries and file atomicity.
Constant Summary collapse
- HEADER_OVERHEAD =
Minimum space reserved for headers (signature + main + end headers)
1024
Instance Attribute Summary collapse
-
#current_volume_bytes ⇒ Integer
readonly
Bytes written to current volume.
-
#current_volume_number ⇒ Integer
readonly
Current volume number (1-based).
-
#max_volume_size ⇒ Integer
readonly
Maximum size per volume in bytes.
-
#volumes ⇒ Array<Hash>
readonly
Volume metadata.
Class Method Summary collapse
-
.needs_splitting?(total_size, max_volume_size) ⇒ Boolean
Check if archive needs splitting.
Instance Method Summary collapse
-
#calculate_file_distribution(files) ⇒ Array<Array<Integer>>
Calculate optimal file distribution across volumes.
-
#can_fit_in_current_volume?(data_size) ⇒ Boolean
Check if data can fit in current volume.
-
#finalize_volume ⇒ Hash
Finalize current volume.
-
#initialize(max_volume_size:) ⇒ VolumeSplitter
constructor
Initialize volume splitter.
-
#remaining_space ⇒ Integer
Get remaining space in current volume.
-
#start_volume(volume_number) ⇒ void
Start a new volume.
-
#write_to_current_volume(data) ⇒ void
Write data to current volume.
Constructor Details
#initialize(max_volume_size:) ⇒ VolumeSplitter
Initialize volume splitter
40 41 42 43 44 45 46 |
# File 'lib/omnizip/formats/rar/rar5/multi_volume/volume_splitter.rb', line 40 def initialize(max_volume_size:) @max_volume_size = max_volume_size @current_volume_number = 0 @current_volume_bytes = 0 @current_volume_data = [] @volumes = [] end |
Instance Attribute Details
#current_volume_bytes ⇒ Integer (readonly)
Returns Bytes written to current volume.
29 30 31 |
# File 'lib/omnizip/formats/rar/rar5/multi_volume/volume_splitter.rb', line 29 def current_volume_bytes @current_volume_bytes end |
#current_volume_number ⇒ Integer (readonly)
Returns Current volume number (1-based).
26 27 28 |
# File 'lib/omnizip/formats/rar/rar5/multi_volume/volume_splitter.rb', line 26 def current_volume_number @current_volume_number end |
#max_volume_size ⇒ Integer (readonly)
Returns Maximum size per volume in bytes.
23 24 25 |
# File 'lib/omnizip/formats/rar/rar5/multi_volume/volume_splitter.rb', line 23 def max_volume_size @max_volume_size end |
#volumes ⇒ Array<Hash> (readonly)
Returns Volume metadata.
32 33 34 |
# File 'lib/omnizip/formats/rar/rar5/multi_volume/volume_splitter.rb', line 32 def volumes @volumes end |
Class Method Details
.needs_splitting?(total_size, max_volume_size) ⇒ Boolean
Check if archive needs splitting
147 148 149 |
# File 'lib/omnizip/formats/rar/rar5/multi_volume/volume_splitter.rb', line 147 def self.needs_splitting?(total_size, max_volume_size) total_size > max_volume_size end |
Instance Method Details
#calculate_file_distribution(files) ⇒ Array<Array<Integer>>
Calculate optimal file distribution across volumes
This method determines how to distribute files across volumes to minimize volume count while respecting atomicity.
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/omnizip/formats/rar/rar5/multi_volume/volume_splitter.rb', line 108 def calculate_file_distribution(files) distribution = [] current_volume_files = [] current_volume_used = HEADER_OVERHEAD files.each_with_index do |file, idx| file_size = file[:compressed_size] + file[:header_size] # Check if file fits in current volume if (current_volume_used + file_size) <= @max_volume_size current_volume_files << idx current_volume_used += file_size else # Start new volume distribution << current_volume_files unless current_volume_files.empty? current_volume_files = [idx] current_volume_used = HEADER_OVERHEAD + file_size # Check if single file exceeds volume size if current_volume_used > @max_volume_size # File must span multiple volumes (not implemented yet) # For now, just place it in its own volume distribution << [idx] current_volume_files = [] current_volume_used = HEADER_OVERHEAD end end end # Add final volume if not empty distribution << current_volume_files unless current_volume_files.empty? distribution end |
#can_fit_in_current_volume?(data_size) ⇒ Boolean
Check if data can fit in current volume
62 63 64 |
# File 'lib/omnizip/formats/rar/rar5/multi_volume/volume_splitter.rb', line 62 def can_fit_in_current_volume?(data_size) (@current_volume_bytes + data_size) <= @max_volume_size end |
#finalize_volume ⇒ Hash
Finalize current volume
90 91 92 93 94 95 96 97 98 99 |
# File 'lib/omnizip/formats/rar/rar5/multi_volume/volume_splitter.rb', line 90 def finalize_volume volume_info = { number: @current_volume_number, size: @current_volume_bytes, data: @current_volume_data.join, } @volumes << volume_info volume_info end |
#remaining_space ⇒ Integer
Get remaining space in current volume
69 70 71 |
# File 'lib/omnizip/formats/rar/rar5/multi_volume/volume_splitter.rb', line 69 def remaining_space @max_volume_size - @current_volume_bytes end |
#start_volume(volume_number) ⇒ void
This method returns an undefined value.
Start a new volume
52 53 54 55 56 |
# File 'lib/omnizip/formats/rar/rar5/multi_volume/volume_splitter.rb', line 52 def start_volume(volume_number) @current_volume_number = volume_number @current_volume_bytes = HEADER_OVERHEAD # Reserve space for headers @current_volume_data = [] end |
#write_to_current_volume(data) ⇒ void
This method returns an undefined value.
Write data to current volume
79 80 81 82 83 84 85 |
# File 'lib/omnizip/formats/rar/rar5/multi_volume/volume_splitter.rb', line 79 def write_to_current_volume(data) raise "No active volume" if @current_volume_number.zero? raise "Data doesn't fit in current volume" unless can_fit_in_current_volume?(data.bytesize) @current_volume_data << data @current_volume_bytes += data.bytesize end |