Replace ConnList linked list with multiset

Keeping a sorted multi-set allows faster search by source /
source+destination address.

Fixes O(n^2) complexity when handling a lot of connections (now it's
O(n log n)).
This commit is contained in:
Vladimir Panteleev
2022-03-23 17:28:09 +00:00
parent f46954525d
commit 92fb73116a
6 changed files with 100 additions and 96 deletions

View File

@@ -97,13 +97,10 @@ void process_init() {
int Process::getLastPacket() {
int lastpacket = 0;
ConnList *curconn = connections;
while (curconn != NULL) {
assert(curconn != NULL);
assert(curconn->getVal() != NULL);
if (curconn->getVal()->getLastPacket() > lastpacket)
lastpacket = curconn->getVal()->getLastPacket();
curconn = curconn->getNext();
for (auto it = connections.begin(); it != connections.end(); ++it) {
assert(*it != NULL);
if ((*it)->getLastPacket() > lastpacket)
lastpacket = (*it)->getLastPacket();
}
return lastpacket;
}
@@ -113,30 +110,20 @@ static void sum_active_connections(Process *process_ptr, u_int64_t &sum_sent,
u_int64_t &sum_recv) {
/* walk though all process_ptr process's connections, and sum
* them up */
ConnList *curconn = process_ptr->connections;
ConnList *previous = NULL;
while (curconn != NULL) {
if (curconn->getVal()->getLastPacket() <= curtime.tv_sec - CONNTIMEOUT) {
for (auto it = process_ptr->connections.begin(); it != process_ptr->connections.end(); ) {
if ((*it)->getLastPacket() <= curtime.tv_sec - CONNTIMEOUT) {
/* capture sent and received totals before deleting */
process_ptr->sent_by_closed_bytes += curconn->getVal()->sumSent;
process_ptr->rcvd_by_closed_bytes += curconn->getVal()->sumRecv;
process_ptr->sent_by_closed_bytes += (*it)->sumSent;
process_ptr->rcvd_by_closed_bytes += (*it)->sumRecv;
/* stalled connection, remove. */
ConnList *todelete = curconn;
Connection *conn_todelete = curconn->getVal();
curconn = curconn->getNext();
if (todelete == process_ptr->connections)
process_ptr->connections = curconn;
if (previous != NULL)
previous->setNext(curconn);
delete (todelete);
delete (conn_todelete);
delete (*it);
it = process_ptr->connections.erase(it);
} else {
u_int64_t sent = 0, recv = 0;
curconn->getVal()->sumanddel(curtime, &recv, &sent);
(*it)->sumanddel(curtime, &recv, &sent);
sum_sent += sent;
sum_recv += recv;
previous = curconn;
curconn = curconn->getNext();
++it;
}
}
}
@@ -171,12 +158,10 @@ void Process::getgbps(float *recvd, float *sent) {
/** get total values for this process */
void Process::gettotal(u_int64_t *recvd, u_int64_t *sent) {
u_int64_t sum_sent = 0, sum_recv = 0;
ConnList *curconn = this->connections;
while (curconn != NULL) {
Connection *conn = curconn->getVal();
for (auto it = this->connections.begin(); it != this->connections.end(); ++it) {
Connection *conn = (*it);
sum_sent += conn->sumSent;
sum_recv += conn->sumRecv;
curconn = curconn->getNext();
}
// std::cout << "Sum sent: " << sum_sent << std::endl;
// std::cout << "Sum recv: " << sum_recv << std::endl;
@@ -403,7 +388,7 @@ Process *getProcess(Connection *connection, const char *devicename,
processes = new ProcList(proc, processes);
}
proc->connections = new ConnList(connection, proc->connections);
proc->connections.insert(connection);
return proc;
}