Skip to content

Commit

Permalink
Do not shrink on remove()
Browse files Browse the repository at this point in the history
This is in line with Qt 5 behavior, how std::vector works and also
how QString and QByteArray behave. If you need the shrink allocated
storage, call squeeze() manually.

Change-Id: I16cadd4f2a89bb2ec5de02fe69186f5da321cd06
Reviewed-by: Paul Wicking <[email protected]>
Reviewed-by: Thiago Macieira <[email protected]>
  • Loading branch information
laknoll authored and andrey-golubev committed Nov 9, 2020
1 parent f438286 commit 2768270
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 35 deletions.
7 changes: 3 additions & 4 deletions src/corelib/doc/src/qt6-changes.qdoc
Original file line number Diff line number Diff line change
Expand Up @@ -161,10 +161,9 @@
\section3 Stability of References

There are several changes made to the QVector/QList implementation. The
QVector related ones are: insertion at the beginning is optimized (similarly
to QList in Qt 5) and element removal can reallocate in order to remove the
unused capacity. The QList related one is: memory layout for the elements is
simplified.
QVector related one is: insertion at the beginning is optimized (similarly
to QList in Qt 5). The QList related one is: memory layout for the elements
is simplified.

\important These changes impact the stability of references. In Qt 6, you
should consider any size or capacity modifying method to invalidate all
Expand Down
21 changes: 5 additions & 16 deletions src/corelib/tools/qlist.h
Original file line number Diff line number Diff line change
Expand Up @@ -639,22 +639,11 @@ inline void QList<T>::remove(qsizetype i, qsizetype n)
if (n == 0)
return;

const auto newSize = size() - n;
if (d->needsDetach() ||
((d->flags() & Data::CapacityReserved) == 0
&& newSize < d->allocatedCapacity()/2)) {
// allocate memory
DataPointer detached(Data::allocate(d->detachCapacity(newSize)));
const_iterator where = constBegin() + i;
if (newSize) {
detached->copyAppend(constBegin(), where);
detached->copyAppend(where + n, constEnd());
}
d.swap(detached);
} else {
// we're detached and we can just move data around
d->erase(d->begin() + i, d->begin() + i + n);
}
if (d->needsDetach())
d.detach();

d->erase(d->begin() + i, d->begin() + i + n);
}

template <typename T>
inline void QList<T>::removeFirst()
Expand Down
20 changes: 5 additions & 15 deletions src/corelib/tools/qlist.qdoc
Original file line number Diff line number Diff line change
Expand Up @@ -501,11 +501,6 @@
may have used more memory than the normal QList growth strategy
would have allocated—or you may have used less.

\note Calling reserve() changes the growth strategy of QList to the one that
avoids unnecessary reallocations. This may give worse performance when \a
size is underestimated. To restore automatic growth strategy, call
squeeze().

\warning reserve() reserves memory but does not change the size of the list.
Accessing data beyond the end of the list is undefined behavior.

Expand Down Expand Up @@ -799,19 +794,14 @@
Removes \a n elements from the list, starting at index position \a i.

//! [shrinking-erase]
Element removal may cause the list to shrink the capacity to reduce the
allocated memory size. The automatic shrinking only happens when the new
size is below some threshold (e.g. half of the capacity). This means that,
for large lists, removing a couple of elements often won't cause any side
effects. To make sure shrinking does not happen at all, use reserve()
beforehand to give a hint to the QList that the capacity should be
preserved.
Element removal will preserve the list's capacity and not reduce the amount of
allocated memory. To shed extra capacity and free as much memory as possible,
call squeeze().
//! [shrinking-erase]

//! [iterator-invalidation-erase]
\note When QList is not \l{implicitly shared} and the capacity is reserved
with a call to reserve(), this function only invalidates iterators at or
after the specified position.
\note When QList is not \l{implicitly shared}, this function only
invalidates iterators at or after the specified position.
//! [iterator-invalidation-erase]

\sa insert(), replace(), fill()
Expand Down

0 comments on commit 2768270

Please sign in to comment.