summaryrefslogtreecommitdiffstats
path: root/estimation-scripts/Estimators.rb
blob: 1ef0c6e2a517b6282694dd76fbf8ddbd1aeaf100 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
require 'Sample'

# abstract base class of all estimators

class Estimator

    # processes a sample
    def process(sample)
    end
    
    # returns an estimate (ETA as float)
    # note that you must process at least one sample before this will return meaningful output
    def estimate
    end

    # returns the name of the estimator
    def name
    end
end

# estimator that uses the current speed
class CSAEstimator < Estimator
    def process(sample)
        @sample = sample.clone
    end
    
    def estimate
        return @sample.bytesLeft.to_f / @sample.speed
    end

    def name
        'CurrentSpeedEstimator'
    end
end

# estimator that uses the global average speed of the whole torrent download for estimation

class GASAEstimator < Estimator
    def process(sample)
        @first = sample.clone if @first == nil
        @last = sample.clone
        @avgSpeed = Sample.averageSpeed(@first, @last)
    end

    def estimate
        return @last.bytesLeft.to_f / @avgSpeed
    end

    def name
        'AverageSpeedEstimator'
    end
end

# estimator that uses the average over the last n seconds

class WINXEstimator < Estimator

    attr_reader :windowSize

    def process(sample)
        # remove all samples that are older than the window size. Note: samples are sorted.
        @list.pop until @list.length <= 1 or (sample.time - @list.last.time) <= @windowSize

        # prepend array with newest sample
        @list.unshift(sample.clone)
    end

    def estimate

        if @list.length > 1
            first = @list.first
            last = @list.last
            return first.bytesLeft.to_f / Sample.averageSpeed(last, first) 
        elsif @list.length == 1
            sample = @list.first
            return  sample.bytesLeft.to_f / sample.speed
        elsif @list.length == 0
            return 0
        end
    end
    
    def name
        "MovingAverageEstimator_#{@windowSize}s"
    end

    def initialize(windowSizeInSeconds)
        @list = Array.new
        @windowSize = windowSizeInSeconds
    end
end