void CwndController::OnAckRcvd(bin64_t ackd) {
if (ackd==bin64_t::NONE) {
- cwnd_ /= 2;
+ if (NOW>last_change_+ch_->rtt_avg_) {
+ cwnd_ /= 2;
+ last_change_ = NOW;
+ }
} else {
if (cwnd_<1)
cwnd_ *= 2;
struct CwndController : public SendController {
- double cwnd_;
+ double cwnd_;
+ tint last_change_;
CwndController(SendController* orig, int cwnd=1) :
- SendController(orig), cwnd_(cwnd) { }
+ SendController(orig), cwnd_(cwnd), last_change_(0) { }
bool MaySendData() ;
tint NextSendTime () ;
uint64_t complete_kilo () const { return completek_; }
uint64_t seq_complete () ;
bool is_complete ()
- { return size_ && seq_complete()==size_; }
+ { return size_ && complete_==size_; }
bins& ack_out () { return ack_out_; }
~HashTree ();
data_out_.pop_front();
if (data_out_.size()!=oldsize)
cc_->OnAckRcvd(bin64_t::NONE);
+ while (data_out_.size() && ack_in_.get(data_out_.front().bin)==bins::FILLED)
+ data_out_.pop_front();
}
tintbin f = hint_out_.front();
if (f.time<NOW-rtt_avg_*8) {
hint_out_.pop_front();
+ transfer().picker().Expired(f.bin);
} else {
int status = file().ack_out().get(f.bin);
if (status==bins::EMPTY) {
+ transfer().picker().Received(f.bin);
break;
} else if (status==bins::FILLED) {
hint_out_.pop_front();
+ transfer().picker().Expired(f.bin);
} else { // mixed
hint_out_.front().bin = f.bin.right();
f.bin = f.bin.left();