Optimize removal of expired mdata records

Instead of sliding the entire queue down one element at a time, move the
non-expired elements in one step, and wipe all the trailing elements
in a single pass.
This commit is contained in:
Kp 2022-07-16 15:26:12 +00:00
parent 851edbbd3c
commit efecd3507f
2 changed files with 14 additions and 7 deletions

View file

@ -73,8 +73,8 @@ constexpr std::integral_constant<unsigned, 12> UDP_NETGAMES_PPAGE{}; // Netgames
}
#define UDP_NETGAMES_PAGES 75 // Pages available on Netlist (UDP_MAX_NETGAMES/UDP_NETGAMES_PPAGE)
#define UDP_TIMEOUT (5*F1_0) // 5 seconds disconnect timeout
#define UDP_MDATA_STOR_QUEUE_SIZE 1024 // Store up to 1024 MDATA packets
#define UDP_MDATA_STOR_MIN_FREE_2JOIN 384 // have at least this many free packet slots before we let someone join the game
#define UDP_MDATA_STOR_QUEUE_SIZE 1024u // Store up to 1024 MDATA packets
#define UDP_MDATA_STOR_MIN_FREE_2JOIN 384u // have at least this many free packet slots before we let someone join the game
#define UDP_MDATA_PKT_NUM_MIN 1 // start from pkt_num 1 (0 is used to initialize the trace list)
#define UDP_MDATA_PKT_NUM_MAX (UDP_MDATA_STOR_QUEUE_SIZE*100) // the max value for pkt_num. roll over when we go any higher. this should be smaller than INT_MAX

View file

@ -5326,7 +5326,7 @@ static int net_udp_noloss_validate_mdata(uint32_t pkt_num, ubyte sender_pnum, co
// Make sure this is the packet we are expecting!
if (UDP_mdata_trace[sender_pnum].pkt_num_torecv != pkt_num)
{
range_for (auto &i, partial_const_range(UDP_mdata_trace[sender_pnum].pkt_num, static_cast<uint32_t>(UDP_MDATA_STOR_QUEUE_SIZE)))
range_for (auto &i, partial_const_range(UDP_mdata_trace[sender_pnum].pkt_num, UDP_MDATA_STOR_QUEUE_SIZE))
{
if (pkt_num == i) // We got this packet already - need to REsend ACK
{
@ -5487,11 +5487,18 @@ void net_udp_noloss_process_queue(fix64 time)
}
// Now that we are done processing the queue, actually remove all unused packets from the top of the list.
while (!UDP_mdata_queue[0].used && UDP_mdata_queue_highest > 0)
{
std::move(std::next(UDP_mdata_queue.begin()), UDP_mdata_queue.end(), UDP_mdata_queue.begin());
UDP_mdata_queue[UDP_MDATA_STOR_QUEUE_SIZE - 1] = {};
UDP_mdata_queue_highest--;
const auto b = UDP_mdata_queue.begin();
const auto e = std::next(b, UDP_mdata_queue_highest);
const auto first_used_entry = std::find_if(b, e, [](const UDP_mdata_store &m) { return m.used; });
if (first_used_entry != b)
{
std::move(first_used_entry, e, b);
const auto total_used_entries = std::distance(first_used_entry, e);
UDP_mdata_queue_highest = total_used_entries;
for (auto first_unused_entry = std::next(b, total_used_entries); first_unused_entry != e; ++first_unused_entry)
*first_unused_entry = {};
}
}
}