PacketSortor::needForceFlush
bool needForceFlush(SEQ seq) {
return
// 缓冲区不为空
!_pkt_sort_cache_map.empty()
&&
// 缓冲区长度超过最大值
(_pkt_sort_cache_map.size() > _max_buffer_size
// 包间隔超过指定值
|| distance(seq) > _max_distance
// 收包超过指定时间
|| _ticker.elapsedTime() > _max_buffer_ms);
}
此函数用于判断是否需要清空缓冲区
PacketSortor::distance
SEQ distance(SEQ seq) {
SEQ ret;
auto next_seq = static_cast<SEQ>(_last_seq_out + 1);
if (seq > next_seq) {
ret = seq - next_seq;
} else {
ret = next_seq - seq;
}
// 超过最大值1/2情况, 最大值1/2-ret
if (ret > SEQ_MAX >> 1) {
return SEQ_MAX - ret;
}
return ret;
}
此函数用于判断当前包的seq与预期seq的距离
PacketSorter::forceFlush
// 外部调用代码确保_pkt_sort_cache_map不为空
void forceFlush(SEQ next_seq) {
// 寻找距离比next_seq大的最近的seq
auto it = _pkt_sort_cache_map.lower_bound(next_seq);
if (it == _pkt_sort_cache_map.end()) {
// 没有比next_seq更大的seq,应该是回环时丢包导致
it = _pkt_sort_cache_map.begin();
}
// 丢包无法恢复,把这个包当做next_seq
popIterator(it);
// 清空连续包列表
flushPacket();
// 删除距离next_seq太大的包
for (auto it = _pkt_sort_cache_map.begin(); it != _pkt_sort_cache_map.end();) {
if (distance(it->first) > _max_distance) {
it = _pkt_sort_cache_map.erase(it);
} else {
++it;
}
}
}
- popIterator(it) 使用最新的包作为next_seq
- 后续清空前面连续的包,和距离太远的包
PacketSorter::flushPacket
void flushPacket() {
if (_pkt_sort_cache_map.empty()) {
return;
}
auto next_seq = static_cast<SEQ>(_last_seq_out + 1);
// 在forceflush函数中,会删除所有,next_seq已被更新为最大值
auto it = _pkt_sort_cache_map.lower_bound(next_seq);
if (!mayLooped(next_seq, next_seq)) {
// 无回环风险, 清空 < next_seq的值
it = _pkt_sort_cache_map.erase(_pkt_sort_cache_map.begin(), it);
}
// 在forceflush函数中,此段代码不会被调用
// _pkt_sort_cache_map 已经被清空
// 而且事先已经更新了_last_seq_out,即使存在非连续也不会满足要求
while (it != _pkt_sort_cache_map.end()) {
// 找到下一个包
if (it->first == static_cast<SEQ>(_last_seq_out + 1)) {
it = popIterator(it);
continue;
}
break;
}
}
此函数用于清空buffer中存在的连续包
PacketSorter::popIterator
iterator popIterator(iterator it) {
output(it->first, std::move(it->second));
return _pkt_sort_cache_map.erase(it);
}
此函数用于将缓冲区的数据取出,更新seq和定时器