Sha256: 3cc1e2806b221df13188118ab7b7dcc286d99af6e9e84e7c612401503bcf3ef0

Contents?: true

Size: 1.03 KB

Versions: 2

Compression:

Stored size: 1.03 KB

Contents

# frozen_string_literal: true

module SlowEnumeratorTools
  module Merger
    def self.merge(enums)
      enum = Iterator.new(enums).tap(&:start)

      Enumerator.new do |y|
        loop { y << enum.next }
      end.lazy
    end

    class Iterator
      DONE = Object.new

      def initialize(enums)
        @enums = enums
        @q = SizedQueue.new(5)
        @done = false
      end

      def next
        raise StopIteration if @done

        nxt = @q.pop
        if DONE.equal?(nxt)
          @done = true
          raise StopIteration
        else
          nxt
        end
      end

      def start
        threads = @enums.map { |enum| spawn_empty_into(enum, @q) }

        spawn do
          threads.each(&:join)
          @q << DONE
        end
      end

      protected

      def spawn_empty_into(enum, queue)
        spawn do
          enum.each { |e| queue << e }
        end
      end

      def spawn
        Thread.new do
          Thread.current.abort_on_exception = true
          yield
        end
      end
    end
  end
end

Version data entries

2 entries across 2 versions & 1 rubygems

Version Path
slow_enumerator_tools-1.0.0 lib/slow_enumerator_tools/merger.rb
slow_enumerator_tools-1.0.0a1 lib/slow_enumerator_tools/merger.rb