@@ -485,16 +485,8 @@ LibDHCP::unpackOptions4(const OptionBuffer& buf, const string& option_space,
485
485
// The buffer being read comprises a set of options, each starting with
486
486
// a one-byte type code and a one-byte length field.
487
487
488
- // Track seen options in a first pass. We use 2 different data structures
489
- // (seen and counts) because this code is in the critical path and
490
- // having more than one instance of an option is a very rare case.
491
-
492
- // Record if an option was already seen using the most efficient
493
- // data structure for this goal.
494
- vector<bool > seen (256 , false );
495
- // Handle the very rare case where an option is more than once in the
496
- // input buffer, in other / common case it stays empty.
497
- unordered_map<uint8_t , size_t > counts;
488
+ // Track seen options in a first pass.
489
+ vector<uint32_t > count (256 , 0 );
498
490
while (offset < buf.size ()) {
499
491
// Get the option type
500
492
uint8_t opt_type = buf[offset++];
@@ -533,24 +525,13 @@ LibDHCP::unpackOptions4(const OptionBuffer& buf, const string& option_space,
533
525
534
526
offset += opt_len;
535
527
536
- // Mark as seen.
537
- if (!seen[opt_type]) {
538
- seen[opt_type] = true ;
539
- continue ;
540
- }
541
-
542
- // Already seen.
543
- size_t & count = counts[opt_type];
544
- if (count == 0 ) {
545
- // Default value for size_t is 0 but this option was already seen.
546
- count = 2 ;
547
- } else {
548
- ++count;
549
- }
528
+ // Increment count.
529
+ count[opt_type] += 1 ;
550
530
}
551
531
552
532
// Fusing option buffers.
553
533
unordered_map<uint8_t , OptionBuffer> fused;
534
+ unordered_map<uint8_t , uint32_t > seen;
554
535
555
536
// Second pass.
556
537
offset = 0 ;
@@ -612,16 +593,17 @@ LibDHCP::unpackOptions4(const OptionBuffer& buf, const string& option_space,
612
593
offset += opt_len;
613
594
614
595
// Concatenate multiple instance of an option.
615
- if (!counts. empty () && (counts. count ( opt_type) > 0 )) {
616
- size_t count = counts[opt_type];
596
+ uint32_t opt_count = count[ opt_type];
597
+ if (opt_count > 1 ) {
617
598
OptionBuffer& previous = fused[opt_type];
618
599
previous.insert (previous.end (), obuf.begin (), obuf.end ());
619
- if (count <= 1 ) {
600
+ uint32_t & already_seen = seen[opt_type];
601
+ ++already_seen;
602
+ if (already_seen != opt_count) {
603
+ continue ;
604
+ } else {
620
605
// last occurrence: build the option.
621
606
obuf = previous;
622
- } else {
623
- counts[opt_type] = count - 1 ;
624
- continue ;
625
607
}
626
608
}
627
609
0 commit comments