Skip to content

Commit 4aade8d

Browse files
committed
Some speed optimizations
1 parent a84e899 commit 4aade8d

File tree

4 files changed

+57
-9
lines changed

4 files changed

+57
-9
lines changed

Gemfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ source 'https://rubygems.org'
33
# Specify your gem's dependencies in segment_tree.gemspec
44
gemspec
55

6-
gem "simplecov", "~> 0.6.4"
6+
gem "simplecov", "~> 0.6.4"
7+
gem "ruby-prof"

benchmark/profile.rb

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#!/usr/bin/env ruby
2+
require "rubygems"
3+
require "bundler/setup"
4+
require "segment_tree"
5+
require 'ruby-prof'
6+
7+
# generate a tree with +n+ number of intervals
8+
def tree(n)
9+
SegmentTree.new list(n)
10+
end
11+
def list(n)
12+
(0..n).map { |num| [(num * 10)..(num + 1) * 10 - 1, num] }
13+
end
14+
15+
t = tree(10_000)
16+
n = rand(10_000)
17+
18+
RubyProf.start
19+
t.find_first(n)
20+
result = RubyProf.stop
21+
22+
# Print a flat profile to text
23+
printer = RubyProf::FlatPrinterWithLineNumbers.new(result)
24+
printer.print(STDOUT)

lib/segment_tree.rb

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,45 @@
1-
require "forwardable"
2-
1+
# == Synopsys
2+
# Segment tree is a tree data structure for storing intervals, or segments.
3+
# It allows querying which of the stored segments contain a given point.
4+
# It is, in principle, a static structure; that is, its content cannot be modified once the structure is built.
5+
#
6+
# == Example
7+
# data = [
8+
# [IPAddr.new('87.224.241.0/24').to_range, {:city => "YEKT"}],
9+
# [IPAddr.new('195.58.18.0/24').to_range, {:city => "MSK"}]
10+
# # and so on
11+
# ]
12+
# ip_tree = SegmentTree.new(data)
13+
#
14+
# client_ip = IPAddr.new("87.224.241.66")
15+
# ip_tree.find_first(client_ip).value # => {:city=>"YEKT"}
316
class SegmentTree
417
# An abstract tree node
518
class Node #:nodoc:all:
6-
extend Forwardable
7-
def_delegators :@range, :include?, :begin, :end
19+
attr_reader :begin, :end
20+
21+
def initialize(*)
22+
@begin, @end = @range.begin, @range.end
23+
end
24+
protected :initialize
25+
26+
def include?(x)
27+
@range.include?(x)
28+
end
829
end
930

1031
# An elementary intervals or nodes container
1132
class Container < Node #:nodoc:all:
1233
extend Forwardable
1334

14-
attr_reader :left, :right
35+
#attr_reader :left, :right
1536

1637
# Node constructor, accepts both +Node+ and +Segment+
1738
def initialize(left, right)
1839
@left, @right = left, right
19-
2040
@range = left.begin..(right || left).end
41+
42+
super
2143
end
2244

2345
# Find all intervals containing point +x+ within node's children. Returns array
@@ -48,14 +70,15 @@ def initialize(range, value)
4870
raise ArgumentError, 'Range expected, %s given' % range.class.name unless range.is_a?(Range)
4971

5072
@range, @value = range, value
73+
super
5174
end
5275

5376
def find(x)
5477
[find_first(x)].compact
5578
end
5679

5780
def find_first(x)
58-
include?(x) ? self : nil
81+
@range.include?(x) ? self : nil
5982
end
6083
end
6184

lib/segment_tree/version.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
class SegmentTree
2-
VERSION = "0.0.2"
2+
VERSION = "0.0.3"
33
end

0 commit comments

Comments
 (0)