Advertisement
Polyergic

randomfile.rb

Oct 5th, 2012
164
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Ruby 4.29 KB | None | 0 0
  1. #!/usr/bin/ruby1.9 -wKU
  2. # encoding: UTF-8
  3. #
  4. # !!! enforce line endings LF only !!!
  5. # shell may fail to correctly recognize interpreter if CR precedes or replaces LF
  6. #
  7. #---------#---------#---------#---------#---------#---------#---------#---------#---------#---------#
  8.  
  9. module RandomFile
  10.  
  11.     BUFFERDEFAULT=1024**2
  12.  
  13.     def self.min( *values )
  14.         least = values[0]
  15.         values.each do|v|
  16.             least = v if v < least
  17.         end
  18.         #puts "min(#{values.inspect}) => #{least}"
  19.         least
  20.     end
  21.  
  22.     def self.max( *values )
  23.         most = values[0]
  24.         values.each do|v|
  25.             most = v if v > most
  26.         end
  27.         #puts "max(#{values.inspect}) => #{most}"
  28.         most
  29.     end
  30.  
  31.     def self.randominteger( floor, ceiling )
  32.         (low,high)=[floor,ceiling].sort
  33.         r = low + rand(high-low+1)
  34.         #puts "random in [ #{low}, #{high} ] => #{r}"
  35.         r
  36.     end
  37.  
  38.     class Status
  39.         def initialize( size, parent=nil )
  40.             @parent = parent
  41.             @size = size.to_i
  42.             @done = 0
  43.             #puts inspect
  44.         end
  45.         def add( change )
  46.             #puts "<Status #{object_id.to_s(16)}: (#{@done}+#{change})/#{@size} = #{progress(change)} in #{@parent.inspect}>"
  47.             @done += change
  48.             @parent.add( change ) unless nil==@parent
  49.             #puts inspect
  50.         end
  51.         def progress( plus=0 )
  52.             (@done.to_f+plus)/@size
  53.         end
  54.         def percent( plus=0 )
  55.             progress(plus)*100
  56.         end
  57.         def inspect
  58.             "<Status #{object_id.to_s(16)}: #{@done}/#{@size} = #{progress}, #{percent}%, in #{@parent.inspect}>"
  59.         end
  60.     end
  61.  
  62.     def self.randomstring( count, buffer="", pstat=nil )
  63.         tobuff = count
  64.         status = Status.new( count, pstat )
  65.         #puts "randomstring( #{count} ) @ #{buffer.length}+#{tobuff} :: starting"
  66.         [[8,2**64-1,"Q"],[4,2**32-1,"L"],[2,2**16-1,"S"],[1,2**8-1,"C"]].each do |bytes,ceiling,pcode|
  67.             #puts "randomstring( #{count} ) @ #{buffer.length}+#{tobuff} :: code #{pcode} for #{bytes}-byte substrings in [0..#{ceiling}]"
  68.             while bytes <= tobuff
  69.                 b = [randominteger(0,ceiling)].pack(pcode)
  70.                 buffer << b
  71.                 tobuff -= b.length
  72.                 status.add(b.length)
  73.                 #puts "randomstring( #{count} ) @ #{buffer.length}+#{tobuff} :: added #{b.length}, #{status.inspect}"
  74.             end
  75.         end
  76.         #puts "randomstring( #{count} ) @ #{buffer.length}+#{tobuff} :: done"
  77.         buffer
  78.     end
  79.  
  80.     def self.randomoutput( count, outstream=STDOUT, buffersize=BUFFERDEFAULT, pstat=nil )
  81.         towrite = count
  82.         buffsize = min( towrite, buffersize )
  83.         buffer = ""
  84.         written = 0
  85.         status = Status.new( count, pstat )
  86.         #puts "randomoutput( #{count} ) @ #{written}+#{towrite} :: starting"
  87.         while 0 < towrite
  88.             randomstring( buffsize, buffer, status ) # fill buffer
  89.             w = outstream.write(buffer)              # write buffer
  90.             towrite -= w                             # update remaining
  91.             written += w
  92.             #puts "randomoutput( #{count} ) @ #{written}+#{towrite} :: added #{buffer.length}, #{status.inspect}"
  93.             buffsize = min( towrite, buffersize ) # shrink buffer near end
  94.             buffer.clear                          # empty without deallocating
  95.         end
  96.         #puts "randomoutput( #{count} ) @ #{buffer.length}+#{towrite} :: done"
  97.         towrite
  98.     end
  99.  
  100.     def self.randomfile( count, filename, buffersize=BUFFERDEFAULT, pstat=nil )
  101.         status = Status.new( count, pstat )
  102.         #puts "randomfile( #{count}, #{name} ) :: starting"
  103.         File.open( filename, "wb" ) do |filestream|
  104.             randomoutput( count, filestream, buffersize, status )
  105.         end
  106.         #puts "randomfile( #{count}, #{name} ) :: done"
  107.     end
  108.  
  109. end
  110.  
  111.  
  112. if $0 == __FILE__
  113.     sizes = ARGV
  114.     sizes = [RandomFile::BUFFERDEFAULT] if 0 == sizes.length
  115.     sizes.each do |s|
  116.         size = s.to_i
  117.         next if 0 == size
  118.         name = "randomfile-#{size}.noise"
  119.         status = RandomFile::Status.new( size )
  120.         #puts "generating #{size} bytes of noise in #{name}"
  121.         t = Thread.new do
  122.             pnew=0.0
  123.             dnew=0
  124.             fmt = "\r%3.0f%% %1s "
  125.             stc = ["-","\\","|","/"]
  126.             i = 0
  127.             c = stc[i]
  128.             until 100 == pnew do
  129.                 pold=pnew
  130.                 dold=dnew
  131.                 sleep 0.25
  132.                 pnew = status.percent
  133.                 if [ 0, pold ].include?( pnew )
  134.                     dnew = dold
  135.                     c = "?"
  136.                 elsif 100 == pnew
  137.                     dnew = dold
  138.                     c = " "
  139.                 else
  140.                     dnew = RandomFile::max(dold,-Math.log10(pnew-pold).floor)
  141.                     fmt = "\r%#{dnew+4}.#{dnew}f%% %1s " unless dnew == dold
  142.                     i = i+1
  143.                     i = 0 if i >= stc.length
  144.                     c = stc[i]
  145.                 end
  146.                 print fmt % [ pnew, c ]
  147.             end
  148.             puts
  149.         end
  150.         RandomFile.randomfile( size, name, 2**24-1, status )
  151.         t.join
  152.     end
  153. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement