Class: CZTop::Z85::Pipe::Strategy::Parallel

Inherits:
CZTop::Z85::Pipe::Strategy show all
Defined in:
lib/cztop/z85/pipe.rb

Overview

Uses three threads:

  1. reads from source

  2. encodes/decodes

  3. writes to sink

This might give a performance increase on truly parallel platforms such as Rubinius and JRuby (and multiple CPU cores).

Instance Method Summary collapse

Constructor Details

#initializeParallel

Initializes the 2 sized queues used.



128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/cztop/z85/pipe.rb', line 128

def initialize(*)
  super
  # @source
  # |
  # V
  @source_queue = SizedQueue.new(20) # limit memory usage
  # |
  # V
  # xcode
  # |
  # V
  @sink_queue   = SizedQueue.new(20) # limit memory usage
  # |
  # V
  # @sink
end

Instance Method Details

#executeObject

Runs the algorithm.

Raises:

  • (void)


148
149
150
151
152
# File 'lib/cztop/z85/pipe.rb', line 148

def execute
  Thread.new { read }
  Thread.new { xcode }
  write
end

#readvoid (private)

This method returns an undefined value.

Reads all chunks and pushes them into the source queue. Then pushes a nil into the queue.



159
160
161
162
163
164
# File 'lib/cztop/z85/pipe.rb', line 159

def read
  while (chunk = @source.read(@read_sz))
    @source_queue << chunk
  end
  @source_queue << nil
end

#writevoid (private)

This method returns an undefined value.

Pops all chunks from the sink queue and writes them to the sink.



190
191
192
193
194
# File 'lib/cztop/z85/pipe.rb', line 190

def write
  while (chunk = @sink_queue.pop)
    @sink << chunk
  end
end

#xcodevoid (private)

This method returns an undefined value.

Pops all chunks from the source queue, encodes or decodes them, and pushes the result into the sink queue. Then pushes a nil into the queue.



171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
# File 'lib/cztop/z85/pipe.rb', line 171

def xcode
  # Encode all but the last chunk with pure Z85.
  previous_chunk = nil
  while true
    chunk = @source_queue.pop

    # call @xcode for the trailing nil-chunk as well
    @sink_queue << @xcode.call(chunk, previous_chunk)

    break if chunk.nil?

    previous_chunk = chunk
  end
  @sink_queue << nil
end