d_heap 0.6.1 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,8 +8,34 @@ require "mkmf"
8
8
  # $CFLAGS << " -g -ginline-points "
9
9
  # $CFLAGS << " -fno-omit-frame-pointer "
10
10
 
11
- if enable_config("debug")
12
- CONFIG["warnflags"] << " -Werror -Wpedantic "
11
+ # Use `rake compile -- --enable-debug`
12
+ debug_mode = enable_config("debug", ENV["EXTCONF_DEBUG"] == "1")
13
+
14
+ # Use `rake compile -- --enable-development`
15
+ devel_mode = enable_config("development") || debug_mode
16
+
17
+ if debug_mode
18
+ $stderr.puts "Building in debug mode." # rubocop:disable Style/StderrPuts
19
+ CONFIG["warnflags"] \
20
+ << " -ggdb" \
21
+ << " -DDEBUG"
22
+ end
23
+
24
+ if devel_mode
25
+ $stderr.puts "Building in development mode." # rubocop:disable Style/StderrPuts
26
+ CONFIG["warnflags"] \
27
+ << " -Wall " \
28
+ << " -Wpedantic" \
29
+ # There are warnings on MacOS that are annoying to debug (I don't have a Mac).
30
+ unless RbConfig::CONFIG["target_os"] =~ /darwin/
31
+ CONFIG["warnflags"] << " -Werror"
32
+ end
33
+ end
34
+
35
+ # Use `rake compile -- --enable-heapmap`
36
+ if enable_config("heapmap", true)
37
+ $stderr.puts "Building with DHeap::Map support." # rubocop:disable Style/StderrPuts
38
+ $defs.push "-DDHEAP_MAP"
13
39
  end
14
40
 
15
41
  have_func "rb_gc_mark_movable" # since ruby-2.7
@@ -17,6 +43,11 @@ have_func "rb_gc_mark_movable" # since ruby-2.7
17
43
  check_sizeof("long")
18
44
  check_sizeof("unsigned long long")
19
45
  check_sizeof("long double")
20
- have_macro("LDBL_MANT_DIG", "float.h")
46
+ check_sizeof("double")
47
+
48
+ unless have_macro("LDBL_MANT_DIG", "float.h")
49
+ raise NotImplementedError, "Missing LDBL_MANT_DIG."
50
+ end
21
51
 
52
+ create_header
22
53
  create_makefile("d_heap/d_heap")
data/images/push_n.png CHANGED
Binary file
Binary file
data/images/push_pop.png CHANGED
Binary file
data/lib/d_heap.rb CHANGED
@@ -83,7 +83,7 @@ class DHeap
83
83
  # If all pushes are popped, the default is probably best.
84
84
  # @param capacity [Integer] initial capacity of the heap.
85
85
  def initialize(d: DEFAULT_D, capacity: DEFAULT_CAPA) # rubocop:disable Naming/MethodParameterName
86
- __init_without_kw__(d, capacity)
86
+ __init_without_kw__(d, capacity, false)
87
87
  end
88
88
 
89
89
  # Consumes the heap by popping each minumum value until it is empty.
@@ -108,4 +108,28 @@ class DHeap
108
108
  nil
109
109
  end
110
110
 
111
+ if defined?(Map)
112
+
113
+ # Unlike {DHeap}, an object can only be added into a {DHeap::Map} once. Any
114
+ # subsequent addition simply rescores the already existing member. Objects
115
+ # are identified by their {#hash} value, just like with Hash.
116
+ class Map
117
+ alias score :[]
118
+ alias rescore :[]=
119
+ alias update :[]=
120
+
121
+ # Initialize a _d_-ary min-heap which can map objects to scores.
122
+ #
123
+ # @param d [Integer] Number of children for each parent node.
124
+ # Higher values generally speed up push but slow down pop.
125
+ # If all pushes are popped, the default is probably best.
126
+ # @param capacity [Integer] initial capacity of the heap.
127
+ def initialize(d: DEFAULT_D, capacity: DEFAULT_CAPA) # rubocop:disable Naming/MethodParameterName
128
+ __init_without_kw__(d, capacity, true)
129
+ end
130
+
131
+ end
132
+
133
+ end
134
+
111
135
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class DHeap
4
- VERSION = "0.6.1"
4
+ VERSION = "0.7.0"
5
5
 
6
6
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: d_heap
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.1
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - nicholas a. evans
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-01-24 00:00:00.000000000 Z
11
+ date: 2021-02-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: benchmark_driver
@@ -48,53 +48,29 @@ extensions:
48
48
  - ext/d_heap/extconf.rb
49
49
  extra_rdoc_files: []
50
50
  files:
51
+ - ".clang-format"
51
52
  - ".github/workflows/main.yml"
52
53
  - ".gitignore"
53
- - ".rspec"
54
54
  - ".rubocop.yml"
55
- - ".travis.yml"
56
55
  - ".yardopts"
57
56
  - CHANGELOG.md
58
57
  - CODE_OF_CONDUCT.md
59
- - Gemfile
60
- - Gemfile.lock
58
+ - D
61
59
  - LICENSE.txt
62
- - N
63
60
  - README.md
64
- - Rakefile
65
- - benchmarks/perf.rb
66
- - benchmarks/push_n.yml
67
- - benchmarks/push_n_pop_n.yml
68
- - benchmarks/push_pop.yml
69
- - benchmarks/stackprof.rb
70
- - bin/bench_charts
71
- - bin/bench_n
72
- - bin/benchmark-driver
73
- - bin/benchmarks
74
- - bin/console
75
- - bin/profile
76
- - bin/rake
77
- - bin/rspec
78
- - bin/rubocop
79
- - bin/setup
80
61
  - d_heap.gemspec
81
62
  - docs/benchmarks-2.txt
82
63
  - docs/benchmarks-mem.txt
83
64
  - docs/benchmarks.txt
84
65
  - docs/profile.txt
66
+ - ext/d_heap/.rubocop.yml
85
67
  - ext/d_heap/d_heap.c
86
68
  - ext/d_heap/extconf.rb
87
69
  - images/push_n.png
88
70
  - images/push_n_pop_n.png
89
71
  - images/push_pop.png
90
72
  - images/wikipedia-min-heap.png
91
- - lib/benchmark_driver/runner/ips_zero_fail.rb
92
73
  - lib/d_heap.rb
93
- - lib/d_heap/benchmarks.rb
94
- - lib/d_heap/benchmarks/benchmarker.rb
95
- - lib/d_heap/benchmarks/implementations.rb
96
- - lib/d_heap/benchmarks/profiler.rb
97
- - lib/d_heap/benchmarks/rspec_matchers.rb
98
74
  - lib/d_heap/version.rb
99
75
  homepage: https://github.com/nevans/d_heap
100
76
  licenses:
@@ -121,5 +97,5 @@ requirements: []
121
97
  rubygems_version: 3.1.4
122
98
  signing_key:
123
99
  specification_version: 4
124
- summary: A d-ary heap implementation, for priority queues
100
+ summary: very fast min-heap priority queue
125
101
  test_files: []
data/.rspec DELETED
@@ -1,3 +0,0 @@
1
- --format documentation
2
- --color
3
- --require spec_helper
data/.travis.yml DELETED
@@ -1,6 +0,0 @@
1
- ---
2
- language: ruby
3
- cache: bundler
4
- rvm:
5
- - 2.7.2
6
- before_install: gem install bundler -v 2.1.4
data/Gemfile DELETED
@@ -1,20 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- source "https://rubygems.org"
4
-
5
- # Specify your gem's dependencies in d_heap.gemspec
6
- gemspec
7
-
8
- gem "pry"
9
- gem "rake", "~> 13.0"
10
- gem "rake-compiler"
11
- gem "rspec", "~> 3.10"
12
- gem "rubocop", "~> 1.0"
13
-
14
- install_if -> { RUBY_PLATFORM !~ /darwin/ } do
15
- gem "benchmark_driver-output-gruff"
16
- end
17
-
18
- gem "perf"
19
- gem "priority_queue_cxx"
20
- gem "stackprof"
data/Gemfile.lock DELETED
@@ -1,83 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- d_heap (0.6.1)
5
-
6
- GEM
7
- remote: https://rubygems.org/
8
- specs:
9
- ast (2.4.1)
10
- benchmark_driver (0.15.16)
11
- benchmark_driver-output-gruff (0.3.1)
12
- benchmark_driver (>= 0.12.0)
13
- gruff
14
- coderay (1.1.3)
15
- diff-lcs (1.4.4)
16
- gruff (0.12.1)
17
- histogram
18
- rmagick
19
- histogram (0.2.4.1)
20
- method_source (1.0.0)
21
- parallel (1.19.2)
22
- parser (2.7.2.0)
23
- ast (~> 2.4.1)
24
- perf (0.1.2)
25
- priority_queue_cxx (0.3.4)
26
- pry (0.13.1)
27
- coderay (~> 1.1)
28
- method_source (~> 1.0)
29
- rainbow (3.0.0)
30
- rake (13.0.3)
31
- rake-compiler (1.1.1)
32
- rake
33
- regexp_parser (1.8.2)
34
- rexml (3.2.3)
35
- rmagick (4.1.2)
36
- rspec (3.10.0)
37
- rspec-core (~> 3.10.0)
38
- rspec-expectations (~> 3.10.0)
39
- rspec-mocks (~> 3.10.0)
40
- rspec-core (3.10.0)
41
- rspec-support (~> 3.10.0)
42
- rspec-expectations (3.10.0)
43
- diff-lcs (>= 1.2.0, < 2.0)
44
- rspec-support (~> 3.10.0)
45
- rspec-mocks (3.10.0)
46
- diff-lcs (>= 1.2.0, < 2.0)
47
- rspec-support (~> 3.10.0)
48
- rspec-support (3.10.0)
49
- rubocop (1.2.0)
50
- parallel (~> 1.10)
51
- parser (>= 2.7.1.5)
52
- rainbow (>= 2.2.2, < 4.0)
53
- regexp_parser (>= 1.8)
54
- rexml
55
- rubocop-ast (>= 1.0.1)
56
- ruby-progressbar (~> 1.7)
57
- unicode-display_width (>= 1.4.0, < 2.0)
58
- rubocop-ast (1.1.1)
59
- parser (>= 2.7.1.5)
60
- ruby-prof (1.4.2)
61
- ruby-progressbar (1.10.1)
62
- stackprof (0.2.16)
63
- unicode-display_width (1.7.0)
64
-
65
- PLATFORMS
66
- ruby
67
-
68
- DEPENDENCIES
69
- benchmark_driver
70
- benchmark_driver-output-gruff
71
- d_heap!
72
- perf
73
- priority_queue_cxx
74
- pry
75
- rake (~> 13.0)
76
- rake-compiler
77
- rspec (~> 3.10)
78
- rubocop (~> 1.0)
79
- ruby-prof
80
- stackprof
81
-
82
- BUNDLED WITH
83
- 2.2.3
data/Rakefile DELETED
@@ -1,20 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "bundler/gem_tasks"
4
- require "rspec/core/rake_task"
5
-
6
- RSpec::Core::RakeTask.new(:spec)
7
-
8
- require "rubocop/rake_task"
9
-
10
- RuboCop::RakeTask.new
11
-
12
- require "rake/extensiontask"
13
-
14
- task build: :compile
15
-
16
- Rake::ExtensionTask.new("d_heap") do |ext|
17
- ext.lib_dir = "lib/d_heap"
18
- end
19
-
20
- task default: %i[clobber compile spec rubocop]
data/benchmarks/perf.rb DELETED
@@ -1,29 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- require "perf"
5
-
6
- system("#{RbConfig.ruby} bin/rake compile", err: :out, exception: true)
7
- require "d_heap/benchmarks"
8
- include DHeap::Benchmarks # rubocop:disable Style/MixinUsage
9
- fill_random_vals
10
-
11
- n = ENV.fetch("BENCH_N", 5_000_000).to_i
12
- # interval = ENV.fetch("PROF_INTERVAL", 100).to_i # measured in μs
13
-
14
- i = 0
15
-
16
- q = initq RbHeap
17
- n.times { q << n }
18
- q.clear
19
-
20
- Perf.record do
21
- while i < n
22
- q << random_val
23
- i += 1
24
- end
25
- while 0 < i # rubocop:disable Style/NumericPredicate
26
- q.pop
27
- i -= 1
28
- end
29
- end
@@ -1,35 +0,0 @@
1
- ---
2
- prelude: |
3
- system("#{RbConfig.ruby} bin/rake compile", err: :out, exception: true)
4
- require "d_heap/benchmarks"
5
- include DHeap::Benchmarks
6
- fill_random_vals
7
-
8
- N = ENV.fetch("BENCH_N", 1000).to_i
9
-
10
- benchmark:
11
- - script: &script |
12
- if __bmdv_i % N == 0
13
- q.clear
14
- end
15
-
16
- q << random_val
17
- name: "push N (findmin)"
18
- prelude: "q = initq FindMin"
19
- loop_count: 24000000
20
- - script: *script
21
- name: "push N (bsearch)"
22
- prelude: "q = initq BSearch"
23
- loop_count: 2300000
24
- - script: *script
25
- name: "push N (rb_heap)"
26
- prelude: "q = initq RbHeap"
27
- loop_count: 9800000
28
- - script: *script
29
- name: "push N (c++ stl)"
30
- prelude: "q = initq CppSTL"
31
- loop_count: 18700000
32
- - script: *script
33
- name: "push N (c_dheap)"
34
- prelude: "q = initq DHeap"
35
- loop_count: 25100000
@@ -1,52 +0,0 @@
1
- ---
2
- prelude: |
3
- system("#{RbConfig.ruby} bin/rake compile", err: :out, exception: true)
4
- require "d_heap/benchmarks"
5
- include DHeap::Benchmarks
6
- fill_random_vals
7
-
8
- N = ENV.fetch("BENCH_N", 1000).to_i
9
- N2 = N * 2
10
-
11
- i = j = 0
12
-
13
- benchmark:
14
- - script: &script |
15
- if i < N
16
- q.clear if __bmdv_i == 0
17
- q << random_val
18
- i += 1
19
-
20
- elsif j < N
21
- q.pop
22
- j += 1
23
-
24
- elsif q.empty?
25
- i = 1
26
- j = 0
27
- q.clear
28
- q << random_val
29
-
30
- else
31
- raise "q not empty!"
32
- end
33
-
34
- name: "push N + pop N (findmin)"
35
- prelude: "q = initq FindMin"
36
- loop_count: 200000
37
- - script: *script
38
- name: "push N + pop N (bsearch)"
39
- prelude: "q = initq BSearch"
40
- loop_count: 4000000
41
- - script: *script
42
- name: "push N + pop N (rb_heap)"
43
- prelude: "q = initq RbHeap"
44
- loop_count: 4000000
45
- - script: *script
46
- name: "push N + pop N (c++ stl)"
47
- prelude: "q = initq CppSTL"
48
- loop_count: 16000000
49
- - script: *script
50
- name: "push N + pop N (c_dheap)"
51
- prelude: "q = initq DHeap"
52
- loop_count: 16000000