omnizip 0.3.52 → 0.3.53

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.
@@ -1,84 +1,111 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "lutaml/model"
4
+
3
5
  module Omnizip
4
6
  module Models
5
- # Model for format conversion results
6
- class ConversionResult
7
- attr_reader :source_path, :target_path, :source_format, :target_format,
8
- :source_size, :target_size, :duration, :entry_count,
9
- :compression_ratio, :warnings
10
-
11
- # Initialize conversion result
12
- # @param source_path [String] Source file path
13
- # @param target_path [String] Target file path
14
- # @param source_format [Symbol] Source format
15
- # @param target_format [Symbol] Target format
16
- # @param source_size [Integer] Source file size in bytes
17
- # @param target_size [Integer] Target file size in bytes
18
- # @param duration [Float] Conversion duration in seconds
19
- # @param entry_count [Integer] Number of entries converted
20
- # @param warnings [Array<String>] Conversion warnings
21
- def initialize(
22
- source_path:,
23
- target_path:,
24
- source_format:,
25
- target_format:,
26
- source_size:,
27
- target_size:,
28
- duration:,
29
- entry_count:,
30
- warnings: []
31
- )
32
- @source_path = source_path
33
- @target_path = target_path
34
- @source_format = source_format
35
- @target_format = target_format
36
- @source_size = source_size
37
- @target_size = target_size
38
- @duration = duration
39
- @entry_count = entry_count
40
- @warnings = warnings
41
- @compression_ratio = calculate_compression_ratio
7
+ # Model for format conversion results.
8
+ #
9
+ # Serialized via lutaml-model — no hand-rolled +to_h+ / +to_json+.
10
+ # The percentage/speed keys serialize the derived methods; the
11
+ # attribute names differ from the keys so the framework's
12
+ # generated readers do not shadow the methods.
13
+ class ConversionResult < Lutaml::Model::Serializable
14
+ attribute :source_path, :string
15
+ attribute :target_path, :string
16
+ attribute :source_format, :symbol
17
+ attribute :target_format, :symbol
18
+ attribute :source_size, :integer
19
+ attribute :target_size, :integer
20
+ attribute :duration, :double
21
+ attribute :entry_count, :integer
22
+ attribute :warnings, :string, collection: true, default: []
23
+
24
+ attribute :ratio, :double, method: :compression_ratio_value
25
+ attribute :reduction_pct, :double, method: :size_reduction
26
+ attribute :ratio_pct, :double, method: :size_ratio
27
+ attribute :speed, :double, method: :processing_speed
28
+
29
+ key_value do
30
+ map "source_path", to: :source_path,
31
+ render_default: true, render_nil: true
32
+ map "target_path", to: :target_path,
33
+ render_default: true, render_nil: true
34
+ map "source_format", to: :source_format,
35
+ render_default: true, render_nil: true
36
+ map "target_format", to: :target_format,
37
+ render_default: true, render_nil: true
38
+ map "source_size", to: :source_size,
39
+ render_default: true, render_nil: true
40
+ map "target_size", to: :target_size,
41
+ render_default: true, render_nil: true
42
+ map "size_reduction", to: :reduction_pct,
43
+ render_default: true, render_nil: true
44
+ map "size_ratio", to: :ratio_pct,
45
+ render_default: true, render_nil: true
46
+ map "duration", to: :duration,
47
+ render_default: true, render_nil: true
48
+ map "entry_count", to: :entry_count,
49
+ render_default: true, render_nil: true
50
+ map "processing_speed", to: :speed,
51
+ render_default: true, render_nil: true
52
+ map "warnings", to: :warnings,
53
+ render_default: true, render_nil: true
54
+ map "compression_ratio", to: :ratio,
55
+ render_default: true, render_nil: true
56
+ end
57
+
58
+ # lutaml-model 0.8.x does not render empty-string/empty-collection
59
+ # defaults, so they are assigned explicitly to keep every key
60
+ # present in the serialized shape.
61
+ def initialize(attrs = {})
62
+ super({ warnings: [] }.merge(attrs))
42
63
  end
43
64
 
44
65
  # Get size reduction percentage
66
+ #
45
67
  # @return [Float] Size reduction as percentage
46
68
  def size_reduction
47
- return 0.0 if source_size.zero?
69
+ return 0.0 if source_size.to_i.zero?
48
70
 
49
71
  ((source_size - target_size).to_f / source_size * 100).round(2)
50
72
  end
51
73
 
52
74
  # Get size ratio
75
+ #
53
76
  # @return [Float] Target size as percentage of source size
54
77
  def size_ratio
55
- return 0.0 if source_size.zero?
78
+ return 0.0 if source_size.to_i.zero?
56
79
 
57
80
  (target_size.to_f / source_size * 100).round(2)
58
81
  end
59
82
 
60
83
  # Check if conversion resulted in smaller file
84
+ #
61
85
  # @return [Boolean] True if target is smaller
62
86
  def smaller?
63
87
  target_size < source_size
64
88
  end
65
89
 
66
90
  # Check if conversion resulted in larger file
91
+ #
67
92
  # @return [Boolean] True if target is larger
68
93
  def larger?
69
94
  target_size > source_size
70
95
  end
71
96
 
72
97
  # Check if there were warnings
98
+ #
73
99
  # @return [Boolean] True if warnings exist
74
100
  def warnings?
75
101
  !warnings.empty?
76
102
  end
77
103
 
78
104
  # Get average processing speed
105
+ #
79
106
  # @return [Float] MB/s processing speed
80
107
  def processing_speed
81
- return 0.0 if duration.zero? || source_size.zero?
108
+ return 0.0 if duration.to_f.zero? || source_size.to_i.zero?
82
109
 
83
110
  speed = source_size / duration / 1_048_576.0
84
111
  rounded = speed.round(2)
@@ -86,26 +113,17 @@ module Omnizip
86
113
  rounded.zero? && speed.positive? ? speed : rounded
87
114
  end
88
115
 
89
- # Convert to hash
90
- # @return [Hash] Result as hash
91
- def to_h
92
- {
93
- source_path: source_path,
94
- target_path: target_path,
95
- source_format: source_format,
96
- target_format: target_format,
97
- source_size: source_size,
98
- target_size: target_size,
99
- size_reduction: size_reduction,
100
- size_ratio: size_ratio,
101
- duration: duration,
102
- entry_count: entry_count,
103
- processing_speed: processing_speed,
104
- warnings: warnings,
105
- }
116
+ # Compression ratio (0.0-1.0 fraction saved by compression)
117
+ #
118
+ # @return [Float]
119
+ def compression_ratio_value
120
+ return 0.0 if source_size.to_i.zero?
121
+
122
+ (1.0 - (target_size.to_f / source_size)).round(4)
106
123
  end
107
124
 
108
125
  # Format as human-readable string
126
+ #
109
127
  # @return [String] Formatted result
110
128
  def to_s
111
129
  "Converted #{source_path} (#{format_size(source_size)}) to " \
@@ -115,12 +133,6 @@ module Omnizip
115
133
 
116
134
  private
117
135
 
118
- def calculate_compression_ratio
119
- return 0.0 if source_size.zero?
120
-
121
- (1.0 - (target_size.to_f / source_size)).round(4)
122
- end
123
-
124
136
  def format_size(bytes)
125
137
  Omnizip::CliOutputFormatter.format_size(bytes)
126
138
  end
@@ -16,6 +16,8 @@
16
16
  # See the COPYING file for the complete text of the license.
17
17
  #
18
18
 
19
+ require "lutaml/model"
20
+
19
21
  module Omnizip
20
22
  module Models
21
23
  # Configuration model for a filter in a compression pipeline.
@@ -23,6 +25,8 @@ module Omnizip
23
25
  # This class replaces hash-based filter configuration with a proper
24
26
  # model class. It provides format-aware ID resolution and validation.
25
27
  #
28
+ # Serialized via lutaml-model — no hand-rolled +to_h+ / +to_json+.
29
+ #
26
30
  # @example Create a BCJ filter configuration
27
31
  # config = FilterConfig.new(name: :bcj_x86, architecture: :x86)
28
32
  # config.id_for_format(:xz) # => 0x04
@@ -31,42 +35,39 @@ module Omnizip
31
35
  # @example Create a Delta filter configuration
32
36
  # config = FilterConfig.new(name: :delta)
33
37
  # config.delta? # => true
34
- class FilterConfig
35
- # @return [Symbol] Filter name (:bcj_x86, :delta, etc.)
36
- attr_reader :name_sym
37
-
38
- # @return [String] Binary properties data for filter configuration
39
- attr_accessor :properties
40
-
41
- # @return [Symbol] Target architecture for BCJ filters
42
- attr_accessor :architecture
38
+ class FilterConfig < Lutaml::Model::Serializable
39
+ attribute :name, :symbol
40
+ attribute :properties, :string, default: ""
41
+ attribute :architecture, :symbol
42
+
43
+ key_value do
44
+ map "name", to: :name, render_default: true, render_nil: true
45
+ map "properties", to: :properties,
46
+ render_default: true, render_nil: true
47
+ map "architecture", to: :architecture,
48
+ render_default: true, render_nil: true
49
+ end
43
50
 
44
- # Initialize filter configuration.
51
+ # Initialize filter configuration. The legacy +name_sym+ key is
52
+ # accepted as an alias for +name+.
45
53
  #
46
54
  # @param attributes [Hash] Initialization attributes
47
55
  # @option attributes [Symbol] :name Filter name
48
- # @option attributes [Symbol] :name_sym Filter name (alternative key)
56
+ # @option attributes [Symbol] :name_sym Filter name (alias)
49
57
  # @option attributes [String] :properties Binary properties data
50
58
  # @option attributes [Symbol] :architecture Target architecture
51
59
  def initialize(attributes = {})
52
- @name_sym = attributes[:name] || attributes[:name_sym]
53
- @properties = attributes[:properties] || "".b
54
- @architecture = attributes[:architecture]
60
+ attrs = attributes.dup
61
+ attrs[:name] ||= attrs.delete(:name_sym)
62
+ attrs[:properties] ||= "" # empty-string defaults do not render
63
+ super(attrs)
55
64
  end
56
65
 
57
- # Set filter name.
58
- #
59
- # @param value [Symbol] Filter name
60
- # @return [void]
61
- def name=(value)
62
- @name_sym = value
63
- end
64
-
65
- # Get filter name as symbol.
66
+ # Get filter name as symbol (legacy alias for #name).
66
67
  #
67
68
  # @return [Symbol] Filter name
68
69
  def name_sym
69
- @name_sym
70
+ name
70
71
  end
71
72
 
72
73
  # Get filter instance from registry.
@@ -74,11 +75,11 @@ module Omnizip
74
75
  # @return [Object] Filter instance from FilterRegistry
75
76
  # @raise [KeyError] If filter not found in registry
76
77
  def filter_instance
77
- filter = Omnizip::FilterRegistry.get(@name_sym)
78
+ filter = Omnizip::FilterRegistry.get(name)
78
79
 
79
80
  # Handle architecture parameter if needed
80
- if @architecture && requires_initialize_kwargs?(filter)
81
- filter.new(architecture: @architecture)
81
+ if architecture && requires_initialize_kwargs?(filter)
82
+ filter.new(architecture: architecture)
82
83
  else
83
84
  filter.new
84
85
  end
@@ -100,7 +101,7 @@ module Omnizip
100
101
  filter.id_for_format(format)
101
102
  else
102
103
  raise NotImplementedError,
103
- "Filter #{@name_sym} doesn't support format-aware IDs. " \
104
+ "Filter #{name} doesn't support format-aware IDs. " \
104
105
  "Use the newer BCJ filter instead."
105
106
  end
106
107
  end
@@ -109,14 +110,14 @@ module Omnizip
109
110
  #
110
111
  # @return [Boolean] True if BCJ filter variant
111
112
  def bcj?
112
- @name_sym.to_s.start_with?("bcj_")
113
+ name.to_s.start_with?("bcj_")
113
114
  end
114
115
 
115
116
  # Check if this is a Delta filter.
116
117
  #
117
118
  # @return [Boolean] True if Delta filter
118
119
  def delta?
119
- @name_sym == :delta
120
+ name == :delta
120
121
  end
121
122
 
122
123
  # Validate configuration.
@@ -124,26 +125,15 @@ module Omnizip
124
125
  # @return [Boolean] True if valid
125
126
  # @raise [ArgumentError] If filter name is nil or not registered
126
127
  def validate!
127
- raise ArgumentError, "Filter name is required" if @name_sym.nil?
128
+ raise ArgumentError, "Filter name is required" if name.nil?
128
129
 
129
- unless Omnizip::FilterRegistry.registered?(@name_sym)
130
- raise ArgumentError, "Filter not registered: #{@name_sym}"
130
+ unless Omnizip::FilterRegistry.registered?(name)
131
+ raise ArgumentError, "Filter not registered: #{name}"
131
132
  end
132
133
 
133
134
  true
134
135
  end
135
136
 
136
- # Convert to hash representation.
137
- #
138
- # @return [Hash] Hash representation with :name, :properties, :architecture
139
- def to_h
140
- {
141
- name: @name_sym,
142
- properties: @properties,
143
- architecture: @architecture,
144
- }
145
- end
146
-
147
137
  private
148
138
 
149
139
  # Check if filter class requires keyword arguments for initialize.
@@ -1,24 +1,46 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "lutaml/model"
4
+
3
5
  module Omnizip
4
6
  module Models
5
- # Represents the result of pattern matching against archive entries
7
+ # Represents the result of pattern matching against archive entries.
6
8
  #
7
- # Contains matched entries with metadata about the matching process.
8
- class MatchResult
9
+ # Serialized via lutaml-model — no hand-rolled +to_h+ / +to_json+.
10
+ # The serialized "matches" is the match COUNT (not the entry
11
+ # objects, which are arbitrary caller types); the live entry
12
+ # collection stays a plain reader.
13
+ class MatchResult < Lutaml::Model::Serializable
9
14
  include Enumerable
10
15
 
11
- attr_reader :matches, :total_scanned, :pattern
16
+ attribute :total_scanned, :integer, default: 0
17
+
18
+ attribute :pattern_repr, :string, method: :pattern_to_s
19
+ attribute :match_count, :integer, method: :count
20
+ attribute :rate, :double, method: :match_rate
21
+
22
+ key_value do
23
+ map "pattern", to: :pattern_repr,
24
+ render_default: true, render_nil: true
25
+ map "matches", to: :match_count,
26
+ render_default: true, render_nil: true
27
+ map "scanned", to: :total_scanned,
28
+ render_default: true, render_nil: true
29
+ map "match_rate", to: :rate,
30
+ render_default: true, render_nil: true
31
+ end
32
+
33
+ attr_reader :matches, :pattern
12
34
 
13
35
  # Initialize a new match result
14
36
  #
15
37
  # @param pattern [Object] The pattern that was matched
16
38
  # @param matches [Array] Array of matched entries
17
39
  # @param total_scanned [Integer] Total entries scanned
18
- def initialize(pattern, matches: [], total_scanned: 0)
40
+ def initialize(pattern = nil, matches: [], total_scanned: 0)
41
+ super(total_scanned: total_scanned)
19
42
  @pattern = pattern
20
43
  @matches = Array(matches)
21
- @total_scanned = total_scanned
22
44
  end
23
45
 
24
46
  # Add a matched entry
@@ -35,7 +57,7 @@ module Omnizip
35
57
  # @param count [Integer] Number to increment by
36
58
  # @return [self]
37
59
  def increment_scanned(count = 1)
38
- @total_scanned += count
60
+ self.total_scanned = total_scanned + count
39
61
  self
40
62
  end
41
63
 
@@ -64,9 +86,9 @@ module Omnizip
64
86
  #
65
87
  # @return [Float] Match rate between 0.0 and 1.0
66
88
  def match_rate
67
- return 0.0 if @total_scanned.zero?
89
+ return 0.0 if total_scanned.zero?
68
90
 
69
- count.to_f / @total_scanned
91
+ count.to_f / total_scanned
70
92
  end
71
93
 
72
94
  # Get match percentage
@@ -108,16 +130,11 @@ module Omnizip
108
130
  @matches.dup
109
131
  end
110
132
 
111
- # Get summary hash
133
+ # Serialized pattern representation.
112
134
  #
113
- # @return [Hash]
114
- def to_h
115
- {
116
- pattern: @pattern.to_s,
117
- matches: count,
118
- scanned: @total_scanned,
119
- match_rate: match_rate,
120
- }
135
+ # @return [String] The pattern as a string
136
+ def pattern_to_s
137
+ @pattern.to_s
121
138
  end
122
139
  end
123
140
  end
@@ -1,41 +1,60 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "lutaml/model"
4
+
3
5
  module Omnizip
4
6
  module Models
5
- # Represents a performance optimization suggestion based on profiling data
6
- class OptimizationSuggestion
7
+ # Represents a performance optimization suggestion based on
8
+ # profiling data.
9
+ #
10
+ # Serialized via lutaml-model — no hand-rolled +to_h+ / +to_json+.
11
+ # The priority_score key serializes the derived #priority_score
12
+ # method under a distinct attribute name.
13
+ class OptimizationSuggestion < Lutaml::Model::Serializable
7
14
  SEVERITY_LEVELS = %i[low medium high critical].freeze
8
15
  CATEGORIES = %i[
9
16
  memory cpu hotpath algorithm io gc allocation concurrency
10
17
  ].freeze
11
18
 
12
- attr_reader :title, :description, :severity, :category, :impact_estimate,
13
- :implementation_effort, :related_operations, :code_locations,
14
- :metrics
19
+ attribute :title, :string
20
+ attribute :description, :string
21
+ attribute :severity, :symbol
22
+ attribute :category, :symbol
23
+ attribute :impact_estimate, :double
24
+ attribute :implementation_effort, :double
25
+ attribute :related_operations, :string, collection: true, default: []
26
+ attribute :code_locations, :string, collection: true, default: []
27
+ attribute :metrics, :hash, default: {}
28
+
29
+ attribute :priority, :double, method: :priority_score
30
+
31
+ key_value do
32
+ map "title", to: :title, render_default: true, render_nil: true
33
+ map "description", to: :description,
34
+ render_default: true, render_nil: true
35
+ map "severity", to: :severity, render_default: true, render_nil: true
36
+ map "category", to: :category, render_default: true, render_nil: true
37
+ map "impact_estimate", to: :impact_estimate,
38
+ render_default: true, render_nil: true
39
+ map "implementation_effort", to: :implementation_effort,
40
+ render_default: true, render_nil: true
41
+ map "priority_score", to: :priority,
42
+ render_default: true, render_nil: true
43
+ map "related_operations", to: :related_operations,
44
+ render_default: true, render_nil: true
45
+ map "code_locations", to: :code_locations,
46
+ render_default: true, render_nil: true
47
+ map "metrics", to: :metrics, render_default: true, render_nil: true
48
+ end
15
49
 
16
- def initialize(
17
- title:,
18
- description:,
19
- severity:,
20
- category:,
21
- impact_estimate: nil,
22
- implementation_effort: nil,
23
- related_operations: [],
24
- code_locations: [],
25
- metrics: {}
26
- )
50
+ # Severity and category are validated after the framework
51
+ # constructor assigns the attributes. Empty-collection defaults
52
+ # are assigned explicitly (lutaml-model 0.8.x drops them).
53
+ def initialize(attrs = {})
54
+ super({ related_operations: [], code_locations: [],
55
+ metrics: {} }.merge(attrs))
27
56
  validate_severity!(severity)
28
57
  validate_category!(category)
29
-
30
- @title = title
31
- @description = description
32
- @severity = severity
33
- @category = category
34
- @impact_estimate = impact_estimate
35
- @implementation_effort = implementation_effort
36
- @related_operations = related_operations
37
- @code_locations = code_locations
38
- @metrics = metrics
39
58
  end
40
59
 
41
60
  def critical?
@@ -54,21 +73,6 @@ module Omnizip
54
73
  severity_weight * impact_weight * effort_weight
55
74
  end
56
75
 
57
- def to_h
58
- {
59
- title: title,
60
- description: description,
61
- severity: severity,
62
- category: category,
63
- impact_estimate: impact_estimate,
64
- implementation_effort: implementation_effort,
65
- priority_score: priority_score,
66
- related_operations: related_operations,
67
- code_locations: code_locations,
68
- metrics: metrics,
69
- }
70
- end
71
-
72
76
  private
73
77
 
74
78
  def validate_severity!(severity)
@@ -1,35 +1,60 @@
1
- # frozen_string_literal: true
1
+ # frozen_string: true
2
+
3
+ require "lutaml/model"
2
4
 
3
5
  module Omnizip
4
6
  module Models
5
- # Represents the performance characteristics of a profiled operation
6
- class PerformanceResult
7
- attr_reader :operation_name, :total_time, :cpu_time, :wall_time,
8
- :memory_allocated, :memory_retained, :object_allocations,
9
- :gc_runs, :call_count, :timestamp
7
+ # Represents the performance characteristics of a profiled operation.
8
+ #
9
+ # Serialized via lutaml-model — no hand-rolled +to_h+ / +to_json+.
10
+ # The derived-rate keys serialize the calculation methods; attribute
11
+ # names differ from the keys so generated readers do not shadow them.
12
+ class PerformanceResult < Lutaml::Model::Serializable
13
+ attribute :operation_name, :string
14
+ attribute :total_time, :double
15
+ attribute :cpu_time, :double
16
+ attribute :wall_time, :double
17
+ attribute :memory_allocated, :integer
18
+ attribute :memory_retained, :integer
19
+ attribute :object_allocations, :integer
20
+ attribute :gc_runs, :integer
21
+ attribute :call_count, :integer
22
+ attribute :timestamp, :date_time, default: -> { Time.now }
23
+
24
+ attribute :throughput, :double, method: :throughput_ops_per_second
25
+ attribute :average_time, :double, method: :average_time_per_operation
26
+ attribute :memory_per_op, :double, method: :memory_per_operation
27
+ attribute :pressure, :double, method: :gc_pressure
10
28
 
11
- def initialize(
12
- operation_name:,
13
- total_time: nil,
14
- cpu_time: nil,
15
- wall_time: nil,
16
- memory_allocated: nil,
17
- memory_retained: nil,
18
- object_allocations: nil,
19
- gc_runs: nil,
20
- call_count: nil,
21
- timestamp: Time.now
22
- )
23
- @operation_name = operation_name
24
- @total_time = total_time
25
- @cpu_time = cpu_time
26
- @wall_time = wall_time
27
- @memory_allocated = memory_allocated
28
- @memory_retained = memory_retained
29
- @object_allocations = object_allocations
30
- @gc_runs = gc_runs
31
- @call_count = call_count
32
- @timestamp = timestamp
29
+ key_value do
30
+ map "operation_name", to: :operation_name,
31
+ render_default: true, render_nil: true
32
+ map "total_time", to: :total_time,
33
+ render_default: true, render_nil: true
34
+ map "cpu_time", to: :cpu_time,
35
+ render_default: true, render_nil: true
36
+ map "wall_time", to: :wall_time,
37
+ render_default: true, render_nil: true
38
+ map "memory_allocated", to: :memory_allocated,
39
+ render_default: true, render_nil: true
40
+ map "memory_retained", to: :memory_retained,
41
+ render_default: true, render_nil: true
42
+ map "object_allocations", to: :object_allocations,
43
+ render_default: true, render_nil: true
44
+ map "gc_runs", to: :gc_runs,
45
+ render_default: true, render_nil: true
46
+ map "call_count", to: :call_count,
47
+ render_default: true, render_nil: true
48
+ map "throughput_ops_per_second", to: :throughput,
49
+ render_default: true, render_nil: true
50
+ map "average_time_per_operation", to: :average_time,
51
+ render_default: true, render_nil: true
52
+ map "memory_per_operation", to: :memory_per_op,
53
+ render_default: true, render_nil: true
54
+ map "gc_pressure", to: :pressure,
55
+ render_default: true, render_nil: true
56
+ map "timestamp", to: :timestamp,
57
+ render_default: true, render_nil: true
33
58
  end
34
59
 
35
60
  def throughput_ops_per_second
@@ -55,25 +80,6 @@ module Omnizip
55
80
 
56
81
  gc_runs.to_f / total_time
57
82
  end
58
-
59
- def to_h
60
- {
61
- operation_name: operation_name,
62
- total_time: total_time,
63
- cpu_time: cpu_time,
64
- wall_time: wall_time,
65
- memory_allocated: memory_allocated,
66
- memory_retained: memory_retained,
67
- object_allocations: object_allocations,
68
- gc_runs: gc_runs,
69
- call_count: call_count,
70
- throughput_ops_per_second: throughput_ops_per_second,
71
- average_time_per_operation: average_time_per_operation,
72
- memory_per_operation: memory_per_operation,
73
- gc_pressure: gc_pressure,
74
- timestamp: timestamp.iso8601,
75
- }
76
- end
77
83
  end
78
84
  end
79
85
  end