/**
 * 
 */
package jist.swans.rate;

import org.apache.log4j.Logger;

import jist.swans.mac.MacInfo;

/**
 * Implementation of the AARF algorithm. Inspired by the implementation in
 * yans-0.9.0 (http://yans.inria.fr/).
 * 
 * @author Oliver
 * 
 */
public class AdaptiveAutoRateFallback extends AutoRateFallback {

  public static Logger log = Logger.getLogger(AdaptiveAutoRateFallback.class);
  
  protected ArfState createState() {
    return new AarfState();
  }
    
  public AdaptiveAutoRateFallback(MacInfo macInfo) {
    super(macInfo);
  }

  public AdaptiveAutoRateFallback(MacInfo macInfo, int thresholdFactor, int maxSuccessThreshold,
      int timerFactor) {
    super(macInfo);
    AarfState.m_success_k = thresholdFactor;
    AarfState.m_max_success_threshold = maxSuccessThreshold;
    AarfState.m_timer_k = timerFactor;
  }

  public AdaptiveAutoRateFallback(MacInfo macInfo, int thresholdFactor, int maxSuccessThreshold,
      int minTimerTimeout, int minSuccessThreshold, int timerFactor) {
    super(macInfo, minTimerTimeout, minSuccessThreshold);
    AarfState.m_success_k = thresholdFactor;
    AarfState.m_max_success_threshold = maxSuccessThreshold;
    AarfState.m_timer_k = timerFactor;
  }

  static protected class AarfState extends ArfState {
    static double m_success_k             = 2.0;

    static int    m_max_success_threshold = 50;

    static double m_timer_k               = 1.5;

    protected void report_recovery_failure() {
      set_success_threshold((int) (Math.min(m_success_threshold * m_success_k,
          m_max_success_threshold)));
      set_timer_timeout((int) (Math.max(s_min_timer_timeout,
          m_success_threshold * m_timer_k)));
    }

    protected void report_failure() {
      set_timer_timeout(s_min_timer_timeout);
      set_success_threshold(s_min_success_threshold);
    }
  }
}
