1+ /* *
2+ * \file topPorts.cpp
3+ * \brief TopPorts class implementation.
4+ * \author Damir Zainullin <zaidamilda@gmail.com>
5+ * \date 2024
6+ */
7+
8+ #include " topPorts.hpp"
9+
10+ #include < functional>
11+ #include < algorithm>
12+ #include < array>
13+ #include < cstdint>
14+ #include < limits>
15+ #include < vector>
16+ #include < string>
17+
18+ namespace ipxp {
19+
20+ TopPorts::TopPorts (size_t top_ports_count) noexcept
21+ : m_top_ports_count(top_ports_count)
22+ {
23+ }
24+
25+ std::string TopPorts::PortStats::to_string () const noexcept
26+ {
27+ return std::to_string (port) + " [" +
28+ (protocol == Protocol::TCP ? " TCP" : " UDP" ) + " ] - " + std::to_string (frequency);
29+ }
30+
31+ bool update_port_buffer (std::vector<TopPorts::PortStats>& port_buffer, TopPorts::PortStats port_stats) noexcept {
32+ auto port_pos = std::lower_bound (port_buffer.begin (), port_buffer.end (), port_stats.frequency ,
33+ [](const TopPorts::PortStats& port_frequency, size_t count) {
34+ return port_frequency.frequency >= count;
35+ });
36+
37+ if (port_pos != port_buffer.end ()) {
38+ std::copy_backward (port_pos, std::prev (port_buffer.end ()), port_buffer.end ());
39+ *port_pos = port_stats;
40+ return true ;
41+ // ports_inserted = std::min<size_t>(m_top_ports_count, ports_inserted + 1);
42+ }
43+ return false ;
44+ };
45+
46+ std::vector<TopPorts::PortStats> TopPorts::get_top_ports () const noexcept
47+ {
48+ std::vector<PortStats> port_buffer (m_top_ports_count);
49+ size_t ports_inserted = 0 ;
50+
51+ std::for_each (m_tcp_port_frequencies.begin (), m_tcp_port_frequencies.end (), [&, port = uint16_t {0 }](size_t frequency) mutable {
52+ ports_inserted += update_port_buffer (port_buffer, {port++, frequency, PortStats::Protocol::TCP });
53+ });
54+ std::for_each (m_udp_port_frequencies.begin (), m_udp_port_frequencies.end (), [&, port = uint16_t {0 }](size_t frequency) mutable {
55+ ports_inserted += update_port_buffer (port_buffer, {port++, frequency, PortStats::Protocol::UDP });
56+ });
57+
58+ port_buffer.resize (std::min (m_top_ports_count, ports_inserted));
59+ return port_buffer;
60+ }
61+
62+ } // namespace ipxp
0 commit comments