@@ -1601,6 +1601,10 @@ std::pair<ExtensionSet::Extension*, bool> ExtensionSet::Insert(int key) {
1601
1601
return Insert (key);
1602
1602
}
1603
1603
1604
+ namespace {
1605
+ constexpr bool IsPowerOfTwo (size_t n) { return (n & (n - 1 )) == 0 ; }
1606
+ } // namespace
1607
+
1604
1608
void ExtensionSet::GrowCapacity (size_t minimum_new_capacity) {
1605
1609
if (PROTOBUF_PREDICT_FALSE (is_large ())) {
1606
1610
return ; // LargeMap does not have a "reserve" method.
@@ -1614,8 +1618,8 @@ void ExtensionSet::GrowCapacity(size_t minimum_new_capacity) {
1614
1618
new_flat_capacity = new_flat_capacity == 0 ? 1 : new_flat_capacity * 4 ;
1615
1619
} while (new_flat_capacity < minimum_new_capacity);
1616
1620
1617
- const KeyValue* begin = flat_begin ();
1618
- const KeyValue* end = flat_end ();
1621
+ KeyValue* begin = flat_begin ();
1622
+ KeyValue* end = flat_end ();
1619
1623
AllocatedData new_map;
1620
1624
Arena* const arena = arena_;
1621
1625
if (new_flat_capacity > kMaximumFlatCapacity ) {
@@ -1631,8 +1635,18 @@ void ExtensionSet::GrowCapacity(size_t minimum_new_capacity) {
1631
1635
std::copy (begin, end, new_map.flat );
1632
1636
}
1633
1637
1634
- if (arena == nullptr ) {
1635
- DeleteFlatMap (begin, flat_capacity_);
1638
+ // ReturnArrayMemory is more efficient with power-of-2 bytes, and
1639
+ // sizeof(KeyValue) is a power-of-2 on 64-bit platforms. flat_capacity_ is
1640
+ // always a power-of-2.
1641
+ ABSL_DCHECK (IsPowerOfTwo (sizeof (KeyValue)) || sizeof (void *) != 8 )
1642
+ << sizeof (KeyValue) << " " << sizeof (void *);
1643
+ ABSL_DCHECK (IsPowerOfTwo (flat_capacity_));
1644
+ if (flat_capacity_ > 0 ) {
1645
+ if (arena == nullptr ) {
1646
+ DeleteFlatMap (begin, flat_capacity_);
1647
+ } else {
1648
+ arena->ReturnArrayMemory (begin, sizeof (KeyValue) * flat_capacity_);
1649
+ }
1636
1650
}
1637
1651
flat_capacity_ = new_flat_capacity;
1638
1652
map_ = new_map;
0 commit comments