class Huffnpuff
Constants
- CMP
- VERSION
Public Class Methods
get_system_string_from_histogram(ary, rat = 0.61)
click to toggle source
# File lib/huffnpuff.rb, line 41 def self.get_system_string_from_histogram(ary, rat = 0.61) raise "histogram array must be reverse sorted with values >= 1" unless histogram_array_valid?(ary) raise "parameter 2 must be between 0.1 and 0.9" unless ((rat >= 0.1) && (rat <= 0.9)) sys = [] top = (rat * 4096.0).to_i n = ary.count - 1 tar = (ary[0] * top) >> 12 cnt = 1 n.times do |idx| if ary[idx+1] <= tar sys.push cnt cnt = 1 tar = (ary[idx+1] * top) >> 12 else cnt += 1 end end sys.push cnt ary = [] borrow = 0 sys.each do |num| num -= borrow bin_size = 1 << (num-1).bit_length ary.push bin_size borrow = bin_size - num end pre = "" if ary.count==1 # don't bother ... all same return "x" * (ary.first.bit_length - 1) end sys = [] ary.each do |num| str = pre + "0" + "x" * (num.bit_length-1) pre += "1" sys.push str end sys.sort! &CMP sys.join(':') end
histogram_array_valid?(ary)
click to toggle source
# File lib/huffnpuff.rb, line 5 def self.histogram_array_valid?(ary) return false if ary.empty? ary.each do |elm| return false unless elm.kind_of? Integer return false if elm <= 0 end return false unless ary == ary.sort.reverse true end
new(sys, fifo, dat = [])
click to toggle source
# File lib/huffnpuff.rb, line 84 def initialize(sys, fifo, dat = []) @data = dat @fifo = fifo systemize!(sys) end
validate_system_string(str)
click to toggle source
# File lib/huffnpuff.rb, line 15 def self.validate_system_string(str) ary = str.split(':') raise "singular bin not valid" if 1==ary.count ary.each do |bin| raise "empty bin definition" if bin.empty? raise "preamble missing: must start with 1 or 0" unless (bin[0]=='0' || bin[0]=='1') xmode = false bin.each_char do |ch| if xmode raise "illegal char following 'x': [#{ch}]" unless 'x'==ch else if ch=='x' xmode = true elsif ch=='0' elsif ch=='1' else raise "invalid symbol [#{ch}]" end end end end true end
Public Instance Methods
get()
click to toggle source
ok, we have a problem … the MSB is the preamble
# File lib/huffnpuff.rb, line 159 def get idx = 0 @ary.each do |ii| pre = @fifo.get(ii.first.length) # not enough bits to address data return nil if pre.nil? if(pre==ii.first.to_i(2)) if(0==ii[1]) # only one, no x's return @data[ii[2]] else off = @fifo.get(ii[1]) if off.nil? @fifo.unget(ii[1]+ii.first.length) # not enough bits to address data return nil end return @data[off + ii[2]] end else # put back to try another system @fifo.unget(ii.first.length) end end return nil end
max()
click to toggle source
# File lib/huffnpuff.rb, line 92 def max @max end
min()
click to toggle source
# File lib/huffnpuff.rb, line 89 def min @min end
push(item)
click to toggle source
# File lib/huffnpuff.rb, line 138 def push(item) raise "can't excede system size of #{@size}" if @data.size >= @size @data.push item end
push_each(item)
click to toggle source
# File lib/huffnpuff.rb, line 143 def push_each(item) if item.respond_to? :each item.each do |elm| push elm end elsif item.respond_to? :each_char item.each_char do |ch| push ch end else # punt push item end end
size()
click to toggle source
# File lib/huffnpuff.rb, line 95 def size @size end
sys()
click to toggle source
# File lib/huffnpuff.rb, line 99 def sys() @sys end
systemize!(sys)
click to toggle source
# File lib/huffnpuff.rb, line 103 def systemize!(sys) @ary = [] if sys.kind_of? String @sys = sys ary = sys.split(':') elsif sys.kind_of? Array ary = sys @sys = ary.join(':') else raise "imcompatible type first parameter" end self.class.validate_system_string(@sys) off = 0 @min = 2 ** 10000 @max = 0 ary.each do |ii| pos = ii.index('x') if pos.nil? @ary.push [ii,0, off] off += 1 sz = ii.length @min = sz < @min ? sz : @min @max = sz > @max ? sz : @max else xcount = ii.length - pos @ary.push [ii[(0..(pos-1))],xcount,off] off += 2 ** xcount sz = xcount + ii[(0..(pos-1))].length @min = sz < @min ? sz : @min @max = sz > @max ? sz : @max end end @size = off end