Skip to content

Commit 020619c

Browse files
Abseil Teamsuertreus
authored andcommitted
Export of internal Abseil changes
-- 336f161ad8cb2cc3e1a6bbcbbb8c5b692ee59789 by Derek Mauro <[email protected]>: Internal change PiperOrigin-RevId: 398308807 -- 80d512823d17561a45feca81f37713a91a175349 by Abseil Team <[email protected]>: Internal change. PiperOrigin-RevId: 398257218 -- f1f9792000355eb1d0c11b17800048491662a218 by Abseil Team <[email protected]>: Fix documentation for btree_multi{map,set}::merge to match behavior for elements with equivalent keys. PiperOrigin-RevId: 398071060 -- 8a9a302aebf2419e83f0c7dc5a63c33d26b807a3 by James Y Knight <[email protected]>: Silence -Wunused-value warning newly emitted by ToT Clang. The value is being intentionally ignored, as the purpose of the call is only to eliminate this overload via SFINAE when `GenT{}` is not constant evaluable. PiperOrigin-RevId: 397861294 GitOrigin-RevId: 336f161ad8cb2cc3e1a6bbcbbb8c5b692ee59789 Change-Id: I946e1d22619f92ce6a424c8c13a20a50b39ed463
1 parent d4af654 commit 020619c

File tree

6 files changed

+110
-68
lines changed

6 files changed

+110
-68
lines changed

absl/container/btree_map.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -693,9 +693,8 @@ class btree_multimap
693693

694694
// btree_multimap::merge()
695695
//
696-
// Extracts elements from a given `source` btree_multimap into this
697-
// `btree_multimap`. If the destination `btree_multimap` already contains an
698-
// element with an equivalent key, that element is not extracted.
696+
// Extracts all elements from a given `source` btree_multimap into this
697+
// `btree_multimap`.
699698
using Base::merge;
700699

701700
// btree_multimap::swap(btree_multimap& other)

absl/container/btree_set.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -604,9 +604,8 @@ class btree_multiset
604604

605605
// btree_multiset::merge()
606606
//
607-
// Extracts elements from a given `source` btree_multiset into this
608-
// `btree_multiset`. If the destination `btree_multiset` already contains an
609-
// element with an equivalent key, that element is not extracted.
607+
// Extracts all elements from a given `source` btree_multiset into this
608+
// `btree_multiset`.
610609
using Base::merge;
611610

612611
// btree_multiset::swap(btree_multiset& other)

absl/container/inlined_vector.h

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -207,8 +207,8 @@ class InlinedVector {
207207

208208
other.storage_.SetInlinedSize(0);
209209
} else if (other.storage_.GetIsAllocated()) {
210-
storage_.SetAllocatedData(other.storage_.GetAllocatedData(),
211-
other.storage_.GetAllocatedCapacity());
210+
storage_.SetAllocation({other.storage_.GetAllocatedData(),
211+
other.storage_.GetAllocatedCapacity()});
212212
storage_.SetAllocatedSize(other.storage_.GetSize());
213213

214214
other.storage_.SetInlinedSize(0);
@@ -242,8 +242,8 @@ class InlinedVector {
242242
other.storage_.SetInlinedSize(0);
243243
} else if ((storage_.GetAllocator() == other.storage_.GetAllocator()) &&
244244
other.storage_.GetIsAllocated()) {
245-
storage_.SetAllocatedData(other.storage_.GetAllocatedData(),
246-
other.storage_.GetAllocatedCapacity());
245+
storage_.SetAllocation({other.storage_.GetAllocatedData(),
246+
other.storage_.GetAllocatedCapacity()});
247247
storage_.SetAllocatedSize(other.storage_.GetSize());
248248

249249
other.storage_.SetInlinedSize(0);
@@ -735,15 +735,12 @@ class InlinedVector {
735735

736736
// `InlinedVector::shrink_to_fit()`
737737
//
738-
// Reduces memory usage by freeing unused memory. After being called, calls to
739-
// `capacity()` will be equal to `max(N, size())`.
738+
// Attempts to reduce memory usage by moving elements to (or keeping elements
739+
// in) the smallest available buffer sufficient for containing `size()`
740+
// elements.
740741
//
741-
// If `size() <= N` and the inlined vector contains allocated memory, the
742-
// elements will all be moved to the inlined space and the allocated memory
743-
// will be deallocated.
744-
//
745-
// If `size() > N` and `size() < capacity()`, the elements will be moved to a
746-
// smaller allocation.
742+
// If `size()` is sufficiently small, the elements will be moved into (or kept
743+
// in) the inlined space.
747744
void shrink_to_fit() {
748745
if (storage_.GetIsAllocated()) {
749746
storage_.ShrinkToFit();

absl/container/internal/inlined_vector.h

Lines changed: 87 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,11 @@
2121
#include <iterator>
2222
#include <limits>
2323
#include <memory>
24+
#include <new>
25+
#include <type_traits>
2426
#include <utility>
2527

28+
#include "absl/base/attributes.h"
2629
#include "absl/base/macros.h"
2730
#include "absl/container/internal/compressed_tuple.h"
2831
#include "absl/memory/memory.h"
@@ -102,6 +105,27 @@ void DestroyElements(NoTypeDeduction<A>& allocator, Pointer<A> destroy_first,
102105
}
103106
}
104107

108+
template <typename A>
109+
struct Allocation {
110+
Pointer<A> data;
111+
SizeType<A> capacity;
112+
};
113+
114+
template <typename A,
115+
bool IsOverAligned =
116+
(alignof(ValueType<A>) > ABSL_INTERNAL_DEFAULT_NEW_ALIGNMENT)>
117+
struct MallocAdapter {
118+
static Allocation<A> Allocate(A& allocator, SizeType<A> requested_capacity) {
119+
return {AllocatorTraits<A>::allocate(allocator, requested_capacity),
120+
requested_capacity};
121+
}
122+
123+
static void Deallocate(A& allocator, Pointer<A> pointer,
124+
SizeType<A> capacity) {
125+
AllocatorTraits<A>::deallocate(allocator, pointer, capacity);
126+
}
127+
};
128+
105129
// If kUseMemcpy is true, memcpy(dst, src, n); else do nothing.
106130
// Useful to avoid compiler warnings when memcpy() is used for T values
107131
// that are not trivially copyable in non-reachable code.
@@ -201,7 +225,7 @@ class AllocationTransaction {
201225

202226
~AllocationTransaction() {
203227
if (DidAllocate()) {
204-
AllocatorTraits<A>::deallocate(GetAllocator(), GetData(), GetCapacity());
228+
MallocAdapter<A>::Deallocate(GetAllocator(), GetData(), GetCapacity());
205229
}
206230
}
207231

@@ -213,18 +237,27 @@ class AllocationTransaction {
213237
SizeType<A>& GetCapacity() { return capacity_; }
214238

215239
bool DidAllocate() { return GetData() != nullptr; }
216-
Pointer<A> Allocate(SizeType<A> capacity) {
217-
GetData() = AllocatorTraits<A>::allocate(GetAllocator(), capacity);
218-
GetCapacity() = capacity;
219-
return GetData();
240+
241+
Pointer<A> Allocate(SizeType<A> requested_capacity) {
242+
Allocation<A> result =
243+
MallocAdapter<A>::Allocate(GetAllocator(), requested_capacity);
244+
GetData() = result.data;
245+
GetCapacity() = result.capacity;
246+
return result.data;
247+
}
248+
249+
ABSL_MUST_USE_RESULT Allocation<A> Release() && {
250+
Allocation<A> result = {GetData(), GetCapacity()};
251+
Reset();
252+
return result;
220253
}
221254

255+
private:
222256
void Reset() {
223257
GetData() = nullptr;
224258
GetCapacity() = 0;
225259
}
226260

227-
private:
228261
container_internal::CompressedTuple<A, Pointer<A>> allocator_data_;
229262
SizeType<A> capacity_;
230263
};
@@ -405,15 +438,9 @@ class Storage {
405438
GetSizeAndIsAllocated() -= count << static_cast<SizeType<A>>(1);
406439
}
407440

408-
void SetAllocatedData(Pointer<A> data, SizeType<A> capacity) {
409-
data_.allocated.allocated_data = data;
410-
data_.allocated.allocated_capacity = capacity;
411-
}
412-
413-
void AcquireAllocatedData(AllocationTransaction<A>& allocation_tx) {
414-
SetAllocatedData(allocation_tx.GetData(), allocation_tx.GetCapacity());
415-
416-
allocation_tx.Reset();
441+
void SetAllocation(Allocation<A> allocation) {
442+
data_.allocated.allocated_data = allocation.data;
443+
data_.allocated.allocated_capacity = allocation.capacity;
417444
}
418445

419446
void MemcpyFrom(const Storage& other_storage) {
@@ -425,8 +452,8 @@ class Storage {
425452

426453
void DeallocateIfAllocated() {
427454
if (GetIsAllocated()) {
428-
AllocatorTraits<A>::deallocate(GetAllocator(), GetAllocatedData(),
429-
GetAllocatedCapacity());
455+
MallocAdapter<A>::Deallocate(GetAllocator(), GetAllocatedData(),
456+
GetAllocatedCapacity());
430457
}
431458
}
432459

@@ -476,9 +503,11 @@ void Storage<T, N, A>::InitFrom(const Storage& other) {
476503
// Because this is only called from the `InlinedVector` constructors, it's
477504
// safe to take on the allocation with size `0`. If `ConstructElements(...)`
478505
// throws, deallocation will be automatically handled by `~Storage()`.
479-
SizeType<A> new_capacity = ComputeCapacity(GetInlinedCapacity(), n);
480-
dst = AllocatorTraits<A>::allocate(GetAllocator(), new_capacity);
481-
SetAllocatedData(dst, new_capacity);
506+
SizeType<A> requested_capacity = ComputeCapacity(GetInlinedCapacity(), n);
507+
Allocation<A> allocation =
508+
MallocAdapter<A>::Allocate(GetAllocator(), requested_capacity);
509+
SetAllocation(allocation);
510+
dst = allocation.data;
482511
src = other.GetAllocatedData();
483512
}
484513
if (IsMemcpyOk<A>::value) {
@@ -503,9 +532,12 @@ auto Storage<T, N, A>::Initialize(ValueAdapter values, SizeType<A> new_size)
503532
// Because this is only called from the `InlinedVector` constructors, it's
504533
// safe to take on the allocation with size `0`. If `ConstructElements(...)`
505534
// throws, deallocation will be automatically handled by `~Storage()`.
506-
SizeType<A> new_capacity = ComputeCapacity(GetInlinedCapacity(), new_size);
507-
construct_data = AllocatorTraits<A>::allocate(GetAllocator(), new_capacity);
508-
SetAllocatedData(construct_data, new_capacity);
535+
SizeType<A> requested_capacity =
536+
ComputeCapacity(GetInlinedCapacity(), new_size);
537+
Allocation<A> allocation =
538+
MallocAdapter<A>::Allocate(GetAllocator(), requested_capacity);
539+
construct_data = allocation.data;
540+
SetAllocation(allocation);
509541
SetIsAllocated();
510542
} else {
511543
construct_data = GetInlinedData();
@@ -532,8 +564,9 @@ auto Storage<T, N, A>::Assign(ValueAdapter values, SizeType<A> new_size)
532564
absl::Span<ValueType<A>> destroy_loop;
533565

534566
if (new_size > storage_view.capacity) {
535-
SizeType<A> new_capacity = ComputeCapacity(storage_view.capacity, new_size);
536-
construct_loop = {allocation_tx.Allocate(new_capacity), new_size};
567+
SizeType<A> requested_capacity =
568+
ComputeCapacity(storage_view.capacity, new_size);
569+
construct_loop = {allocation_tx.Allocate(requested_capacity), new_size};
537570
destroy_loop = {storage_view.data, storage_view.size};
538571
} else if (new_size > storage_view.size) {
539572
assign_loop = {storage_view.data, storage_view.size};
@@ -553,7 +586,7 @@ auto Storage<T, N, A>::Assign(ValueAdapter values, SizeType<A> new_size)
553586

554587
if (allocation_tx.DidAllocate()) {
555588
DeallocateIfAllocated();
556-
AcquireAllocatedData(allocation_tx);
589+
SetAllocation(std::move(allocation_tx).Release());
557590
SetIsAllocated();
558591
}
559592

@@ -583,8 +616,9 @@ auto Storage<T, N, A>::Resize(ValueAdapter values, SizeType<A> new_size)
583616
// Use transactional wrappers for the first two steps so we can roll
584617
// back if necessary due to exceptions.
585618
AllocationTransaction<A> allocation_tx(alloc);
586-
SizeType<A> new_capacity = ComputeCapacity(storage_view.capacity, new_size);
587-
Pointer<A> new_data = allocation_tx.Allocate(new_capacity);
619+
SizeType<A> requested_capacity =
620+
ComputeCapacity(storage_view.capacity, new_size);
621+
Pointer<A> new_data = allocation_tx.Allocate(requested_capacity);
588622

589623
ConstructionTransaction<A> construction_tx(alloc);
590624
construction_tx.Construct(new_data + size, values, new_size - size);
@@ -596,7 +630,7 @@ auto Storage<T, N, A>::Resize(ValueAdapter values, SizeType<A> new_size)
596630
DestroyElements<A>(alloc, base, size);
597631
construction_tx.Commit();
598632
DeallocateIfAllocated();
599-
AcquireAllocatedData(allocation_tx);
633+
SetAllocation(std::move(allocation_tx).Release());
600634
SetIsAllocated();
601635
}
602636
SetSize(new_size);
@@ -621,8 +655,9 @@ auto Storage<T, N, A>::Insert(ConstIterator<A> pos, ValueAdapter values,
621655
IteratorValueAdapter<A, MoveIterator<A>> move_values(
622656
MoveIterator<A>(storage_view.data));
623657

624-
SizeType<A> new_capacity = ComputeCapacity(storage_view.capacity, new_size);
625-
Pointer<A> new_data = allocation_tx.Allocate(new_capacity);
658+
SizeType<A> requested_capacity =
659+
ComputeCapacity(storage_view.capacity, new_size);
660+
Pointer<A> new_data = allocation_tx.Allocate(requested_capacity);
626661

627662
construction_tx.Construct(new_data + insert_index, values, insert_count);
628663

@@ -636,7 +671,7 @@ auto Storage<T, N, A>::Insert(ConstIterator<A> pos, ValueAdapter values,
636671
construction_tx.Commit();
637672
move_construction_tx.Commit();
638673
DeallocateIfAllocated();
639-
AcquireAllocatedData(allocation_tx);
674+
SetAllocation(std::move(allocation_tx).Release());
640675

641676
SetAllocatedSize(new_size);
642677
return Iterator<A>(new_data + insert_index);
@@ -717,8 +752,8 @@ auto Storage<T, N, A>::EmplaceBackSlow(Args&&... args) -> Reference<A> {
717752
AllocationTransaction<A> allocation_tx(GetAllocator());
718753
IteratorValueAdapter<A, MoveIterator<A>> move_values(
719754
MoveIterator<A>(storage_view.data));
720-
SizeType<A> new_capacity = NextCapacity(storage_view.capacity);
721-
Pointer<A> construct_data = allocation_tx.Allocate(new_capacity);
755+
SizeType<A> requested_capacity = NextCapacity(storage_view.capacity);
756+
Pointer<A> construct_data = allocation_tx.Allocate(requested_capacity);
722757
Pointer<A> last_ptr = construct_data + storage_view.size;
723758

724759
// Construct new element.
@@ -737,7 +772,7 @@ auto Storage<T, N, A>::EmplaceBackSlow(Args&&... args) -> Reference<A> {
737772
DestroyElements<A>(GetAllocator(), storage_view.data, storage_view.size);
738773

739774
DeallocateIfAllocated();
740-
AcquireAllocatedData(allocation_tx);
775+
SetAllocation(std::move(allocation_tx).Release());
741776
SetIsAllocated();
742777
AddSize(1);
743778
return *last_ptr;
@@ -778,17 +813,17 @@ auto Storage<T, N, A>::Reserve(SizeType<A> requested_capacity) -> void {
778813
IteratorValueAdapter<A, MoveIterator<A>> move_values(
779814
MoveIterator<A>(storage_view.data));
780815

781-
SizeType<A> new_capacity =
816+
SizeType<A> new_requested_capacity =
782817
ComputeCapacity(storage_view.capacity, requested_capacity);
783-
Pointer<A> new_data = allocation_tx.Allocate(new_capacity);
818+
Pointer<A> new_data = allocation_tx.Allocate(new_requested_capacity);
784819

785820
ConstructElements<A>(GetAllocator(), new_data, move_values,
786821
storage_view.size);
787822

788823
DestroyElements<A>(GetAllocator(), storage_view.data, storage_view.size);
789824

790825
DeallocateIfAllocated();
791-
AcquireAllocatedData(allocation_tx);
826+
SetAllocation(std::move(allocation_tx).Release());
792827
SetIsAllocated();
793828
}
794829

@@ -809,8 +844,12 @@ auto Storage<T, N, A>::ShrinkToFit() -> void {
809844

810845
Pointer<A> construct_data;
811846
if (storage_view.size > GetInlinedCapacity()) {
812-
SizeType<A> new_capacity = storage_view.size;
813-
construct_data = allocation_tx.Allocate(new_capacity);
847+
SizeType<A> requested_capacity = storage_view.size;
848+
construct_data = allocation_tx.Allocate(requested_capacity);
849+
if (allocation_tx.GetCapacity() >= storage_view.capacity) {
850+
// Already using the smallest available heap allocation.
851+
return;
852+
}
814853
} else {
815854
construct_data = GetInlinedData();
816855
}
@@ -820,17 +859,17 @@ auto Storage<T, N, A>::ShrinkToFit() -> void {
820859
storage_view.size);
821860
}
822861
ABSL_INTERNAL_CATCH_ANY {
823-
SetAllocatedData(storage_view.data, storage_view.capacity);
862+
SetAllocation({storage_view.data, storage_view.capacity});
824863
ABSL_INTERNAL_RETHROW;
825864
}
826865

827866
DestroyElements<A>(GetAllocator(), storage_view.data, storage_view.size);
828867

829-
AllocatorTraits<A>::deallocate(GetAllocator(), storage_view.data,
830-
storage_view.capacity);
868+
MallocAdapter<A>::Deallocate(GetAllocator(), storage_view.data,
869+
storage_view.capacity);
831870

832871
if (allocation_tx.DidAllocate()) {
833-
AcquireAllocatedData(allocation_tx);
872+
SetAllocation(std::move(allocation_tx).Release());
834873
} else {
835874
UnsetIsAllocated();
836875
}
@@ -881,16 +920,16 @@ auto Storage<T, N, A>::Swap(Storage* other_storage_ptr) -> void {
881920
inlined_ptr->GetSize());
882921
}
883922
ABSL_INTERNAL_CATCH_ANY {
884-
allocated_ptr->SetAllocatedData(allocated_storage_view.data,
885-
allocated_storage_view.capacity);
923+
allocated_ptr->SetAllocation(
924+
{allocated_storage_view.data, allocated_storage_view.capacity});
886925
ABSL_INTERNAL_RETHROW;
887926
}
888927

889928
DestroyElements<A>(inlined_ptr->GetAllocator(),
890929
inlined_ptr->GetInlinedData(), inlined_ptr->GetSize());
891930

892-
inlined_ptr->SetAllocatedData(allocated_storage_view.data,
893-
allocated_storage_view.capacity);
931+
inlined_ptr->SetAllocation(
932+
{allocated_storage_view.data, allocated_storage_view.capacity});
894933
}
895934

896935
swap(GetSizeAndIsAllocated(), other_storage_ptr->GetSizeAndIsAllocated());

absl/flags/internal/flag.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ constexpr T InitDefaultValue(EmptyBraces) {
290290

291291
template <typename ValueT, typename GenT,
292292
typename std::enable_if<std::is_integral<ValueT>::value, int>::type =
293-
(GenT{}, 0)>
293+
((void)GenT{}, 0)>
294294
constexpr FlagDefaultArg DefaultArg(int) {
295295
return {FlagDefaultSrc(GenT{}.value), FlagDefaultKind::kOneWord};
296296
}

0 commit comments

Comments
 (0)