From: martinahansen Date: Tue, 18 Oct 2011 15:24:11 +0000 (+0000) Subject: rewrote interval_set in bitarray.rb = 20 x faster X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=22af84b1ab4d900ccdfb6985d1fec889ea1fbf0a;p=biopieces.git rewrote interval_set in bitarray.rb = 20 x faster git-svn-id: http://biopieces.googlecode.com/svn/trunk@1585 74ccb610-7750-0410-82ae-013aeee3265d --- diff --git a/code_ruby/lib/maasha/bitarray.rb b/code_ruby/lib/maasha/bitarray.rb index efaba4f..659a930 100644 --- a/code_ruby/lib/maasha/bitarray.rb +++ b/code_ruby/lib/maasha/bitarray.rb @@ -155,12 +155,26 @@ class BitArray # Method to set the bits to "on" in an interval in a bit array. # Returns the number of bits set. def interval_set(start, stop) - raise BitArrayError, "interval start < 0 (#{start} < 0)" if start < 0 + raise BitArrayError, "interval start < 0 (#{start} < 0)" if start < 0 raise BitArrayError, "interval stop > bit array size (#{stop} > #{self.size})" if stop > self.size - raise BitArrayError, "interval stop < interval start (#{stop} < #{start})" if stop < start + raise BitArrayError, "interval stop < interval start (#{stop} < #{start})" if stop < start - (start ... stop).each do |pos| - self.bit_set(pos) + mask = (2 ** BitsInChar) - 1 # 11111111 + + bits_start = start % BitsInChar + bits_stop = stop % BitsInChar + + mask_start = mask >> bits_start + mask_stop = mask << (BitsInChar - bits_stop) + + self.byte_array[start / BitsInChar] |= mask_start if (stop / BitsInChar) != (start / BitsInChar) + self.byte_array[stop / BitsInChar] |= mask_stop + + byte_start = (start + BitsInChar - bits_start) / BitsInChar + byte_stop = stop / BitsInChar + + (byte_start ... byte_stop).each do |pos| + self.byte_array[pos] |= mask end stop - start @@ -169,9 +183,9 @@ class BitArray # Method to set the bits to "off" in an interval in a bit array. # Returns the number of bits unset. def interval_unset(start, stop) - raise BitArrayError, "interval start < 0 (#{start} < 0)" if start < 0 + raise BitArrayError, "interval start < 0 (#{start} < 0)" if start < 0 raise BitArrayError, "interval stop > bit array size (#{stop} > #{self.size})" if stop > self.size - raise BitArrayError, "interval stop < interval start (#{stop} < #{start})" if stop < start + raise BitArrayError, "interval stop < interval start (#{stop} < #{start})" if stop < start (start ... stop).each do |pos| self.bit_unset(pos)