Skip to content

Commit

Permalink
Minor refactor of IncomingSplitBuffer
Browse files Browse the repository at this point in the history
  • Loading branch information
sfan5 committed Aug 16, 2019
1 parent fc2f55d commit 428a4c8
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 35 deletions.
83 changes: 52 additions & 31 deletions src/network/connection.cpp
Expand Up @@ -386,6 +386,48 @@ std::list<BufferedPacket> ReliablePacketBuffer::getTimedOuts(float timeout,
return timed_outs;
}

/*
IncomingSplitPacket
*/

bool IncomingSplitPacket::insert(u32 chunk_num, SharedBuffer<u8> &chunkdata)
{
sanity_check(chunk_num < chunk_count);

// If chunk already exists, ignore it.
// Sometimes two identical packets may arrive when there is network
// lag and the server re-sends stuff.
if (chunks.find(chunk_num) != chunks.end())
return false;

// Set chunk data in buffer
chunks[chunk_num] = chunkdata;

return true;
}

SharedBuffer<u8> IncomingSplitPacket::reassemble()
{
sanity_check(allReceived());

// Calculate total size
u32 totalsize = 0;
for (const auto &chunk : chunks)
totalsize += chunk.second.getSize();

SharedBuffer<u8> fulldata(totalsize);

// Copy chunks to data buffer
u32 start = 0;
for (u32 chunk_i = 0; chunk_i < chunk_count; chunk_i++) {
const SharedBuffer<u8> &buf = chunks[chunk_i];
memcpy(&fulldata[start], *buf, buf.getSize());
start += buf.getSize();
}

return fulldata;
}

/*
IncomingSplitBuffer
*/
Expand All @@ -397,10 +439,7 @@ IncomingSplitBuffer::~IncomingSplitBuffer()
delete i.second;
}
}
/*
This will throw a GotSplitPacketException when a full
split packet is constructed.
*/

SharedBuffer<u8> IncomingSplitBuffer::insert(const BufferedPacket &p, bool reliable)
{
MutexAutoLock listlock(m_map_mutex);
Expand All @@ -426,12 +465,14 @@ SharedBuffer<u8> IncomingSplitBuffer::insert(const BufferedPacket &p, bool relia
}

// Add if doesn't exist
IncomingSplitPacket *sp;
if (m_buf.find(seqnum) == m_buf.end()) {
m_buf[seqnum] = new IncomingSplitPacket(chunk_count, reliable);
sp = new IncomingSplitPacket(chunk_count, reliable);
m_buf[seqnum] = sp;
} else {
sp = m_buf[seqnum];
}

IncomingSplitPacket *sp = m_buf[seqnum];

if (chunk_count != sp->chunk_count) {
errorstream << "IncomingSplitBuffer::insert(): chunk_count="
<< chunk_count << " != sp->chunk_count=" << sp->chunk_count
Expand All @@ -443,47 +484,27 @@ SharedBuffer<u8> IncomingSplitBuffer::insert(const BufferedPacket &p, bool relia
<<" != sp->reliable="<<sp->reliable
<<std::endl);

// If chunk already exists, ignore it.
// Sometimes two identical packets may arrive when there is network
// lag and the server re-sends stuff.
if (sp->chunks.find(chunk_num) != sp->chunks.end())
return SharedBuffer<u8>();

// Cut chunk data out of packet
u32 chunkdatasize = p.data.getSize() - headersize;
SharedBuffer<u8> chunkdata(chunkdatasize);
memcpy(*chunkdata, &(p.data[headersize]), chunkdatasize);

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

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

// Calculate total size
u32 totalsize = 0;
for (const auto &chunk : sp->chunks) {
totalsize += chunk.second.getSize();
}

SharedBuffer<u8> fulldata(totalsize);

// Copy chunks to data buffer
u32 start = 0;
for (u32 chunk_i=0; chunk_i<sp->chunk_count; chunk_i++) {
const SharedBuffer<u8> &buf = sp->chunks[chunk_i];
u16 buf_chunkdatasize = buf.getSize();
memcpy(&fulldata[start], *buf, buf_chunkdatasize);
start += buf_chunkdatasize;
}
SharedBuffer<u8> fulldata = sp->reassemble();

// Remove sp from buffer
m_buf.erase(seqnum);
delete sp;

return fulldata;
}

void IncomingSplitBuffer::removeUnreliableTimedOuts(float dtime, float timeout)
{
std::deque<u16> remove_queue;
Expand Down
12 changes: 8 additions & 4 deletions src/network/connection.h
Expand Up @@ -121,16 +121,20 @@ struct IncomingSplitPacket

IncomingSplitPacket() = delete;

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

bool allReceived() const
{
return (chunks.size() == chunk_count);
}
bool insert(u32 chunk_num, SharedBuffer<u8> &chunkdata);
SharedBuffer<u8> reassemble();

private:
// Key is chunk number, value is data without headers
std::map<u16, SharedBuffer<u8>> chunks;
};

/*
Expand Down

0 comments on commit 428a4c8

Please sign in to comment.