Class: Omnizip::ETA::TimeEstimator
- Inherits:
-
Object
- Object
- Omnizip::ETA::TimeEstimator
- Defined in:
- lib/omnizip/eta/time_estimator.rb
Overview
Abstract base class for time estimation strategies.
This class defines the interface for ETA estimators and provides common functionality. Subclasses implement specific estimation algorithms (exponential smoothing, moving average, etc.).
Direct Known Subclasses
Instance Attribute Summary collapse
-
#rate_calculator ⇒ Object
readonly
Returns the value of attribute rate_calculator.
-
#sample_history ⇒ Object
readonly
Returns the value of attribute sample_history.
Instance Method Summary collapse
-
#add_sample(bytes_processed:, files_processed:, timestamp: Time.now) ⇒ Object
Add a sample to the history.
-
#confidence_interval(estimated_seconds, confidence_level: 0.95) ⇒ Array<Float>
Calculate confidence interval based on rate variance.
-
#estimate(remaining_bytes) ⇒ Models::ETAResult
Estimate time remaining (to be implemented by subclasses).
-
#format_time(seconds) ⇒ String
Format seconds as human-readable string.
-
#initialize(sample_history: nil, rate_calculator: nil) ⇒ TimeEstimator
constructor
Initialize a new time estimator.
-
#sufficient_samples? ⇒ Boolean
Check if we have enough samples for reliable estimation.
Constructor Details
#initialize(sample_history: nil, rate_calculator: nil) ⇒ TimeEstimator
Initialize a new time estimator
21 22 23 24 25 |
# File 'lib/omnizip/eta/time_estimator.rb', line 21 def initialize(sample_history: nil, rate_calculator: nil) @sample_history = sample_history || SampleHistory.new @rate_calculator = rate_calculator || RateCalculator.new(sample_history: @sample_history) end |
Instance Attribute Details
#rate_calculator ⇒ Object (readonly)
Returns the value of attribute rate_calculator.
15 16 17 |
# File 'lib/omnizip/eta/time_estimator.rb', line 15 def rate_calculator @rate_calculator end |
#sample_history ⇒ Object (readonly)
Returns the value of attribute sample_history.
15 16 17 |
# File 'lib/omnizip/eta/time_estimator.rb', line 15 def sample_history @sample_history end |
Instance Method Details
#add_sample(bytes_processed:, files_processed:, timestamp: Time.now) ⇒ Object
Add a sample to the history
32 33 34 35 36 37 38 |
# File 'lib/omnizip/eta/time_estimator.rb', line 32 def add_sample(bytes_processed:, files_processed:, timestamp: Time.now) sample_history.add_sample( bytes_processed: bytes_processed, files_processed: files_processed, timestamp: , ) end |
#confidence_interval(estimated_seconds, confidence_level: 0.95) ⇒ Array<Float>
Calculate confidence interval based on rate variance
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/omnizip/eta/time_estimator.rb', line 74 def confidence_interval(estimated_seconds, confidence_level: 0.95) return [0.0, 0.0] if sample_history.size < 3 # Use standard deviation of rates to calculate confidence interval std_dev = sample_history.rate_std_dev current_rate = rate_calculator.bytes_per_second return [estimated_seconds, estimated_seconds] if current_rate.zero? # Calculate coefficient of variation cv = std_dev / current_rate # Z-score for confidence level (approximation) z_score = confidence_level >= 0.99 ? 2.576 : 1.96 # Calculate interval as percentage of estimate margin = estimated_seconds * cv * z_score lower = [estimated_seconds - margin, 0.0].max upper = estimated_seconds + margin [lower, upper] end |
#estimate(remaining_bytes) ⇒ Models::ETAResult
Estimate time remaining (to be implemented by subclasses)
45 46 47 |
# File 'lib/omnizip/eta/time_estimator.rb', line 45 def estimate(remaining_bytes) raise NotImplementedError, "#{self.class} must implement #estimate" end |
#format_time(seconds) ⇒ String
Format seconds as human-readable string
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/omnizip/eta/time_estimator.rb', line 53 def format_time(seconds) return "0s" if seconds <= 0 return "∞" if seconds.infinite? hours = (seconds / 3600).floor minutes = ((seconds % 3600) / 60).floor secs = (seconds % 60).round parts = [] parts << "#{hours}h" if hours.positive? parts << "#{minutes}m" if minutes.positive? || hours.positive? parts << "#{secs}s" parts.join(" ") end |
#sufficient_samples? ⇒ Boolean
Check if we have enough samples for reliable estimation
101 102 103 |
# File 'lib/omnizip/eta/time_estimator.rb', line 101 def sufficient_samples? sample_history.size >= 3 end |