deep-cover-core 0.6.4 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|