Sha256: b4aac7206185fa74945295ffa74d4709ee0489dea435830b6c981eb34bac9388
Contents?: true
Size: 1.82 KB
Versions: 1
Compression:
Stored size: 1.82 KB
Contents
require "tempfile" require 'forwardable' class IOWrapper extend Forwardable attr_reader :backing_buffer IO_METHODS = (IO.instance_methods - Object.instance_methods - Enumerable.instance_methods).map{|e| e.to_sym } def_delegators :backing_buffer, *IO_METHODS end # BufferIO is used for writing big segments of text. It works like a StringIO, but when the size # of the underlying string buffer exceeds MAX_IN_MEM_BYTES the string will be flushed to disk # and it automagically becomes a Tempfile class Tracksperanto::BufferIO < Tracksperanto::IOWrapper MAX_IN_MEM_BYTES = 5_000_000 def initialize @backing_buffer = StringIO.new end def write(s) super.tap { replace_with_tempfile_if_needed } end alias_method :<<, :write def puts(s) super.tap { replace_with_tempfile_if_needed } end def putc(c) super.tap { replace_with_tempfile_if_needed } end def close! @backing_buffer.close! if @tempfile_in @backing_buffer = nil end # Sometimes you just need to upgrade to a File forcibly (for example if you want) # to have an object with many iterators sitting on it. We also flush here. def to_file replace_with_tempfile unless @tempfile_in flush self end # Tells whether this one is on disk def file_backed? @tempfile_in end private def replace_with_tempfile sio = @backing_buffer tf = Tempfile.new("tracksperanto-xbuf") tf.set_encoding(Encoding::BINARY) if @rewindable_io.respond_to?(:set_encoding) tf.binmode tf.write(sio.string) tf.flush # Needed if we are going to reopen this file soon from another thread/loop sio.string = "" GC.start @backing_buffer = tf @tempfile_in = true end def replace_with_tempfile_if_needed replace_with_tempfile if !@tempfile_in && pos > MAX_IN_MEM_BYTES end end
Version data entries
1 entries across 1 versions & 1 rubygems
Version | Path |
---|---|
tracksperanto-4.2.0 | lib/tracksperanto/buffer_io.rb |