]> git.donarmstrong.com Git - biopieces.git/commitdiff
rewrote interval_set in bitarray.rb = 20 x faster
authormartinahansen <martinahansen@74ccb610-7750-0410-82ae-013aeee3265d>
Tue, 18 Oct 2011 15:24:11 +0000 (15:24 +0000)
committermartinahansen <martinahansen@74ccb610-7750-0410-82ae-013aeee3265d>
Tue, 18 Oct 2011 15:24:11 +0000 (15:24 +0000)
git-svn-id: http://biopieces.googlecode.com/svn/trunk@1585 74ccb610-7750-0410-82ae-013aeee3265d

code_ruby/lib/maasha/bitarray.rb

index efaba4fd69411cec34b56d2b5cddff47188d1151..659a9305c8cba7053dc680ddd61ab1e599ed9ff7 100644 (file)
@@ -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)