kdtree 0.3 → 0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 4d1d98fec6ed9f4ce19cd558098cbe6038c9d77d
4
+ data.tar.gz: 4b2f5d14367f4210146a7dea6e0e6dbd62ba9077
5
+ SHA512:
6
+ metadata.gz: 68331f4219424518d298fa21b5aec5dd6353909a2e0fec61202894fd7b87aeb91d35761afee2b28f1edfc73547834e790b4ee414b18f40b5eab4c4b67d132c87
7
+ data.tar.gz: 506bd2057fec9dd7f9a82132e947ee37fdf2533ed70fa6c721e4643b113f884e32a8f4219ec20459b1e6a812031ff97b3cccf1b71ea93daf3a31941a87a99a1c
data/.gitignore CHANGED
@@ -1,4 +1,6 @@
1
1
  *.gem
2
+ .ruby-version
2
3
  Gemfile.lock
3
4
  lib/*.so
5
+ lib/kdtree.bundle
4
6
  tmp
@@ -1,9 +1,7 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 1.8.7
4
- - 1.9.2
5
- - 1.9.3
6
- - rbx-18mode
7
- - rbx-19mode
8
- # - ruby-head
9
- - ree
3
+ - 2.0.0
4
+ - 2.1.0
5
+ - 2.2.0
6
+ - 2.3.0
7
+ - 2.4.0
data/README.md CHANGED
@@ -1,24 +1,50 @@
1
1
  ## Kdtree
2
2
 
3
+ [![Build Status](https://travis-ci.org/gurgeous/kdtree.svg?branch=master)](https://travis-ci.org/gurgeous/kdtree)
4
+
3
5
  A kd tree is a data structure that recursively partitions the world in order to rapidly answer nearest neighbor queries. A generic kd tree can support any number of dimensions, and can return either the nearest neighbor or a set of N nearest neighbors.
4
6
 
5
7
  This gem is a blazingly fast, native, 2d kdtree. It's specifically built to find the nearest neighbor when searching millions of points. It's used in production at Urbanspoon and several other companies.
6
8
 
7
9
  The first version of this gem was released back in 2009. See the original [blog post](http://gurge.com/2009/10/22/ruby-nearest-neighbor-fast-kdtree-gem/) for the full story. Wikipedia has a great [article on kdtrees](http://en.wikipedia.org/wiki/K-d_tree).
8
10
 
11
+ Note: kdtree 0.3 obsoletes these forks: ghazel-kdtree, groupon-kdtree, tupalo-kdree. Thanks guys!
12
+
9
13
  ### Usage
10
14
 
11
- Usage is very simple:
15
+ First, install kdtree:
16
+
17
+ ```sh
18
+ $ sudo gem install kdtree
19
+ ```
20
+
21
+ It's easy to use:
12
22
 
13
- * **Kdtree.new(points)** - construct a new tree. Each point should be of the form `[x, y, id]`, where `x/y` are floats and `id` is an int. Not a string, not an object, just an int.
23
+ * **Kdtree.new(points)** - construct a new tree. Each point should be of the form `[x, y, id]`, where `x/y` are floats and `id` is an int. Not a string, not an object, **just an int**.
14
24
  * **kd.nearest(x, y)** - find the nearest point. Returns an id.
15
25
  * **kd.nearestk(x, y, k)** - find the nearest `k` points. Returns an array of ids.
16
26
 
17
- Also, I made it possible to **persist** the tree to disk and load it later. That way you can calculate the tree offline and load it quickly at some future point. Loading a persisted tree w/ 1 millions points takes less than a second, as opposed to the 3.5 second startup time shown above. For example:
27
+ For example:
28
+
29
+ ```ruby
30
+ # construct the tree
31
+ points = []
32
+ points << [47.6, -122.3, 1] # Seattle id=1
33
+ points << [45.5, -122.8, 2] # Portland id=2
34
+ points << [40.7, -74.0, 3] # New York id=3
35
+ kd = Kdtree.new(points)
36
+
37
+ # which city is closest to San Francisco?
38
+ p kd.nearest(34.1, -118.2) # => 2
39
+ # which two cities are closest to San Francisco?
40
+ p kd.nearestk(34.1, -118.2, 2) # => [2, 1]
41
+ ```
42
+
43
+ Also, I made it possible to **persist** the tree to disk and load it later. That way you can calculate the tree offline and load it quickly at some future point. Loading a persisted tree w/ 1 millions points takes half a second, as opposed to the 3.5 second build time shown below. At Urbanspoon we persist the tree and rsync it out to other machines. For example:
18
44
 
19
45
  ```ruby
20
46
  File.open("treefile", "w") { |f| kd.persist(f) }
21
- ... later ...
47
+ # ... later ...
22
48
  kd2 = File.open("treefile") { |f| Kdtree.new(f) }
23
49
  ```
24
50
 
@@ -27,16 +53,19 @@ kd2 = File.open("treefile") { |f| Kdtree.new(f) }
27
53
  Kdtree is fast. How fast? Using a tree with 1 million points on my i5 2.8ghz:
28
54
 
29
55
  ```
30
- build 3.5s
56
+ build (init) 3.52s
31
57
  nearest point 0.000003s
32
58
  nearest 5 points 0.000004s
33
59
  nearest 50 points 0.000014s
34
60
  nearest 255 points 0.000063s
61
+
62
+ persist 0.301963s
63
+ read (init) 0.432676s
35
64
  ```
36
65
 
37
66
  ### Limitations
38
67
 
39
- * No **editing** allowed! Once you construct a tree you&#8217;re stuck with it.
68
+ * No **editing** allowed! Once you construct a tree you're stuck with it.
40
69
  * The tree is stored in **one big memory block**, 20 bytes per point. A tree with one million points will allocate a single 19mb block to store its nodes.
41
70
  * Persisted trees are **architecture dependent**, and may not work across different machines due to endian issues.
42
71
  * nearestk is limited to **255 results**
@@ -52,7 +81,7 @@ Since this gem was originally released, several folks have contributed important
52
81
 
53
82
  ### Changelog
54
83
 
55
- #### 0.3 (in progress, unreleased)
84
+ #### 0.3
56
85
 
57
86
  * Ruby 1.9.x compatibility (@mcerna and others)
58
87
  * renamed KDTree to the more idiomatic Kdtree
data/Rakefile CHANGED
@@ -13,11 +13,11 @@ task :build do
13
13
  system "gem build --quiet kdtree.gemspec"
14
14
  end
15
15
 
16
- task :install => :build do
16
+ task install: :build do
17
17
  system "sudo gem install --quiet kdtree-#{spec.version}.gem"
18
18
  end
19
19
 
20
- task :release => :build do
20
+ task release: :build do
21
21
  system "git tag -a #{spec.version} -m 'Tagging #{spec.version}'"
22
22
  system "git push --tags"
23
23
  system "gem push kdtree-#{spec.version}.gem"
@@ -37,5 +37,5 @@ Rake::ExtensionTask.new("kdtree", spec)
37
37
  Rake::TestTask.new(:test) do |test|
38
38
  test.libs << "test"
39
39
  end
40
- task :test => :compile
41
- task :default => :test
40
+ task test: :compile
41
+ task default: :test
@@ -278,7 +278,7 @@ static void kdtree_nearest0(struct kdtree_data *kdtreep, int i, float x, float y
278
278
  * kd = Kdtree.new(points)
279
279
  *
280
280
  * # which two cities are closest to San Francisco?
281
- * kd.nearest(34.1, -118.2) #=> [2, 1]
281
+ * kd.nearestk(34.1, -118.2, 2) #=> [2, 1]
282
282
  */
283
283
  static VALUE kdtree_nearestk(VALUE kdtree, VALUE x, VALUE y, VALUE k)
284
284
  {
@@ -481,7 +481,7 @@ static void write_all(VALUE io, const void *buf, int len)
481
481
  * # which city is closest to San Francisco?
482
482
  * kd.nearest(34.1, -118.2) #=> 2
483
483
  * # which two cities are closest to San Francisco?
484
- * kd.nearest(34.1, -118.2) #=> [2, 1]
484
+ * kd.nearestk(34.1, -118.2, 2) #=> [2, 1]
485
485
  *
486
486
  * For more information on kd trees, see:
487
487
  *
@@ -1,10 +1,11 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "kdtree"
3
- s.version = "0.3"
3
+ s.version = "0.4"
4
4
 
5
5
  s.authors = ["Adam Doppelt"]
6
6
  s.email = ["amd@gurge.com"]
7
7
  s.homepage = "http://github.com/gurgeous/kdtree"
8
+ s.license = "MIT"
8
9
  s.summary = "Blazingly fast, native 2d kdtree."
9
10
  s.description = <<EOF
10
11
  A kdtree is a data structure that makes it possible to quickly solve
@@ -13,7 +14,8 @@ production use with millions of points.
13
14
  EOF
14
15
 
15
16
  s.rubyforge_project = "kdtree"
16
- s.add_development_dependency "rake-compiler"
17
+ s.add_development_dependency "minitest", "~> 5.0"
18
+ s.add_development_dependency "rake-compiler", "~> 1.0"
17
19
 
18
20
  s.files = `git ls-files`.split("\n")
19
21
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
@@ -1,13 +1,13 @@
1
1
  require "benchmark"
2
2
  require "kdtree"
3
3
  require "tempfile"
4
- require "test/unit"
4
+ require "minitest/autorun"
5
5
 
6
6
  #
7
7
  # create a tree
8
8
  #
9
9
 
10
- class KdtreeTest < Test::Unit::TestCase
10
+ class KdtreeTest < Minitest::Test
11
11
  TMP = "#{Dir.tmpdir}/kdtree_test"
12
12
 
13
13
  def setup
@@ -16,7 +16,7 @@ class KdtreeTest < Test::Unit::TestCase
16
16
  end
17
17
 
18
18
  def teardown
19
- File.unlink(TMP) if File.exists?(TMP)
19
+ File.unlink(TMP) if File.exist?(TMP)
20
20
  end
21
21
 
22
22
  def test_nearest
@@ -72,7 +72,7 @@ class KdtreeTest < Test::Unit::TestCase
72
72
 
73
73
  def test_bad_magic
74
74
  File.open(TMP, "w") { |f| f.puts "That ain't right" }
75
- assert_raise RuntimeError do
75
+ assert_raises RuntimeError do
76
76
  File.open(TMP, "r") { |f| Kdtree.new(f) }
77
77
  end
78
78
  end
@@ -83,7 +83,7 @@ class KdtreeTest < Test::Unit::TestCase
83
83
 
84
84
  [2, 10, 100].each do |len|
85
85
  File.open(TMP, "w") { |f| f.write(bytes[0, len]) }
86
- assert_raise EOFError do
86
+ assert_raises EOFError do
87
87
  File.open(TMP, "r") { |f| Kdtree.new(f) }
88
88
  end
89
89
  end
@@ -110,9 +110,7 @@ class KdtreeTest < Test::Unit::TestCase
110
110
 
111
111
  ks.each do |k|
112
112
  bm.report "100 queries (#{k})" do
113
- total = count = 0
114
113
  100.times do
115
- tm = Time.now
116
114
  if k == 1
117
115
  kdtree.nearest(rand_coord, rand_coord)
118
116
  else
metadata CHANGED
@@ -1,39 +1,47 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kdtree
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.3'
5
- prerelease:
4
+ version: '0.4'
6
5
  platform: ruby
7
6
  authors:
8
7
  - Adam Doppelt
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2012-10-17 00:00:00.000000000 Z
11
+ date: 2017-03-28 00:00:00.000000000 Z
13
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: minitest
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '5.0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '5.0'
14
27
  - !ruby/object:Gem::Dependency
15
28
  name: rake-compiler
16
29
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
30
  requirements:
19
- - - ! '>='
31
+ - - "~>"
20
32
  - !ruby/object:Gem::Version
21
- version: '0'
33
+ version: '1.0'
22
34
  type: :development
23
35
  prerelease: false
24
36
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
37
  requirements:
27
- - - ! '>='
38
+ - - "~>"
28
39
  - !ruby/object:Gem::Version
29
- version: '0'
30
- description: ! 'A kdtree is a data structure that makes it possible to quickly solve
31
-
40
+ version: '1.0'
41
+ description: |
42
+ A kdtree is a data structure that makes it possible to quickly solve
32
43
  the nearest neighbor problem. This is a native 2d kdtree suitable for
33
-
34
44
  production use with millions of points.
35
-
36
- '
37
45
  email:
38
46
  - amd@gurge.com
39
47
  executables: []
@@ -41,8 +49,8 @@ extensions:
41
49
  - ext/kdtree/extconf.rb
42
50
  extra_rdoc_files: []
43
51
  files:
44
- - .gitignore
45
- - .travis.yml
52
+ - ".gitignore"
53
+ - ".travis.yml"
46
54
  - Gemfile
47
55
  - LICENSE
48
56
  - README.md
@@ -53,33 +61,28 @@ files:
53
61
  - lib/kdtree.rb
54
62
  - test/test_kdtree.rb
55
63
  homepage: http://github.com/gurgeous/kdtree
56
- licenses: []
64
+ licenses:
65
+ - MIT
66
+ metadata: {}
57
67
  post_install_message:
58
68
  rdoc_options: []
59
69
  require_paths:
60
70
  - lib
61
71
  required_ruby_version: !ruby/object:Gem::Requirement
62
- none: false
63
72
  requirements:
64
- - - ! '>='
73
+ - - ">="
65
74
  - !ruby/object:Gem::Version
66
75
  version: '0'
67
- segments:
68
- - 0
69
- hash: -3094601017742930682
70
76
  required_rubygems_version: !ruby/object:Gem::Requirement
71
- none: false
72
77
  requirements:
73
- - - ! '>='
78
+ - - ">="
74
79
  - !ruby/object:Gem::Version
75
80
  version: '0'
76
- segments:
77
- - 0
78
- hash: -3094601017742930682
79
81
  requirements: []
80
82
  rubyforge_project: kdtree
81
- rubygems_version: 1.8.21
83
+ rubygems_version: 2.6.11
82
84
  signing_key:
83
- specification_version: 3
85
+ specification_version: 4
84
86
  summary: Blazingly fast, native 2d kdtree.
85
- test_files: []
87
+ test_files:
88
+ - test/test_kdtree.rb