Skip to content

Commit 428a4c8

Browse files
committed
Minor refactor of IncomingSplitBuffer
1 parent fc2f55d commit 428a4c8

File tree

2 files changed

+60
-35
lines changed

2 files changed

+60
-35
lines changed

src/network/connection.cpp

+52-31
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,48 @@ std::list<BufferedPacket> ReliablePacketBuffer::getTimedOuts(float timeout,
386386
return timed_outs;
387387
}
388388

389+
/*
390+
IncomingSplitPacket
391+
*/
392+
393+
bool IncomingSplitPacket::insert(u32 chunk_num, SharedBuffer<u8> &chunkdata)
394+
{
395+
sanity_check(chunk_num < chunk_count);
396+
397+
// If chunk already exists, ignore it.
398+
// Sometimes two identical packets may arrive when there is network
399+
// lag and the server re-sends stuff.
400+
if (chunks.find(chunk_num) != chunks.end())
401+
return false;
402+
403+
// Set chunk data in buffer
404+
chunks[chunk_num] = chunkdata;
405+
406+
return true;
407+
}
408+
409+
SharedBuffer<u8> IncomingSplitPacket::reassemble()
410+
{
411+
sanity_check(allReceived());
412+
413+
// Calculate total size
414+
u32 totalsize = 0;
415+
for (const auto &chunk : chunks)
416+
totalsize += chunk.second.getSize();
417+
418+
SharedBuffer<u8> fulldata(totalsize);
419+
420+
// Copy chunks to data buffer
421+
u32 start = 0;
422+
for (u32 chunk_i = 0; chunk_i < chunk_count; chunk_i++) {
423+
const SharedBuffer<u8> &buf = chunks[chunk_i];
424+
memcpy(&fulldata[start], *buf, buf.getSize());
425+
start += buf.getSize();
426+
}
427+
428+
return fulldata;
429+
}
430+
389431
/*
390432
IncomingSplitBuffer
391433
*/
@@ -397,10 +439,7 @@ IncomingSplitBuffer::~IncomingSplitBuffer()
397439
delete i.second;
398440
}
399441
}
400-
/*
401-
This will throw a GotSplitPacketException when a full
402-
split packet is constructed.
403-
*/
442+
404443
SharedBuffer<u8> IncomingSplitBuffer::insert(const BufferedPacket &p, bool reliable)
405444
{
406445
MutexAutoLock listlock(m_map_mutex);
@@ -426,12 +465,14 @@ SharedBuffer<u8> IncomingSplitBuffer::insert(const BufferedPacket &p, bool relia
426465
}
427466

428467
// Add if doesn't exist
468+
IncomingSplitPacket *sp;
429469
if (m_buf.find(seqnum) == m_buf.end()) {
430-
m_buf[seqnum] = new IncomingSplitPacket(chunk_count, reliable);
470+
sp = new IncomingSplitPacket(chunk_count, reliable);
471+
m_buf[seqnum] = sp;
472+
} else {
473+
sp = m_buf[seqnum];
431474
}
432475

433-
IncomingSplitPacket *sp = m_buf[seqnum];
434-
435476
if (chunk_count != sp->chunk_count) {
436477
errorstream << "IncomingSplitBuffer::insert(): chunk_count="
437478
<< chunk_count << " != sp->chunk_count=" << sp->chunk_count
@@ -443,47 +484,27 @@ SharedBuffer<u8> IncomingSplitBuffer::insert(const BufferedPacket &p, bool relia
443484
<<" != sp->reliable="<<sp->reliable
444485
<<std::endl);
445486

446-
// If chunk already exists, ignore it.
447-
// Sometimes two identical packets may arrive when there is network
448-
// lag and the server re-sends stuff.
449-
if (sp->chunks.find(chunk_num) != sp->chunks.end())
450-
return SharedBuffer<u8>();
451-
452487
// Cut chunk data out of packet
453488
u32 chunkdatasize = p.data.getSize() - headersize;
454489
SharedBuffer<u8> chunkdata(chunkdatasize);
455490
memcpy(*chunkdata, &(p.data[headersize]), chunkdatasize);
456491

457-
// Set chunk data in buffer
458-
sp->chunks[chunk_num] = chunkdata;
492+
if (!sp->insert(chunk_num, chunkdata))
493+
return SharedBuffer<u8>();
459494

460495
// If not all chunks are received, return empty buffer
461496
if (!sp->allReceived())
462497
return SharedBuffer<u8>();
463498

464-
// Calculate total size
465-
u32 totalsize = 0;
466-
for (const auto &chunk : sp->chunks) {
467-
totalsize += chunk.second.getSize();
468-
}
469-
470-
SharedBuffer<u8> fulldata(totalsize);
471-
472-
// Copy chunks to data buffer
473-
u32 start = 0;
474-
for (u32 chunk_i=0; chunk_i<sp->chunk_count; chunk_i++) {
475-
const SharedBuffer<u8> &buf = sp->chunks[chunk_i];
476-
u16 buf_chunkdatasize = buf.getSize();
477-
memcpy(&fulldata[start], *buf, buf_chunkdatasize);
478-
start += buf_chunkdatasize;
479-
}
499+
SharedBuffer<u8> fulldata = sp->reassemble();
480500

481501
// Remove sp from buffer
482502
m_buf.erase(seqnum);
483503
delete sp;
484504

485505
return fulldata;
486506
}
507+
487508
void IncomingSplitBuffer::removeUnreliableTimedOuts(float dtime, float timeout)
488509
{
489510
std::deque<u16> remove_queue;

src/network/connection.h

+8-4
Original file line numberDiff line numberDiff line change
@@ -121,16 +121,20 @@ struct IncomingSplitPacket
121121

122122
IncomingSplitPacket() = delete;
123123

124-
// Key is chunk number, value is data without headers
125-
std::map<u16, SharedBuffer<u8>> chunks;
126-
u32 chunk_count;
127124
float time = 0.0f; // Seconds from adding
128-
bool reliable = false; // If true, isn't deleted on timeout
125+
u32 chunk_count;
126+
bool reliable; // If true, isn't deleted on timeout
129127

130128
bool allReceived() const
131129
{
132130
return (chunks.size() == chunk_count);
133131
}
132+
bool insert(u32 chunk_num, SharedBuffer<u8> &chunkdata);
133+
SharedBuffer<u8> reassemble();
134+
135+
private:
136+
// Key is chunk number, value is data without headers
137+
std::map<u16, SharedBuffer<u8>> chunks;
134138
};
135139

136140
/*

0 commit comments

Comments
 (0)