Skip to content

Commit

Permalink
Top 10 ports - Introduce TopPorts class
Browse files Browse the repository at this point in the history
  • Loading branch information
Zadamsa committed Jan 27, 2025
1 parent 70e7cc2 commit 492003b
Showing 1 changed file with 58 additions and 0 deletions.
58 changes: 58 additions & 0 deletions input/topPorts.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/**
* \file topPorts.hpp
* \brief Template class implementing the most popular ports.
* \author Damir Zainullin <[email protected]>
* \date 2024
*/
#pragma once

#include <array>
#include <cstdint>
#include <functional>
#include <limits>

namespace ipxp {
/**
* \brief Top ports counter.
* \tparam TopPortsCount Number of the most popular ports to store.
*/
template<std::size_t TopPortsCount>
class TopPorts {
public:
/**
* \brief Increments number of times given port has been seen.
* \param port Port to increment its frequency.
*/
void increment_frequency(uint16_t port) noexcept
{
m_port_frequencies[port]++;
}

/**
* \brief Get the top ports.
* \return Pair of the top ports array and their count.
*/
std::pair<std::array<std::pair<uint16_t, size_t>, TopPortsCount>, size_t>
get_top_ports() const noexcept
{
std::array<std::pair<uint16_t, size_t>, TopPortsCount> res{};
size_t ports_inserted = 0;
std::for_each(m_port_frequencies.begin(), m_port_frequencies.end(),[&, port = 0](size_t count) mutable {
auto port_pos = std::lower_bound(res.begin(), res.end(), count, [](const std::pair<uint16_t, size_t>& portCount, size_t count) {
return portCount.second >= count;
});
if (port_pos != res.end()) {
std::copy_backward(port_pos, std::prev(res.end()), res.end());
*port_pos = std::make_pair(port, count);
ports_inserted = std::min(TopPortsCount, ports_inserted + 1);
}
port++;
});
return {res, ports_inserted};
}

private:
std::array<std::size_t, std::numeric_limits<uint16_t>::max() + 1> m_port_frequencies {};
};

} // namespace ipxp

0 comments on commit 492003b

Please sign in to comment.