ddmemoize 1.0.0a3 → 1.0.0rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +5 -0
- data/NEWS.md +6 -0
- data/README.md +5 -5
- data/ddmemoize.gemspec +1 -1
- data/lib/ddmemoize.rb +19 -15
- data/lib/ddmemoize/version.rb +1 -1
- data/samples/fib.rb +2 -2
- data/scripts/release +41 -23
- data/spec/ddmemoize_spec.rb +13 -13
- data/spec/spec_helper.rb +1 -1
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9547603b886803ad9fa2067849ae488e7ac6279d728d5951104b0e59090201ee
|
4
|
+
data.tar.gz: 9bfd235ca2a6ec06517ba1f92de0fbc15ec10f48cf2818b8a32b0a649c92a0d5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b0572237f3ee8bf2b46f1c6332034046c39c808e3a1d5f6731a4524e52572f4d42dcfab7d471ff4f533eeb3ec504c46243076ccd5578634092828cbf70e93816
|
7
|
+
data.tar.gz: b2401d5d3748383301346edd247aa3702a7ead1ac67bbf2085ed71d9f4de54f85dc7ff3ee60659d15b82655b955039b77e372da768bd5a0714bf343dfbd893d1
|
data/.travis.yml
CHANGED
data/NEWS.md
CHANGED
data/README.md
CHANGED
@@ -30,7 +30,7 @@ Features:
|
|
30
30
|
|
31
31
|
* Supports memoizing functions on frozen objects
|
32
32
|
* Releases memoized values when needed in order to reduce memory pressure
|
33
|
-
* Optionally records
|
33
|
+
* Optionally records metrics
|
34
34
|
|
35
35
|
## Installation
|
36
36
|
|
@@ -81,14 +81,14 @@ Alternatively, prepend `memoized` to the function definition:
|
|
81
81
|
|
82
82
|
Do not memoize functions that depend on mutable state.
|
83
83
|
|
84
|
-
###
|
84
|
+
### Metrics
|
85
85
|
|
86
|
-
To activate
|
86
|
+
To activate metrics, call `DDMemoize.enable_metrics` after requiring `ddmemoize`.
|
87
87
|
|
88
|
-
To print the collected metrics, call `DDMemoize.
|
88
|
+
To print the collected metrics, call `DDMemoize.print_metrics`:
|
89
89
|
|
90
90
|
```ruby
|
91
|
-
DDMemoize.
|
91
|
+
DDMemoize.print_metrics
|
92
92
|
```
|
93
93
|
|
94
94
|
```
|
data/ddmemoize.gemspec
CHANGED
@@ -14,7 +14,7 @@ Gem::Specification.new do |spec|
|
|
14
14
|
|
15
15
|
spec.required_ruby_version = '>= 2.3.0'
|
16
16
|
|
17
|
-
spec.add_runtime_dependency('
|
17
|
+
spec.add_runtime_dependency('ddmetrics', '= 1.0.0rc1') # TODO: upgrade
|
18
18
|
spec.add_runtime_dependency('ref', '~> 2.0')
|
19
19
|
|
20
20
|
spec.files = `git ls-files -z`.split("\x0")
|
data/lib/ddmemoize.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'ref'
|
4
|
-
require '
|
4
|
+
require 'ddmetrics'
|
5
5
|
require 'singleton'
|
6
6
|
|
7
7
|
require_relative 'ddmemoize/version'
|
@@ -22,24 +22,28 @@ module DDMemoize
|
|
22
22
|
end
|
23
23
|
|
24
24
|
class << self
|
25
|
-
def
|
26
|
-
@
|
25
|
+
def enable_metrics
|
26
|
+
@metrics_enabled = true
|
27
27
|
end
|
28
28
|
|
29
|
-
def
|
30
|
-
@
|
29
|
+
def metrics_enabled?
|
30
|
+
@metrics_enabled
|
31
31
|
end
|
32
32
|
|
33
|
-
def
|
34
|
-
@
|
33
|
+
def metrics_counter
|
34
|
+
@_metrics_counter ||= DDMetrics::Counter.new
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
|
-
def self.
|
38
|
+
def self.print_metrics
|
39
39
|
headers = %w[memoization hit miss %]
|
40
40
|
|
41
|
-
rows_raw = DDMemoize.
|
42
|
-
{
|
41
|
+
rows_raw = DDMemoize.metrics_counter.map do |label, count|
|
42
|
+
{
|
43
|
+
name: label.fetch(:method),
|
44
|
+
type: label.fetch(:type),
|
45
|
+
count: count,
|
46
|
+
}
|
43
47
|
end
|
44
48
|
|
45
49
|
rows = rows_raw.group_by { |r| r[:name] }.map do |name, rows_for_name|
|
@@ -53,7 +57,7 @@ module DDMemoize
|
|
53
57
|
end
|
54
58
|
|
55
59
|
all_rows = [headers] + rows
|
56
|
-
puts
|
60
|
+
puts DDMetrics::Table.new(all_rows).to_s
|
57
61
|
end
|
58
62
|
|
59
63
|
module Mixin
|
@@ -62,7 +66,7 @@ module DDMemoize
|
|
62
66
|
alias_method original_method_name, method_name
|
63
67
|
|
64
68
|
instance_cache = Hash.new { |hash, key| hash[key] = {} }
|
65
|
-
|
69
|
+
full_method_name = "#{self}##{method_name}"
|
66
70
|
|
67
71
|
define_method(method_name) do |*args|
|
68
72
|
instance_method_cache = instance_cache[self]
|
@@ -73,11 +77,11 @@ module DDMemoize
|
|
73
77
|
value = object ? object.value : NONE
|
74
78
|
end
|
75
79
|
|
76
|
-
if DDMemoize.
|
80
|
+
if DDMemoize.metrics_enabled?
|
77
81
|
if NONE.equal?(value)
|
78
|
-
DDMemoize.
|
82
|
+
DDMemoize.metrics_counter.increment(method: full_method_name, type: :miss)
|
79
83
|
else
|
80
|
-
DDMemoize.
|
84
|
+
DDMemoize.metrics_counter.increment(method: full_method_name, type: :hit)
|
81
85
|
end
|
82
86
|
end
|
83
87
|
|
data/lib/ddmemoize/version.rb
CHANGED
data/samples/fib.rb
CHANGED
data/scripts/release
CHANGED
@@ -2,38 +2,28 @@
|
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
require 'fileutils'
|
5
|
+
require 'json'
|
6
|
+
require 'netrc'
|
5
7
|
require 'octokit'
|
8
|
+
require 'shellwords'
|
9
|
+
require 'uri'
|
6
10
|
|
7
11
|
def run(*args)
|
8
|
-
puts '
|
9
|
-
puts ' ' + args.map { |a| a =~ /\s/ ? a.inspect : a }.join(' ')
|
10
|
-
print 'Is this correct? [y/N] '
|
11
|
-
res = gets
|
12
|
-
unless res.strip.casecmp('y').zero?
|
13
|
-
warn 'Answer was not Y; release aborted.'
|
14
|
-
exit 1
|
15
|
-
end
|
16
|
-
|
17
|
-
system('echo', *args)
|
12
|
+
puts('<exec> ' + args.map { |s| Shellwords.escape(s) }.join(' '))
|
18
13
|
system(*args)
|
19
|
-
|
20
|
-
print 'Continue? [y/N] '
|
21
|
-
res = gets
|
22
|
-
unless res.strip.casecmp('y').zero?
|
23
|
-
warn 'Answer was not Y; release aborted.'
|
24
|
-
exit 1
|
25
|
-
end
|
26
|
-
|
27
|
-
true
|
28
14
|
end
|
29
15
|
|
16
|
+
gem_name = 'ddmemoize'
|
17
|
+
version_constant = 'DDMemoize::VERSION'
|
18
|
+
gem_path = 'ddmemoize'
|
19
|
+
|
30
20
|
puts '=== Logging in to GitHub’s API…'
|
31
21
|
client = Octokit::Client.new(netrc: true)
|
32
22
|
puts
|
33
23
|
|
34
24
|
puts '=== Deleting old *.gem files…'
|
35
25
|
Dir['*.gem'].each do |fn|
|
36
|
-
puts "
|
26
|
+
puts "deleting #{fn}…"
|
37
27
|
FileUtils.rm_f(fn)
|
38
28
|
end
|
39
29
|
puts
|
@@ -45,13 +35,41 @@ unless File.readlines('NEWS.md').drop(2).first =~ / \(\d{4}-\d{2}-\d{2}\)$/
|
|
45
35
|
end
|
46
36
|
puts
|
47
37
|
|
38
|
+
puts '=== Reading version…'
|
39
|
+
require "./lib/#{gem_path}/version"
|
40
|
+
version = eval(version_constant) # rubocop:disable Security/Eval
|
41
|
+
puts "Version = #{version}"
|
42
|
+
puts
|
43
|
+
|
48
44
|
puts '=== Building new gem…'
|
49
45
|
run('gem', 'build', 'ddmemoize.gemspec')
|
50
46
|
puts
|
51
47
|
|
52
|
-
puts '===
|
53
|
-
|
54
|
-
|
48
|
+
puts '=== Verifying that gems were built properly…'
|
49
|
+
gem_filename = "#{gem_name}-#{version}.gem"
|
50
|
+
unless File.file?(gem_filename)
|
51
|
+
warn "Error: Could not find gem: #{gem_filename}"
|
52
|
+
exit 1
|
53
|
+
end
|
54
|
+
puts
|
55
|
+
|
56
|
+
puts '=== Verifying that gem version does not yet exist…'
|
57
|
+
url = URI.parse("https://rubygems.org/api/v1/versions/#{gem_name}.json")
|
58
|
+
response = Net::HTTP.get_response(url)
|
59
|
+
existing_versions =
|
60
|
+
case response.code
|
61
|
+
when '404'
|
62
|
+
[]
|
63
|
+
when '200'
|
64
|
+
JSON.parse(response.body).map { |e| e.fetch('number') }
|
65
|
+
else
|
66
|
+
warn "Error: Couldn’t fetch version information for #{gem_name} (status #{response.code})"
|
67
|
+
exit 1
|
68
|
+
end
|
69
|
+
if existing_versions.include?(version)
|
70
|
+
warn "Error: #{gem_name} v#{version} already exists"
|
71
|
+
exit 1
|
72
|
+
end
|
55
73
|
puts
|
56
74
|
|
57
75
|
puts '=== Verifying that release does not yet exist…'
|
data/spec/ddmemoize_spec.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
DDMemoize.
|
3
|
+
DDMemoize.enable_metrics
|
4
4
|
|
5
5
|
describe DDMemoize do
|
6
6
|
it 'has a version number' do
|
@@ -79,7 +79,7 @@ describe DDMemoize do
|
|
79
79
|
record memoized def run; end
|
80
80
|
end
|
81
81
|
|
82
|
-
class
|
82
|
+
class MemoizationSpecWithMetrics
|
83
83
|
DDMemoize.activate(self)
|
84
84
|
|
85
85
|
def run(value)
|
@@ -115,10 +115,10 @@ describe DDMemoize do
|
|
115
115
|
sample.run
|
116
116
|
sample.run
|
117
117
|
|
118
|
-
counter = DDMemoize.
|
118
|
+
counter = DDMemoize.metrics_counter
|
119
119
|
|
120
|
-
expect(counter.get(
|
121
|
-
expect(counter.get(
|
120
|
+
expect(counter.get(method: 'MemoizationSpecEqual#run', type: :miss)).to eq(1)
|
121
|
+
expect(counter.get(method: 'MemoizationSpecEqual#run', type: :hit)).to eq(2)
|
122
122
|
end
|
123
123
|
|
124
124
|
it 'supports memoized def … syntax' do
|
@@ -142,26 +142,26 @@ describe DDMemoize do
|
|
142
142
|
expect(MemoizationSpecInlineSyntaxReturn.sym).to eq(:run)
|
143
143
|
end
|
144
144
|
|
145
|
-
it 'records
|
146
|
-
sample =
|
145
|
+
it 'records metrics' do
|
146
|
+
sample = MemoizationSpecWithMetrics.new
|
147
147
|
|
148
148
|
sample.run('denis')
|
149
149
|
sample.run('denis')
|
150
150
|
sample.run('defreyne')
|
151
151
|
|
152
|
-
counter = DDMemoize.
|
152
|
+
counter = DDMemoize.metrics_counter
|
153
153
|
|
154
|
-
expect(counter.get(
|
155
|
-
expect(counter.get(
|
154
|
+
expect(counter.get(method: 'MemoizationSpecWithMetrics#run', type: :miss)).to eq(2)
|
155
|
+
expect(counter.get(method: 'MemoizationSpecWithMetrics#run', type: :hit)).to eq(1)
|
156
156
|
end
|
157
157
|
|
158
|
-
it 'prints recorded
|
159
|
-
sample =
|
158
|
+
it 'prints recorded metrics' do
|
159
|
+
sample = MemoizationSpecWithMetrics.new
|
160
160
|
|
161
161
|
sample.run('denis')
|
162
162
|
sample.run('denis')
|
163
163
|
sample.run('defreyne')
|
164
164
|
|
165
|
-
expect { DDMemoize.
|
165
|
+
expect { DDMemoize.print_metrics }.to output(/memoization │ hit\s+miss\s+%/).to_stdout
|
166
166
|
end
|
167
167
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ddmemoize
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.0rc1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Denis Defreyne
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-01-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: ddmetrics
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 1.0.
|
19
|
+
version: 1.0.0rc1
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 1.0.
|
26
|
+
version: 1.0.0rc1
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: ref
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -82,7 +82,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
82
82
|
version: 1.3.1
|
83
83
|
requirements: []
|
84
84
|
rubyforge_project:
|
85
|
-
rubygems_version: 2.7.
|
85
|
+
rubygems_version: 2.7.4
|
86
86
|
signing_key:
|
87
87
|
specification_version: 4
|
88
88
|
summary: Adds support for memoizing functions
|