]> git.donarmstrong.com Git - biopieces.git/commitdiff
worked on each_interval, but still too slow
authormartinahansen <martinahansen@74ccb610-7750-0410-82ae-013aeee3265d>
Wed, 19 Oct 2011 15:36:01 +0000 (15:36 +0000)
committermartinahansen <martinahansen@74ccb610-7750-0410-82ae-013aeee3265d>
Wed, 19 Oct 2011 15:36:01 +0000 (15:36 +0000)
git-svn-id: http://biopieces.googlecode.com/svn/trunk@1587 74ccb610-7750-0410-82ae-013aeee3265d

code_ruby/lib/maasha/bitarray.rb

index 633c54a55777897b9b9fc4eb93583fd76ca7d415..114bc26474c7acc4019e1cd27e66b325f8d5a928 100644 (file)
@@ -58,16 +58,16 @@ class BitArray
 
   # Method to set a bit to 1 at a given position in the bit array.
   def bit_set(pos)
-    raise BitArrayError, "Position #{pos} must be an integer."              unless pos.is_a? Fixnum
-    raise BitArrayError, "Position #{pos} outside of range: 0 ... #{@size}" unless (0 ... @size ).include? pos
+    raise BitArrayError, "Position #{pos} must be an integer."                  unless pos.is_a? Fixnum
+    raise BitArrayError, "Position #{pos} outside of range: 0 ... #{@size - 1}" unless (0 ... @size ).include? pos
 
     @byte_array[byte_pos(pos)] = @byte_array[byte_pos(pos)] | bit_pos(pos)
   end
 
   # Method to set a bit to 0 at a given position in the bit array.
   def bit_unset(pos)
-    raise BitArrayError, "Position #{pos} must be an integer."              unless pos.is_a? Fixnum
-    raise BitArrayError, "Position #{pos} outside of range: 0 ... #{@size}" unless (0 ... @size ).include? pos
+    raise BitArrayError, "Position #{pos} must be an integer."                  unless pos.is_a? Fixnum
+    raise BitArrayError, "Position #{pos} outside of range: 0 ... #{@size - 1}" unless (0 ... @size ).include? pos
 
     mask = bit_pos(pos)
     mask = ~mask
@@ -77,8 +77,8 @@ class BitArray
 
   # Method to check if a bit at a given position in the bit array is set.
   def bit_set?(pos)
-    raise BitArrayError, "Position #{pos} must be an integer."              unless pos.is_a? Fixnum
-    raise BitArrayError, "Position #{pos} outside of range: 0 ... #{@size}" unless (0 ... @size ).include? pos
+    raise BitArrayError, "Position #{pos} must be an integer."                  unless pos.is_a? Fixnum
+    raise BitArrayError, "Position #{pos} outside of range: 0 ... #{@size - 1}" unless (0 ... @size ).include? pos
 
     (@byte_array[byte_pos(pos)] & bit_pos(pos)) != 0
   end
@@ -221,27 +221,64 @@ class BitArray
   # Method to locate intervals of bits set to "on" in a bit array.
   #   BitArray.each_interval -> Array
   #   BitArray.each_interval { |start, stop| } -> Fixnum
-  def each_interval
+  def each_interval_old
     intervals = []
-    start     = 0
-    stop      = 0
+    bit_start = 0
+    bit_stop  = 0
 
-    while start < self.size
-      if self.bit_set?(start)
-        stop = start
+    while bit_start < self.size
+      bit_start += 1 while bit_start < self.size and not self.bit_set?(bit_start)
+      bit_stop = bit_start
+      bit_stop  += 1 while bit_stop < self.size and self.bit_set?(bit_stop)
 
-        while stop < self.size and self.bit_set?(stop)
-          stop += 1
-        end
+      if block_given?
+        yield bit_start, bit_stop
+      else
+        intervals << [bit_start, bit_stop]
+      end
+
+      bit_start = bit_stop + 1
+    end
+
+    return intervals unless block_given?
+  end
+
+  # Method to locate intervals of bits set to "on" in a bit array.
+  #   BitArray.each_interval -> Array
+  #   BitArray.each_interval { |start, stop| } -> Fixnum
+  def each_interval
+    intervals  = []
+    byte_start = 0
+    bit_start  = 0
+
+    while bit_start < self.size
+#      puts "0 byte_start: #{byte_start}   bit_start: #{bit_start}"
+      byte_start += 1 while byte_start < self.byte_array.size and self.byte_array[byte_start] == 0
+      bit_start  += byte_start * BitsInChar
+      bit_start  += 1 while bit_start < self.size and not self.bit_set?(bit_start)
+
+#      puts "1 byte_start: #{byte_start}   bit_start: #{bit_start}"
+
+      if bit_start < self.size
+        bit_stop   = bit_start
+        byte_stop  = byte_start
+#        puts "1.5 byte_stop: #{byte_stop}   bit_stop: #{bit_stop}"
+        byte_stop += 1 while byte_stop < self.byte_array.size and self.byte_array[byte_stop] == ~0
+        bit_stop  += (byte_stop - byte_start) * BitsInChar
+#        puts "1.5 byte_stop: #{byte_stop}   bit_stop: #{bit_stop}"
+        bit_stop  += 1 while bit_stop < self.size and self.bit_set?(bit_stop)
+
+#        puts "2 byte_stop: #{byte_stop}   bit_stop: #{bit_stop}"
 
         if block_given?
-          yield start, stop
+          yield bit_start, bit_stop - 1
         else
-          intervals << [start, stop]
+          intervals << [bit_start, bit_stop - 1]
         end
-      end
 
-      stop > start ? start = stop : start += 1
+        byte_start  = byte_stop
+        bit_start   = bit_stop + 1
+      end
     end
 
     return intervals unless block_given?