deep-cover-core 0.6.4 → 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.
- checksums.yaml +4 -4
- data/deep_cover_core.gemspec +1 -0
- data/lib/deep_cover.rb +3 -20
- data/lib/deep_cover/auto_run.rb +10 -35
- data/lib/deep_cover/autoload_tracker.rb +9 -5
- data/lib/deep_cover/base.rb +85 -12
- data/lib/deep_cover/basics.rb +15 -3
- data/lib/deep_cover/config.rb +36 -2
- data/lib/deep_cover/config_setter.rb +1 -1
- data/lib/deep_cover/core_ext/exec_callbacks.rb +15 -9
- data/lib/deep_cover/core_ext/instruction_sequence_load_iseq.rb +1 -1
- data/lib/deep_cover/coverage.rb +51 -41
- data/lib/deep_cover/covered_code.rb +54 -17
- data/lib/deep_cover/custom_requirer.rb +10 -10
- data/lib/deep_cover/global_variables.rb +32 -0
- data/lib/deep_cover/load.rb +25 -9
- data/lib/deep_cover/node/base.rb +6 -6
- data/lib/deep_cover/node/begin.rb +1 -2
- data/lib/deep_cover/node/block.rb +5 -1
- data/lib/deep_cover/node/case.rb +1 -1
- data/lib/deep_cover/node/empty_body.rb +1 -5
- data/lib/deep_cover/node/if.rb +3 -4
- data/lib/deep_cover/node/loops.rb +1 -1
- data/lib/deep_cover/node/mixin/flow_accounting.rb +1 -8
- data/lib/deep_cover/node/mixin/has_child.rb +3 -12
- data/lib/deep_cover/node/mixin/has_child_handler.rb +2 -5
- data/lib/deep_cover/node/mixin/has_tracker.rb +3 -7
- data/lib/deep_cover/node/module.rb +20 -23
- data/lib/deep_cover/node/root.rb +1 -1
- data/lib/deep_cover/node/send.rb +4 -5
- data/lib/deep_cover/node/short_circuit.rb +1 -1
- data/lib/deep_cover/persistence.rb +100 -0
- data/lib/deep_cover/problem_with_diagnostic.rb +2 -2
- data/lib/deep_cover/setup/clone_mode_entry_template.rb +66 -0
- data/lib/deep_cover/setup/deep_cover_auto_run.rb +21 -0
- data/lib/deep_cover/setup/deep_cover_config.rb +19 -0
- data/lib/deep_cover/setup/deep_cover_without_config.rb +15 -0
- data/lib/deep_cover/tools.rb +0 -2
- data/lib/deep_cover/tools/after_tests.rb +33 -0
- data/lib/deep_cover/tools/looks_like_rails_project.rb +13 -0
- data/lib/deep_cover/tools/our_coverage.rb +1 -1
- data/lib/deep_cover/tools/scan_match_datas.rb +1 -1
- data/lib/deep_cover/version.rb +4 -2
- metadata +24 -7
- data/lib/deep_cover/coverage/persistence.rb +0 -84
- data/lib/deep_cover/tracker_bucket.rb +0 -50
- data/lib/deep_cover/tracker_hits_per_path.rb +0 -35
- data/lib/deep_cover/tracker_storage.rb +0 -76
- data/lib/deep_cover/tracker_storage_per_path.rb +0 -34
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# This file is called from `require 'deep-cover'`
|
4
|
+
#
|
5
|
+
# Based on the DEEP_COVER environment variable, we automatically start the
|
6
|
+
# covering. This way, users just need to require a file and the CLI will
|
7
|
+
# be able to automatically do the coverage.
|
8
|
+
|
9
|
+
if %w[exec 1 t true].include?(ENV['DEEP_COVER'])
|
10
|
+
# If we spawn more processes, then we don't want them clearing the trackers or doing reports.
|
11
|
+
# We only want them to gather.
|
12
|
+
ENV['DEEP_COVER'] = 'gather'
|
13
|
+
DeepCover.start
|
14
|
+
DeepCover.delete_trackers
|
15
|
+
require_relative '../auto_run'
|
16
|
+
DeepCover::AutoRun.run!('.').report!(**DeepCover.config)
|
17
|
+
elsif ENV['DEEP_COVER'] == 'gather'
|
18
|
+
DeepCover.start
|
19
|
+
require_relative '../auto_run'
|
20
|
+
DeepCover::AutoRun.run!('.')
|
21
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# This file is called from `require 'deep-cover'` and from the CLI, it may have changed work directory
|
4
|
+
#
|
5
|
+
# This initializes DeepCover's configuration from a configuration file
|
6
|
+
# and from an environment variable, if present.
|
7
|
+
# Then, we set the enrionment variable to the current configuration so that
|
8
|
+
# child process are running with the same options.
|
9
|
+
|
10
|
+
require './.deep_cover.rb' if File.exist?('./.deep_cover.rb')
|
11
|
+
|
12
|
+
if ENV['DEEP_COVER_OPTIONS']
|
13
|
+
DeepCover.config.load_hash_for_serialize(YAML.load(ENV['DEEP_COVER_OPTIONS']))
|
14
|
+
end
|
15
|
+
|
16
|
+
# Any sub process should use the same config as this one
|
17
|
+
# Just leaving DEEP_COVER_OPTIONS as is means only options passed to this process will propagate,
|
18
|
+
# but we want, at the very least, that every sub-process use the same cache_directory.
|
19
|
+
ENV['DEEP_COVER_OPTIONS'] = YAML.dump(DeepCover.config.to_hash_for_serialize)
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# This file is called from `require 'deep-cover'` and from the CLI
|
4
|
+
#
|
5
|
+
# This setups the DeepCover environment code-wise.
|
6
|
+
|
7
|
+
module DeepCover
|
8
|
+
require_relative '../load'
|
9
|
+
|
10
|
+
load_absolute_basics
|
11
|
+
|
12
|
+
extend Base
|
13
|
+
extend ConfigSetter
|
14
|
+
end
|
15
|
+
DeepCover::GLOBAL_BINDING = binding
|
data/lib/deep_cover/tools.rb
CHANGED
@@ -6,8 +6,6 @@ module DeepCover
|
|
6
6
|
|
7
7
|
require_relative 'tools/require_relative_dir'
|
8
8
|
extend Tools::RequireRelativeDir
|
9
|
-
require_relative 'tools/silence_warnings'
|
10
|
-
extend Tools::SilenceWarnings
|
11
9
|
require_relative_dir 'tools'
|
12
10
|
|
13
11
|
# The functions defined in the submodules of Tools can be accessed
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# This file is used by projects cloned with clone mode. As such, special care must be taken to
|
4
|
+
# be compatible with any projects.
|
5
|
+
# THERE MUST NOT BE ANY USE/REQUIRE OF DEPENDENCIES OF DeepCover HERE
|
6
|
+
# See deep-cover/core_gem/lib/deep_cover/setup/clone_mode_entry_template.rb for explanation of
|
7
|
+
# clone mode and of this top_level_module stuff.
|
8
|
+
top_level_module = Thread.current['_deep_cover_top_level_module'] || Object # rubocop:disable Lint/UselessAssignment
|
9
|
+
|
10
|
+
module top_level_module::DeepCover # rubocop:disable Naming/ClassAndModuleCamelCase
|
11
|
+
module Tools
|
12
|
+
module AfterTests
|
13
|
+
extend self
|
14
|
+
|
15
|
+
def after_tests
|
16
|
+
use_at_exit = true
|
17
|
+
if defined?(::Minitest)
|
18
|
+
use_at_exit = false
|
19
|
+
::Minitest.after_run { yield }
|
20
|
+
end
|
21
|
+
if defined?(::Rspec)
|
22
|
+
use_at_exit = false
|
23
|
+
::RSpec.configure do |config|
|
24
|
+
config.after(:suite) { yield }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
if use_at_exit
|
28
|
+
at_exit { yield }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DeepCover
|
4
|
+
module Tools::LooksLikeRailsProject
|
5
|
+
extend self
|
6
|
+
def looks_like_rails_project?(path)
|
7
|
+
path = File.expand_path(path)
|
8
|
+
%w(app config/application.rb config/environments db/migrate lib).all? do |q_path|
|
9
|
+
File.exist?("#{path}/#{q_path}")
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -5,7 +5,7 @@ module DeepCover
|
|
5
5
|
def our_coverage(source, filename, lineno, **options)
|
6
6
|
covered_code = CoveredCode.new(source: source, path: filename, lineno: lineno)
|
7
7
|
Tools.execute_sample(covered_code)
|
8
|
-
covered_code.line_coverage(options)[(lineno - 1)..-1]
|
8
|
+
covered_code.line_coverage(**options)[(lineno - 1)..-1]
|
9
9
|
end
|
10
10
|
end
|
11
11
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module DeepCover
|
4
|
-
module Tools::
|
4
|
+
module Tools::ScanMatchDatas
|
5
5
|
# Like String#scan, but return the MatchData object instead
|
6
6
|
def scan_match_datas(source, matcher)
|
7
7
|
source.to_enum(:scan, matcher).map { Regexp.last_match }
|
data/lib/deep_cover/version.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
top_level_module = Thread.current['_deep_cover_top_level_module'] || Object # rubocop:disable Lint/UselessAssignment
|
4
|
+
|
5
|
+
module top_level_module::DeepCover # rubocop:disable Naming/ClassAndModuleCamelCase
|
6
|
+
VERSION = '0.7.0'
|
5
7
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: deep-cover-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marc-André Lafortune
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date: 2018-
|
12
|
+
date: 2018-11-20 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: parser
|
@@ -53,6 +53,20 @@ dependencies:
|
|
53
53
|
- - ">="
|
54
54
|
- !ruby/object:Gem::Version
|
55
55
|
version: '0'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: term-ansicolor
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
63
|
+
type: :runtime
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
56
70
|
- !ruby/object:Gem::Dependency
|
57
71
|
name: terminal-table
|
58
72
|
requirement: !ruby/object:Gem::Requirement
|
@@ -194,10 +208,10 @@ files:
|
|
194
208
|
- lib/deep_cover/core_ext/require_overrides.rb
|
195
209
|
- lib/deep_cover/coverage.rb
|
196
210
|
- lib/deep_cover/coverage/analysis.rb
|
197
|
-
- lib/deep_cover/coverage/persistence.rb
|
198
211
|
- lib/deep_cover/covered_code.rb
|
199
212
|
- lib/deep_cover/custom_requirer.rb
|
200
213
|
- lib/deep_cover/flag_comment_associator.rb
|
214
|
+
- lib/deep_cover/global_variables.rb
|
201
215
|
- lib/deep_cover/load.rb
|
202
216
|
- lib/deep_cover/memoize.rb
|
203
217
|
- lib/deep_cover/module_override.rb
|
@@ -238,6 +252,7 @@ files:
|
|
238
252
|
- lib/deep_cover/node/splat.rb
|
239
253
|
- lib/deep_cover/node/variables.rb
|
240
254
|
- lib/deep_cover/parser_ext/range.rb
|
255
|
+
- lib/deep_cover/persistence.rb
|
241
256
|
- lib/deep_cover/problem_with_diagnostic.rb
|
242
257
|
- lib/deep_cover/reporter.rb
|
243
258
|
- lib/deep_cover/reporter/base.rb
|
@@ -261,7 +276,12 @@ files:
|
|
261
276
|
- lib/deep_cover/reporter/istanbul.rb
|
262
277
|
- lib/deep_cover/reporter/text.rb
|
263
278
|
- lib/deep_cover/reporter/tree/util.rb
|
279
|
+
- lib/deep_cover/setup/clone_mode_entry_template.rb
|
280
|
+
- lib/deep_cover/setup/deep_cover_auto_run.rb
|
281
|
+
- lib/deep_cover/setup/deep_cover_config.rb
|
282
|
+
- lib/deep_cover/setup/deep_cover_without_config.rb
|
264
283
|
- lib/deep_cover/tools.rb
|
284
|
+
- lib/deep_cover/tools/after_tests.rb
|
265
285
|
- lib/deep_cover/tools/blank.rb
|
266
286
|
- lib/deep_cover/tools/builtin_coverage.rb
|
267
287
|
- lib/deep_cover/tools/camelize.rb
|
@@ -272,6 +292,7 @@ files:
|
|
272
292
|
- lib/deep_cover/tools/format_char_cover.rb
|
273
293
|
- lib/deep_cover/tools/format_generated_code.rb
|
274
294
|
- lib/deep_cover/tools/indent_string.rb
|
295
|
+
- lib/deep_cover/tools/looks_like_rails_project.rb
|
275
296
|
- lib/deep_cover/tools/merge.rb
|
276
297
|
- lib/deep_cover/tools/number_lines.rb
|
277
298
|
- lib/deep_cover/tools/our_coverage.rb
|
@@ -283,10 +304,6 @@ files:
|
|
283
304
|
- lib/deep_cover/tools/slice.rb
|
284
305
|
- lib/deep_cover/tools/strip_heredoc.rb
|
285
306
|
- lib/deep_cover/tools/truncate_backtrace.rb
|
286
|
-
- lib/deep_cover/tracker_bucket.rb
|
287
|
-
- lib/deep_cover/tracker_hits_per_path.rb
|
288
|
-
- lib/deep_cover/tracker_storage.rb
|
289
|
-
- lib/deep_cover/tracker_storage_per_path.rb
|
290
307
|
- lib/deep_cover/version.rb
|
291
308
|
homepage: https://github.com/deep-cover/deep-cover
|
292
309
|
licenses:
|
@@ -1,84 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module DeepCover
|
4
|
-
require 'securerandom'
|
5
|
-
class Coverage
|
6
|
-
class Persistence
|
7
|
-
BASENAME = 'coverage.dc'
|
8
|
-
TRACKER_TEMPLATE = 'trackers%{unique}.dct'
|
9
|
-
|
10
|
-
attr_reader :dir_path
|
11
|
-
def initialize(dest_path, dirname)
|
12
|
-
@dir_path = Pathname(dest_path).join(dirname).expand_path
|
13
|
-
end
|
14
|
-
|
15
|
-
def load(with_trackers: true)
|
16
|
-
saved?
|
17
|
-
cov = load_coverage
|
18
|
-
cov.tracker_storage_per_path.tracker_hits_per_path = load_trackers if with_trackers
|
19
|
-
cov
|
20
|
-
end
|
21
|
-
|
22
|
-
def save(coverage)
|
23
|
-
create_if_needed
|
24
|
-
delete_trackers
|
25
|
-
save_coverage(coverage)
|
26
|
-
end
|
27
|
-
|
28
|
-
def save_trackers(tracker_hits_per_path)
|
29
|
-
saved?
|
30
|
-
basename = format(TRACKER_TEMPLATE, unique: SecureRandom.urlsafe_base64)
|
31
|
-
dir_path.join(basename).binwrite(Marshal.dump(
|
32
|
-
version: DeepCover::VERSION,
|
33
|
-
tracker_hits_per_path: tracker_hits_per_path,
|
34
|
-
))
|
35
|
-
end
|
36
|
-
|
37
|
-
def saved?
|
38
|
-
raise "Can't find folder '#{dir_path}'" unless dir_path.exist?
|
39
|
-
self
|
40
|
-
end
|
41
|
-
|
42
|
-
private
|
43
|
-
|
44
|
-
def create_if_needed
|
45
|
-
dir_path.mkpath
|
46
|
-
end
|
47
|
-
|
48
|
-
def save_coverage(coverage)
|
49
|
-
dir_path.join(BASENAME).binwrite(Marshal.dump(
|
50
|
-
version: DeepCover::VERSION,
|
51
|
-
coverage: coverage,
|
52
|
-
))
|
53
|
-
end
|
54
|
-
|
55
|
-
# rubocop:disable Security/MarshalLoad
|
56
|
-
def load_coverage
|
57
|
-
Marshal.load(dir_path.join(BASENAME).binread).tap do |version:, coverage:|
|
58
|
-
raise "dump version mismatch: #{version}, currently #{DeepCover::VERSION}" unless version == DeepCover::VERSION
|
59
|
-
return coverage
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
# returns a TrackerHitsPerPath
|
64
|
-
def load_trackers
|
65
|
-
tracker_files.map do |full_path|
|
66
|
-
Marshal.load(full_path.binread).yield_self do |version:, tracker_hits_per_path:|
|
67
|
-
raise "dump version mismatch: #{version}, currently #{DeepCover::VERSION}" unless version == DeepCover::VERSION
|
68
|
-
tracker_hits_per_path
|
69
|
-
end
|
70
|
-
end.inject(:merge!)
|
71
|
-
end
|
72
|
-
# rubocop:enable Security/MarshalLoad
|
73
|
-
|
74
|
-
def tracker_files
|
75
|
-
basename = format(TRACKER_TEMPLATE, unique: '*')
|
76
|
-
Pathname.glob(dir_path.join(basename))
|
77
|
-
end
|
78
|
-
|
79
|
-
def delete_trackers
|
80
|
-
tracker_files.each(&:delete)
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
@@ -1,50 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module DeepCover
|
4
|
-
bootstrap
|
5
|
-
|
6
|
-
require_relative 'tracker_storage'
|
7
|
-
|
8
|
-
# A holder for TrackerStorages, using some `global_name`.
|
9
|
-
class TrackerBucket
|
10
|
-
@@index = {}
|
11
|
-
|
12
|
-
def self.[](global_name)
|
13
|
-
raise ArgumentError, "'#{global_name}' is not a valid global name" unless global_name.start_with? '$'
|
14
|
-
@@index[global_name] ||= new(global_name)
|
15
|
-
end
|
16
|
-
|
17
|
-
def setup_source
|
18
|
-
"#{source} ||= {}"
|
19
|
-
end
|
20
|
-
|
21
|
-
def source
|
22
|
-
@global_name
|
23
|
-
end
|
24
|
-
|
25
|
-
class << self
|
26
|
-
alias_method :_load, :[]
|
27
|
-
private :_load, :new
|
28
|
-
end
|
29
|
-
|
30
|
-
def inspect
|
31
|
-
%{#<DeepCover::TrackerBucket "#{@global_name}">}
|
32
|
-
end
|
33
|
-
|
34
|
-
def create_storage(index = nil)
|
35
|
-
index ||= @global.size
|
36
|
-
TrackerStorage.new(bucket: self, array: @global[index] ||= [], index: index)
|
37
|
-
end
|
38
|
-
|
39
|
-
private
|
40
|
-
|
41
|
-
def initialize(global_name)
|
42
|
-
@global_name = global_name
|
43
|
-
@global = eval(setup_source) # rubocop:disable Security/Eval
|
44
|
-
end
|
45
|
-
|
46
|
-
def _dump(_level)
|
47
|
-
@global_name
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
@@ -1,35 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module DeepCover
|
4
|
-
bootstrap
|
5
|
-
|
6
|
-
# Should be seen as a hash like {path => tracker_hits, ...},
|
7
|
-
# where tracker_hits is simply an array of integers returned from
|
8
|
-
# TrackerStorage#tracker_hits.
|
9
|
-
# Make it easier to separate some concerns, as well as marshalling.
|
10
|
-
#
|
11
|
-
class TrackerHitsPerPath
|
12
|
-
extend Forwardable
|
13
|
-
def_delegators :@index, :each, :each_key, :map, :transform_values, :to_h, :to_hash
|
14
|
-
|
15
|
-
def initialize(index = {})
|
16
|
-
@index = index
|
17
|
-
end
|
18
|
-
|
19
|
-
def [](val)
|
20
|
-
@index[val] ||= []
|
21
|
-
end
|
22
|
-
|
23
|
-
def merge!(tracker_hits_per_path)
|
24
|
-
@index.merge!(tracker_hits_per_path) { |_h, actual, to_merge| merge_tracker_hits(actual, to_merge) }
|
25
|
-
self
|
26
|
-
end
|
27
|
-
|
28
|
-
private def merge_tracker_hits(hits, to_merge)
|
29
|
-
unless hits.size == to_merge.size
|
30
|
-
raise "Attempting to merge trackers of different sizes: #{hits.size} vs #{to_merge.size}"
|
31
|
-
end
|
32
|
-
hits.map!.with_index { |val, i| val + to_merge[i] }
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
@@ -1,76 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module DeepCover
|
4
|
-
bootstrap
|
5
|
-
|
6
|
-
# List of allocated trackers from a bucket.
|
7
|
-
# Should be thought of as a simple array of integers with
|
8
|
-
# a limited interface.
|
9
|
-
class TrackerBucket
|
10
|
-
class TrackerStorage
|
11
|
-
extend Forwardable
|
12
|
-
def_delegators :@array, :[], :size, :each, :map, :fetch
|
13
|
-
|
14
|
-
attr_reader :bucket
|
15
|
-
|
16
|
-
def initialize(bucket:, array:, index:)
|
17
|
-
@bucket = bucket
|
18
|
-
@array = array
|
19
|
-
@index = index
|
20
|
-
@allocated = 0
|
21
|
-
end
|
22
|
-
|
23
|
-
# Returns a range of tracker ids
|
24
|
-
def allocate_trackers(nb_needed)
|
25
|
-
prev = @allocated
|
26
|
-
@allocated += nb_needed
|
27
|
-
missing = @allocated - @array.size
|
28
|
-
@array.concat(Array.new(missing, 0)) if missing > 0
|
29
|
-
prev...@allocated
|
30
|
-
end
|
31
|
-
|
32
|
-
def setup_source
|
33
|
-
"(#{bucket.setup_source})[#{@index}]||=Array.new(#{size},0)"
|
34
|
-
end
|
35
|
-
|
36
|
-
def tracker_source(tracker_id)
|
37
|
-
"#{bucket.source}[#{@index}][#{tracker_id}]+=1"
|
38
|
-
end
|
39
|
-
|
40
|
-
def tracker_hits
|
41
|
-
@array.dup.freeze
|
42
|
-
end
|
43
|
-
|
44
|
-
def tracker_hits=(new_hits)
|
45
|
-
if new_hits.size != @array.size
|
46
|
-
warn 'Replacing tracker hits with array of different size'
|
47
|
-
end
|
48
|
-
@array.replace(new_hits)
|
49
|
-
end
|
50
|
-
|
51
|
-
private
|
52
|
-
|
53
|
-
def dump
|
54
|
-
{bucket: @bucket, index: @index, size: @array.size}
|
55
|
-
end
|
56
|
-
|
57
|
-
def _dump(_level)
|
58
|
-
Marshal.dump(dump)
|
59
|
-
end
|
60
|
-
|
61
|
-
class << self
|
62
|
-
private def load(bucket:, index:, size:)
|
63
|
-
storage = bucket.create_storage(index)
|
64
|
-
storage.allocate_trackers(size - storage.size)
|
65
|
-
storage
|
66
|
-
end
|
67
|
-
|
68
|
-
private def _load(data)
|
69
|
-
load(Marshal.load(data)) # rubocop:disable Security/MarshalLoad
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
private_constant :TrackerStorage
|
75
|
-
end
|
76
|
-
end
|