[ create a new paste ] login | about

Link: http://codepad.org/EmAQB8Xn    [ raw code | fork ]

Ruby, pasted on Jan 17:
class SparseBitmap < DelegateClass( Hash )

    def initialize( enum=[] )
        @internal_hash={}
        @bucketsize=0.size * 8
        enum.each {|v|
            add v
        }
        super @internal_hash
    end

    def pack
        mykeys=self.keys.pack('w*')
        myvals=self.values.pack('w*')
        "#{mykeys.size},#{myvals.size}:#{mykeys},#{myvals}"
    end

    def self.unpack( str )
        header,body=str.force_encoding('ASCII-8BIT').split(':',2)
        keysize,valsize=header.split(',').map(&:to_i)
        raise ArgumentError, "Bad packed string" unless body[keysize]==','
        keystr=body[0,keysize]
        valstr=body[keysize+1,valsize]
        newkeys=keystr.unpack('w*')
        newvals=valstr.unpack('w*')
        s=self.new
        s.instance_variable_get(:@internal_hash).replace( Hash[newkeys.zip(newvals)] )
        s
    end
=begin
    def pack
        @internal_hash.to_msgpack
    end

    def self.unpack str
        s=self.new
        s.instance_variable_get(:@internal_hash).replace( MessagePack.unpack(str) )
        s
    end
=end

    def add( v )
        begin
            v=Integer( v )
        rescue
            raise ArgumentError, "#{self.class}: #{__method__}: Unable to parse #{v.inspect} as an int"
        end
        bucket=v / @bucketsize
        bit=v % @bucketsize
        # set the nth bit in the correct bucket
        @internal_hash[bucket]||=0
        @internal_hash[bucket] |= 1 << bit
    end
    alias :<< :add

    def contains?( v )
        begin
            v=Integer( v )
        rescue
            raise ArgumentError, "#{self.class}: #{__method__}: Unable to parse #{v.inspect} as an int"
        end
        bucket=v / @bucketsize
        return false unless @internal_hash[bucket]
        bit=v % @bucketsize
        @internal_hash[bucket][bit]==1
    end

    def to_a
        @internal_hash.each_with_object([]) {|keyval,ary|
            (0...@bucketsize).each {|bit_idx|
                if keyval[1][bit_idx]==1
                    ary << keyval[0]*64 + bit_idx
                end
            }
        }
    end

end


Create a new paste based on this one


Comments: