Sha256: c352cfa3bb528a39ae0c1983e4c83e0ade52b05a88b5e85114640a8d72a7b349

Contents?: true

Size: 1.68 KB

Versions: 1

Compression:

Stored size: 1.68 KB

Contents

# An accumulator buffer for Ruby objects. Use it to sequentially store a shitload
# of objects on disk and then retreive them one by one. Make sure to call clear when done
# with it to discard the stored blob.
#
# This object is intended to be used as a Tracksperanto::Import::Base#receiver, but can be used
# in general like a disk-based object buffer.
#
#  a = Tracksperanto::Accumulator.new
#  parse_big_file do | one_node |
#    a.push(one_node)
#  end
#
#  a.size #=> 30932
#  a.each do | node_read_from_disk |
#     # do something with node
#  end
#
#  a.clear # ensure that the file is deleted
class Tracksperanto::Accumulator
  include Enumerable
  
  # Returns the number of objects stored so far
  attr_reader :size
  
  def initialize
    @store = Tracksperanto::BufferIO.new
    @size = 0
    @byte_size = 0
    
    super
  end
  
  # Store an object
  def push(object_to_store)
    @store.seek(@byte_size)
    blob = marshal_object(object_to_store)
    @store.write(blob)
    @size += 1
    @byte_size = @byte_size + blob.size
    object_to_store
  end
  
  # Retreive each stored object in succession. All other Enumerable
  # methods are also available (but be careful with Enumerable#map)
  def each
    @store.rewind
    @size.times { yield(recover_object) }
  end
  
  # Calls close! on the datastore and deletes the objects in it
  def clear
    @store.close!
    @size = 0
  end
  
  private
  
  def marshal_object(object_to_store)
    d = Marshal.dump(object_to_store)
    blob = [d.size, "\t", d, "\n"].join
  end
  
  def recover_object
    # Up to the tab is the amount of bytes to read
    demarshal_bytes = @store.gets("\t").strip.to_i
    Marshal.load(@store.read(demarshal_bytes))
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
tracksperanto-2.2.0 lib/tracksperanto/accumulator.rb