diff options
author | Francis Dupont <fdupont@isc.org> | 2024-07-19 14:42:14 +0200 |
---|---|---|
committer | Francis Dupont <fdupont@isc.org> | 2024-07-19 17:49:52 +0200 |
commit | 799a4cbf9913fb2a0841639bc45777b4e4df5b43 (patch) | |
tree | aa71c87b2a836541eebaeb23f6cbc7759e7f1786 | |
parent | [#3440] Added design comment (diff) | |
download | kea-799a4cbf9913fb2a0841639bc45777b4e4df5b43.tar.xz kea-799a4cbf9913fb2a0841639bc45777b4e4df5b43.zip |
[#3440] Moved to a single vector
-rw-r--r-- | src/lib/dhcp/libdhcp++.cc | 42 | ||||
-rw-r--r-- | src/lib/dhcp/tests/libdhcp++_unittest.cc | 2 |
2 files changed, 13 insertions, 31 deletions
diff --git a/src/lib/dhcp/libdhcp++.cc b/src/lib/dhcp/libdhcp++.cc index 20b6cbda9d..daa66567d3 100644 --- a/src/lib/dhcp/libdhcp++.cc +++ b/src/lib/dhcp/libdhcp++.cc @@ -485,16 +485,8 @@ LibDHCP::unpackOptions4(const OptionBuffer& buf, const string& option_space, // The buffer being read comprises a set of options, each starting with // a one-byte type code and a one-byte length field. - // Track seen options in a first pass. We use 2 different data structures - // (seen and counts) because this code is in the critical path and - // having more than one instance of an option is a very rare case. - - // Record if an option was already seen using the most efficient - // data structure for this goal. - vector<bool> seen(256, false); - // Handle the very rare case where an option is more than once in the - // input buffer, in other / common case it stays empty. - unordered_map<uint8_t, size_t> counts; + // Track seen options in a first pass. + vector<uint32_t> count(256, 0); while (offset < buf.size()) { // Get the option type uint8_t opt_type = buf[offset++]; @@ -533,24 +525,13 @@ LibDHCP::unpackOptions4(const OptionBuffer& buf, const string& option_space, offset += opt_len; - // Mark as seen. - if (!seen[opt_type]) { - seen[opt_type] = true; - continue; - } - - // Already seen. - size_t& count = counts[opt_type]; - if (count == 0) { - // Default value for size_t is 0 but this option was already seen. - count = 2; - } else { - ++count; - } + // Increment count. + count[opt_type] += 1; } // Fusing option buffers. unordered_map<uint8_t, OptionBuffer> fused; + unordered_map<uint8_t, uint32_t> seen; // Second pass. offset = 0; @@ -612,16 +593,17 @@ LibDHCP::unpackOptions4(const OptionBuffer& buf, const string& option_space, offset += opt_len; // Concatenate multiple instance of an option. - if (!counts.empty() && (counts.count(opt_type) > 0)) { - size_t count = counts[opt_type]; + uint32_t opt_count = count[opt_type]; + if (opt_count > 1) { OptionBuffer& previous = fused[opt_type]; previous.insert(previous.end(), obuf.begin(), obuf.end()); - if (count <= 1) { + uint32_t& already_seen = seen[opt_type]; + ++already_seen; + if (already_seen != opt_count) { + continue; + } else { // last occurrence: build the option. obuf = previous; - } else { - counts[opt_type] = count - 1; - continue; } } diff --git a/src/lib/dhcp/tests/libdhcp++_unittest.cc b/src/lib/dhcp/tests/libdhcp++_unittest.cc index f292643014..0d275ec450 100644 --- a/src/lib/dhcp/tests/libdhcp++_unittest.cc +++ b/src/lib/dhcp/tests/libdhcp++_unittest.cc @@ -1358,7 +1358,7 @@ TEST_F(LibDhcpTest, splitOptionWithSuboptionWhichOverflow) { RAI_OPTION_SUBSCRIBER_ID, buf_in.begin(), buf_in.end())); - ASSERT_TRUE(subscriber_id_opt); +ASSERT_TRUE(subscriber_id_opt); rai->addOption(subscriber_id_opt); splitOptionWithSuboptionWhichOverflow(rai, circuit_id_opt, remote_id_opt, subscriber_id_opt); |