Class: SegmentTree
- Inherits:
-
Object
- Object
- SegmentTree
- Defined in:
- lib/segment_tree.rb,
lib/segment_tree/version.rb
Overview
Synopsys
Segment tree is a tree data structure for storing intervals, or segments. It allows querying which of the stored segments contain a given point. It is, in principle, a static structure; that is, its content cannot be modified once the structure is built.
Example
data = [
[IPAddr.new('87.224.241.0/24').to_range, {:city => "YEKT"}],
[IPAddr.new('195.58.18.0/24').to_range, {:city => "MSK"}]
# and so on
]
ip_tree = SegmentTree.new(data)
client_ip = IPAddr.new("87.224.241.66")
ip_tree.find(client_ip).value # => {:city=>"YEKT"}
Defined Under Namespace
Classes: Segment
Constant Summary collapse
- VERSION =
'0.1.1'
Instance Method Summary collapse
-
#find(x) ⇒ Segment|NilClass
Find first interval containing point
x. -
#initialize(data, sorted = false) ⇒ SegmentTree
constructor
Build a segment tree from
data. - #inspect ⇒ Object
Constructor Details
#initialize(data, sorted = false) ⇒ SegmentTree
Build a segment tree from data.
Data can be one of the following:
-
Hash - a hash, where ranges are keys, i.e. <code>=> some_value1, (4..6) => some_value2, …<code>
-
2-dimensional array - an array of arrays where first element of each element is range, and second is value: <code>[[(0..3), some_value1], [(4..6), some_value2] …]<code>
You can pass optional argument sorted. If sorted is true then tree consider that data already sorted in proper order. Use it at your own risk!
48 49 50 51 52 53 54 55 56 57 |
# File 'lib/segment_tree.rb', line 48 def initialize(data, sorted = false) # build elementary segments @segments = case data when Hash, Array, Enumerable then data.collect { |range, value| Segment.new(range, value) } else raise ArgumentError, '2-dim Array or Hash expected' end @segments.sort! unless sorted end |
Instance Method Details
#find(x) ⇒ Segment|NilClass
Find first interval containing point x.
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/segment_tree.rb', line 61 def find(x) return nil if x.nil? low = 0 high = @segments.size - 1 while low <= high mid = (low + high) / 2 case matches?(x, low, high, mid) when -1 then high = mid - 1 when 1 then low = mid + 1 when 0 then return @segments[mid] else return nil end end nil end |
#inspect ⇒ Object
78 79 80 81 82 83 84 |
# File 'lib/segment_tree.rb', line 78 def inspect if @segments.size > 0 "SegmentTree(#{@segments.first.range.begin}..#{@segments.last.range.end})" else "SegmentTree(empty)" end end |