From 492003bc2e66af0351c8dc03fd8505bada79126c Mon Sep 17 00:00:00 2001 From: Damir Zainullin Date: Mon, 2 Dec 2024 00:42:47 +0100 Subject: [PATCH] Top 10 ports - Introduce TopPorts class --- input/topPorts.hpp | 58 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 input/topPorts.hpp diff --git a/input/topPorts.hpp b/input/topPorts.hpp new file mode 100644 index 00000000..d42716c0 --- /dev/null +++ b/input/topPorts.hpp @@ -0,0 +1,58 @@ +/** + * \file topPorts.hpp + * \brief Template class implementing the most popular ports. + * \author Damir Zainullin + * \date 2024 + */ +#pragma once + +#include +#include +#include +#include + +namespace ipxp { +/** + * \brief Top ports counter. + * \tparam TopPortsCount Number of the most popular ports to store. + */ +template +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, TopPortsCount>, size_t> + get_top_ports() const noexcept + { + std::array, 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& 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::max() + 1> m_port_frequencies {}; +}; + +} // namespace ipxp