📄 udt.cc
字号:
snd_timer_.resched(syn_interval_ + snd_interval_); freeze_ = false; } else snd_timer_.resched(snd_interval_);}void UdtAgent::rateControl(){ if (slow_start_) return; double inc = 0.0; if (bandwidth_ < 1.0 / snd_interval_) inc = 1.0/mtu_; else { inc = pow(10, ceil(log10((bandwidth_ - 1.0 / snd_interval_) * mtu_ * 8))) * 0.0000015 / mtu_; if (inc < 1.0/mtu_) inc = 1.0/mtu_; } snd_interval_ = (snd_interval_ * syn_interval_) / (snd_interval_ * inc + syn_interval_); if (snd_interval_ < 0.000001) snd_interval_ = 0.000001;}void UdtAgent::timeOut(){ if (snd_curr_seqno_ >= snd_last_ack_) { snd_loss_list_->insert(int(snd_last_ack_), int(snd_curr_seqno_)); } exp_interval_ = 1.0; //rtt_ + syn_interval_; exp_timer_.resched(exp_interval_); snd_timer_.resched(0);}/////////////////////////////////////////////////////////////////void SndTimer::expire(Event*){ a_->sendData();}void SynTimer::expire(Event*){ a_->rateControl();}void AckTimer::expire(Event*){ a_->sendCtrl(2);}void NakTimer::expire(Event*){ a_->sendCtrl(3);}void ExpTimer::expire(Event*){ a_->timeOut();}////////////////////////////////////////////////////////////////////// Definition of >, <, >=, and <= with sequence number wrapinline const bool LossList::greaterthan(const int& seqno1, const int& seqno2) const{ if ((seqno1 > seqno2) && (seqno1 - seqno2 < seq_no_th_)) return true; if (seqno1 < seqno2 - seq_no_th_) return true; return false;}inline const bool LossList::lessthan(const int& seqno1, const int& seqno2) const{ return greaterthan(seqno2, seqno1);}inline const bool LossList::notlessthan(const int& seqno1, const int& seqno2) const{ if (seqno1 == seqno2) return true; return greaterthan(seqno1, seqno2);}inline const bool LossList::notgreaterthan(const int& seqno1, const int& seqno2) const{ if (seqno1 == seqno2) return true; return lessthan(seqno1, seqno2);}// return the distance between two sequence numbers, parameters are pre-checkedinline const int LossList::getLength(const int& seqno1, const int& seqno2) const{ if (seqno2 >= seqno1) return seqno2 - seqno1 + 1; else if (seqno2 < seqno1 - seq_no_th_) return seqno2 - seqno1 + max_seq_no_ + 1; else return 0;}//Definition of ++, and -- with sequence number wrapinline const int LossList::incSeqNo(const int& seqno) const{ return (seqno + 1) % max_seq_no_;}inline const int LossList::decSeqNo(const int& seqno) const{ return (seqno - 1 + max_seq_no_) % max_seq_no_;}SndLossList::SndLossList(const int& size, const int& th, const int& max):size_(size){ seq_no_th_ = th; max_seq_no_ = max; data1_ = new int [size_]; data2_ = new int [size_]; next_ = new int [size_]; // -1 means there is no data in the node for (int i = 0; i < size; ++ i) { data1_[i] = -1; data2_[i] = -1; } length_ = 0; head_ = -1; last_insert_pos_ = -1;}SndLossList::~SndLossList(){ delete [] data1_; delete [] data2_; delete [] next_;}int SndLossList::insert(const int& seqno1, const int& seqno2){ if (0 == length_) { // insert data into an empty list head_ = 0; data1_[head_] = seqno1; if (seqno2 != seqno1) data2_[head_] = seqno2; next_[head_] = -1; last_insert_pos_ = head_; length_ += getLength(seqno1, seqno2); return length_; } // otherwise find the position where the data can be inserted int origlen = length_; int offset = seqno1 - data1_[head_]; if (offset < -seq_no_th_) offset += max_seq_no_; else if (offset > seq_no_th_) offset -= max_seq_no_; int loc = (head_ + offset + size_) % size_; if (offset < 0) { // Insert data prior to the head pointer data1_[loc] = seqno1; if (seqno2 != seqno1) data2_[loc] = seqno2; // new node becomes head next_[loc] = head_; head_ = loc; last_insert_pos_ = loc; length_ += getLength(seqno1, seqno2); } else if (offset > 0) { if (seqno1 == data1_[loc]) { last_insert_pos_ = loc; // first seqno is equivlent, compare the second if (-1 == data2_[loc]) { if (seqno2 != seqno1) { length_ += getLength(seqno1, seqno2) - 1; data2_[loc] = seqno2; } } else if (greaterthan(seqno2, data2_[loc])) { // new seq pair is longer than old pair, e.g., insert [3, 7] to [3, 5], becomes [3, 7] length_ += getLength(data2_[loc], seqno2) - 1; data2_[loc] = seqno2; } else // Do nothing if it is already there return 0; } else { // searching the prior node int i; if ((-1 != last_insert_pos_) && lessthan(data1_[last_insert_pos_], seqno1)) i = last_insert_pos_; else i = head_; while ((-1 != next_[i]) && lessthan(data1_[next_[i]], seqno1)) i = next_[i]; if ((-1 == data2_[i]) || lessthan(data2_[i], seqno1)) { last_insert_pos_ = loc; // no overlap, create new node data1_[loc] = seqno1; if (seqno2 != seqno1) data2_[loc] = seqno2; next_[loc] = next_[i]; next_[i] = loc; length_ += getLength(seqno1, seqno2); } else { last_insert_pos_ = i; // overlap, coalesce with prior node, insert(3, 7) to [2, 5], ... becomes [2, 7] if (lessthan(data2_[i], seqno2)) { length_ += getLength(data2_[i], seqno2) - 1; data2_[i] = seqno2; loc = i; } else return 0; } } } else { last_insert_pos_ = head_; // insert to head node if (seqno2 != seqno1) { if (-1 == data2_[loc]) { length_ += getLength(seqno1, seqno2) - 1; data2_[loc] = seqno2; } else if (greaterthan(seqno2, data2_[loc])) { length_ += getLength(data2_[loc], seqno2) - 1; data2_[loc] = seqno2; } else return 0; } else return 0; } // coalesce with next node. E.g., [3, 7], ..., [6, 9] becomes [3, 9] while ((-1 != next_[loc]) && (-1 != data2_[loc])) { int i = next_[loc]; if (notgreaterthan(data1_[i], incSeqNo(data2_[loc]))) { // coalesce if there is overlap if (-1 != data2_[i]) { if (greaterthan(data2_[i], data2_[loc])) { if (notlessthan(data2_[loc], data1_[i])) length_ -= getLength(data1_[i], data2_[loc]); data2_[loc] = data2_[i]; } else length_ -= getLength(data1_[i], data2_[i]); } else { if (data1_[i] == incSeqNo(data2_[loc])) data2_[loc] = data1_[i]; else length_ --; } data1_[i] = -1; data2_[i] = -1; next_[loc] = next_[i]; } else break; } return length_ - origlen;}void SndLossList::remove(const int& seqno){ if (0 == length_) return; // Remove all from the head pointer to a node with a larger seq. no. or the list is empty int offset = seqno - data1_[head_]; if (offset < -seq_no_th_) offset += max_seq_no_; else if (offset > seq_no_th_) offset -= max_seq_no_; int loc = (head_ + offset + size_) % size_; if (0 == offset) { // It is the head. Remove the head and point to the next node loc = (loc + 1) % size_; if (-1 == data2_[head_]) loc = next_[head_]; else { data1_[loc] = incSeqNo(seqno); if (greaterthan(data2_[head_], incSeqNo(seqno))) data2_[loc] = data2_[head_]; data2_[head_] = -1; next_[loc] = next_[head_]; } data1_[head_] = -1; if (last_insert_pos_ == head_) last_insert_pos_ = -1; head_ = loc; length_ --; } else if (offset > 0) { int h = head_; if (seqno == data1_[loc]) { // target node is not empty, remove part/all of the seqno in the node. int temp = loc; loc = (loc + 1) % size_; if (-1 == data2_[temp]) head_ = next_[temp]; else { // remove part, e.g., [3, 7] becomes [], [4, 7] after remove(3) data1_[loc] = incSeqNo(seqno); if (greaterthan(data2_[temp], incSeqNo(seqno))) data2_[loc] = data2_[temp]; head_ = loc; next_[loc] = next_[temp]; next_[temp] = loc; data2_[temp] = -1; } } else { // targe node is empty, check prior node int i = head_; while ((-1 != next_[i]) && lessthan(data1_[next_[i]], seqno)) i = next_[i]; loc = (loc + 1) % size_; if (-1 == data2_[i]) head_ = next_[i]; else if (greaterthan(data2_[i], seqno)) { // remove part seqno in the prior node data1_[loc] = incSeqNo(seqno); if (greaterthan(data2_[i], incSeqNo(seqno))) data2_[loc] = data2_[i]; data2_[i] = seqno; next_[loc] = next_[i]; next_[i] = loc; head_ = loc; } else head_ = next_[i]; } // Remove all nodes prior to the new head while (h != head_) { if (data2_[h] != -1) { length_ -= getLength(data1_[h], data2_[h]); data2_[h] = -1; } else length_ --; data1_[h] = -1; if (last_insert_pos_ == h) last_insert_pos_ = -1; h = next_[h]; } }}int SndLossList::getLossLength(){ return length_;}int SndLossList::getLostSeq(){ if (0 == length_) return -1; if (last_insert_pos_ == head_) last_insert_pos_ = -1; // return the first loss seq. no. int seqno = data1_[head_]; // head moves to the next node if (-1 == data2_[head_]) { //[3, -1] becomes [], and head moves to next node in the list data1_[head_] = -1; head_ = next_[head_]; } else { // shift to next node, e.g., [3, 7] becomes [], [4, 7] int loc = (head_ + 1) % size_; data1_[loc] = incSeqNo(seqno); if (greaterthan(data2_[head_], incSeqNo(seqno))) data2_[loc] = data2_[head_]; data1_[head_] = -1; data2_[head_] = -1; next_[loc] = next_[head_]; head_ = loc; } length_ --; return seqno;}//RcvLossList::RcvLossList(const int& size, const int& th, const int& max):size_(size){ seq_no_th_ = th; max_seq_no_ = max; data1_ = new int [size_]; data2_ = new int [size_];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -