Class: PDTP::RangeMap

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/pdtp/common/range_map.rb

Overview

Structure which maps non-overlapping ranges to objects

Instance Method Summary collapse

Constructor Details

#initializeRangeMap

Returns a new instance of RangeMap.



28
29
30
# File 'lib/pdtp/common/range_map.rb', line 28

def initialize
  @ranges = []
end

Instance Method Details

#[](value) ⇒ Object

Find a value in the RangeMap



66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/pdtp/common/range_map.rb', line 66

def [](value)
  return nil if empty?
  range, obj = @ranges[binary_search(value)]
  return nil if range.nil?
  
  case value
  when Integer, Float
    return nil unless range.include?(value)
  else raise ArgumentError, 'key must be a number'
  end
  
  obj
end

#[]=(range, obj) ⇒ Object

Insert a range into the RangeMap

Raises:

  • (ArgumentError)


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
# File 'lib/pdtp/common/range_map.rb', line 33

def []=(range, obj)
  range = range..range if range.is_a?(Integer) or range.is_a?(Float)
  raise ArgumentError, 'key must be a number or range' unless range.is_a?(Range)
            
  index = binary_search range.begin
  
  # Correct total overlap
  [index, index + 1].each do |i|
    while @ranges[i] and @ranges[i][0].begin >= range.begin and @ranges[i][0].end <= range.end
      @ranges.delete_at i
    end
  end
    
  # Correct overlap with leftmost member
  if @ranges[index] and @ranges[index][0].begin <= range.begin
    if range.end < @ranges[index][0].end
      @ranges[index][0] = (range.end + 1)..(@ranges[index][0].end)
    else
      @ranges[index][0] = (@ranges[index][0].begin)..(range.begin - 1)
      index += 1
    end
  end
  
  # Correct overlap with rightmost member
  if @ranges[index] and @ranges[index][0].begin <= range.end
    @ranges[index][0] = (range.end + 1)..(@ranges[index][0].end)
  end
  
  @ranges.insert(index, [range, obj])
  obj
end

#clearObject

Remove all elements from the RangeMap



106
107
108
109
# File 'lib/pdtp/common/range_map.rb', line 106

def clear
  @ranges.clear
  self
end

#each(&block) ⇒ Object

Iterate over all ranges and objects



81
82
83
# File 'lib/pdtp/common/range_map.rb', line 81

def each(&block)
  @ranges.each(&block)
end

#empty?Boolean

Is the RangeMap empty?

Returns:

  • (Boolean)


101
102
103
# File 'lib/pdtp/common/range_map.rb', line 101

def empty?
  @ranges.empty?
end

#firstObject

First range



91
92
93
# File 'lib/pdtp/common/range_map.rb', line 91

def first
  @ranges.first[0]
end

#inspectObject

Inspect the RangeMap



112
113
114
# File 'lib/pdtp/common/range_map.rb', line 112

def inspect
  "#<PDTP::RangeMap {#{@ranges.map { |r| "#{r.first}=>#{r.last.inspect}" }.join(", ")}}>"
end

#lastObject

Last range



96
97
98
# File 'lib/pdtp/common/range_map.rb', line 96

def last
  @ranges.last[0]
end

#sizeObject

Number of entries in the RangeMap



86
87
88
# File 'lib/pdtp/common/range_map.rb', line 86

def size
  @ranges.size
end