TokenBucketFilter 改

TokenBucketFilter - Tociyuki::Diary」では 2 つのインスタンス変数で状態変化をおこなっていました。これを 1 つの状態変数にまとめてみます。

前に書いたコードに手をいれやすくするために、若干修正すると次のようになります。token と prevtime の 2 つが状態変数になっています。capacity と period は状態変化しても値が変わらないパラメータです。

class TokenBucketFilter
  # portred from linux-2.6.32/net/sched/sch_tbf.c
  # after accepting burst tokens, limits 1 token / period seconds.
  def initialize(burst, period, now)
    @token = @capacity = burst * period
    @period = period
    @prevtime = now
  end

  def pass?(now)
    r = false
    @token = [@token + now - @prevtime, @capacity].min # (1)
    if @token >= @period
      @token -= @period
      r = true
    end
    @prevtime = now # (2)
    return r
  end
end

まず (1) の右辺の第一項と (2) をとりだします。

  @token = @token + now - @prevtime
  @prevtime = now

ここで、prevtime を、prevtime から token を引いた credit に置き換えます。

  @token = @token + now - (@credit + @token)
  @credit = now - @token

上の第一式の右辺の括弧を外すと、token 同士が打ち消しあいます。

  @token = now - @credit
  @credit = now - @token

こうして、token は一時変数になり、状態変数は credit 一つになります。

class TokenBucketFilter
  # portred from linux-2.6.32/net/sched/sch_tbf.c
  # after accepting burst tokens, limits 1 token / period seconds.
  def initialize(burst, period, now)
    token = @capacity = burst * period
    @period = period
    @credit = now - token
  end

  def pass?(now)
    r = false
    token = [now - @credit, @capacity].min
    if token >= @period
      token -= @period
      r = true
    end
    @credit = now - token
    return r
  end
end