1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
|
#
# bio/util/restriction_enzyme/dense_int_array.rb - Internal data storage for Bio::RestrictionEnzyme::Range::SequenceRange
#
# Copyright:: Copyright (C) 2011
# Naohisa Goto <ng@bioruby.org>
# Tomoaki NISHIYAMA
# License:: The Ruby License
#
module Bio
require 'bio/util/restriction_enzyme' unless const_defined?(:RestrictionEnzyme)
class RestrictionEnzyme
# a class to store integer numbers, containing many contiguous
# integral numbers.
#
# Bio::RestrictionEnzyme internal use only.
# Please do not create the instance outside Bio::RestrictionEnzyme.
class DenseIntArray
MutableRange = Struct.new(:first, :last)
include Enumerable
# Same usage as Array.[]
def self.[](*args)
a = self.new
args.each do |elem|
a.push elem
end
a
end
# creates a new object
def initialize
@data = []
end
# initialize copy
def initialize_copy(other)
super(other)
@data = @data.collect { |elem| elem.dup }
end
# sets internal data object
def internal_data=(a)
#clear_cache
@data = a
self
end
protected :internal_data=
# gets internal data object
def internal_data
@data
end
protected :internal_data
# Same usage as Array#[]
def [](*arg)
#$stderr.puts "SortedIntArray#[]"
to_a[*arg]
end
# Not implemented
def []=(*arg)
raise NotImplementedError, 'DenseIntArray#[]= is not implemented.'
end
# Same usage as Array#each
def each
@data.each do |elem|
elem.first.upto(elem.last) { |num| yield num }
end
self
end
# Same usage as Array#reverse_each
def reverse_each
@data.reverse_each do |elem|
elem.last.downto(elem.first) { |num| yield num }
end
self
end
# Same usage as Array#+, but accepts only the same classes instance.
def +(other)
unless other.is_a?(self.class) then
raise TypeError, 'unsupported data type'
end
tmpdata = @data + other.internal_data
tmpdata.sort! { |a,b| a.first <=> b.first }
result = self.class.new
return result if tmpdata.empty?
newdata = result.internal_data
newdata.push tmpdata[0].dup
(1...(tmpdata.size)).each do |i|
if (x = newdata[-1].last) >= tmpdata[i].first then
newdata[-1].last = tmpdata[i].last if tmpdata[i].last > x
else
newdata.push tmpdata[i].dup
end
end
result
end
# Same usage as Array#==
def ==(other)
if r = super(other) then
r
elsif other.is_a?(self.class) then
other.internal_data == @data
else
false
end
end
# Same usage as Array#concat
def concat(ary)
ary.each { |elem| self.<<(elem) }
self
end
# Same usage as Array#push
def push(*args)
args.each do |elem|
self.<<(elem)
end
self
end
# Same usage as Array#unshift
def unshift(*arg)
raise NotImplementedError, 'DenseIntArray#unshift is not implemented.'
end
# Same usage as Array#<<
def <<(elem)
if !@data.empty? and
@data[-1].last + 1 == elem then
@data[-1].last = elem
else
@data << MutableRange.new(elem, elem)
end
self
end
# Same usage as Array#include?
def include?(elem)
return false if @data.empty? or elem < self.first or self.last < elem
@data.any? do |range|
range.first <= elem && elem <= range.last
end
end
# Same usage as Array#first
def first
elem = @data.first
elem ? elem.first : nil
end
# Same usage as Array#last
def last
elem = @data.last
elem ? elem.last : nil
end
# Same usage as Array#size
def size
sum = 0
@data.each do |range|
sum += (range.last - range.first + 1)
end
sum
end
alias length size
# Same usage as Array#delete
def delete(elem)
raise NotImplementedError, 'DenseIntArray#delete is not implemented.'
end
# Does nothing
def sort!(&block)
# does nothing
self
end
# Does nothing
def uniq!
# does nothing
self
end
end #class DenseIntArray
end #class RestrictionEnzyme
end #module Bio
|