Module: External::Chunkable
Overview
The Chunkable mixin provides methods for organizing a span or range into chunks no larger than a specified block size. For reference:
span an array like: [start, length]
range a Range like: start..end or start...(end - 1)
Instance Attribute Summary collapse
-
#default_blksize ⇒ Object
The default block size for chunking a chunkable object; default_blksize must be set by the object.
-
#length ⇒ Object
The length of the chunkable object; length must be set by the object.
Class Method Summary collapse
-
.range_begin_and_end(range_or_span) ⇒ Object
Returns the begining and end of a range or span.
-
.split_range(range) ⇒ Object
Converts a range into an offset and length.
-
.split_span(span) ⇒ Object
The compliment to split_range; returns the span with a negative start index counted back from self.length.
Instance Method Summary collapse
-
#chunk(range_or_span = default_span, blksize = default_blksize) {|rbegin, rend - rbegin| ... } ⇒ Object
Breaks the input range or span into chunks of blksize or less.
-
#default_span ⇒ Object
Returns the default span: [0, length].
-
#reverse_chunk(range_or_span = default_span, blksize = default_blksize) {|rbegin, rend - rbegin| ... } ⇒ Object
Breaks the input range or span into chunks of blksize or less, beginning from the end of the interval.
Instance Attribute Details
#default_blksize ⇒ Object
The default block size for chunking a chunkable object; default_blksize must be set by the object.
17 18 19 |
# File 'lib/external/chunkable.rb', line 17 def default_blksize @default_blksize end |
#length ⇒ Object
The length of the chunkable object; length must be set by the object.
13 14 15 |
# File 'lib/external/chunkable.rb', line 13 def length @length end |
Class Method Details
.range_begin_and_end(range_or_span) ⇒ Object
Returns the begining and end of a range or span.
range_begin_and_end(0..10) # => [0, 10]
range_begin_and_end(0...10) # => [0, 9]
range_begin_and_end([0, 10]) # => [0, 10]
111 112 113 114 115 116 117 |
# File 'lib/external/chunkable.rb', line 111 def range_begin_and_end(range_or_span) rbegin, rend = range_or_span.kind_of?(Range) ? split_range(range_or_span) : split_span(range_or_span) raise ArgumentError.new("negative offset specified: #{PP.singleline_pp(range_or_span,'')}") if rbegin < 0 rend += rbegin [rbegin, rend] end |
.split_range(range) ⇒ Object
Converts a range into an offset and length. Negative values are counted back from self.length
length # => 10
split_range(0..9) # => [0,10]
split_range(0...9) # => [0,9]
split_range(-1..9) # => [9,1]
split_range(0..-1) # => [0,10]
85 86 87 88 89 90 91 |
# File 'lib/external/chunkable.rb', line 85 def split_range(range) start, finish = range.begin, range.end start += length if start < 0 finish += length if finish < 0 [start, finish - start - (range.exclude_end? ? 1 : 0)] end |
.split_span(span) ⇒ Object
The compliment to split_range; returns the span with a negative start index counted back from self.length.
length # => 10
split_span([0, 10]) # => [0,10]
split_span([-1, 1]) # => [9,1]
100 101 102 103 |
# File 'lib/external/chunkable.rb', line 100 def split_span(span) span[0] += self.length if span[0] < 0 span end |
Instance Method Details
#chunk(range_or_span = default_span, blksize = default_blksize) {|rbegin, rend - rbegin| ... } ⇒ Object
Breaks the input range or span into chunks of blksize or less.
The offset and length of each chunk will be provided to the block, if given.
blksize # => 100
chunk(0..250) # => [[0,100],[100,100],[200,50]]
results = []
chunk([10,190]) {|offset, length| results << [offset, length]}
results # => [[10,100],[110,90]]
35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/external/chunkable.rb', line 35 def chunk(range_or_span=default_span, blksize=default_blksize) return collect_results(:chunk, range_or_span) unless block_given? rbegin, rend = range_begin_and_end(range_or_span) # chunk the final range to make sure that no chunks # greater than blksize are returned while rend - rbegin > blksize yield(rbegin, blksize) rbegin += blksize end yield(rbegin, rend - rbegin) if rend - rbegin > 0 end |
#default_span ⇒ Object
Returns the default span: [0, length]
20 21 22 |
# File 'lib/external/chunkable.rb', line 20 def default_span [0, length] end |
#reverse_chunk(range_or_span = default_span, blksize = default_blksize) {|rbegin, rend - rbegin| ... } ⇒ Object
Breaks the input range or span into chunks of blksize or less, beginning from the end of the interval. The offset and length of each chunk will be provided to the block, if given.
blksize # => 100
reverse_chunk(0..250) # => [[150,100],[50,100],[0,50]]
results = []
reverse_chunk([10,190]) {|offset, length| results << [offset, length]}
results # => [[100,100],[10,90]]
60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/external/chunkable.rb', line 60 def reverse_chunk(range_or_span=default_span, blksize=default_blksize) return collect_results(:reverse_chunk, range_or_span) unless block_given? rbegin, rend = range_begin_and_end(range_or_span) # chunk the final range to make sure that no chunks # greater than blksize are returned while rend - rbegin > blksize rend -= blksize yield(rend, blksize) end yield(rbegin, rend - rbegin) if rend - rbegin > 0 end |