QHeaderView - reduce memory usage
Though the worst case memory usage was improved in
b800d8b94a the best case usage changed.
Since best case is the same as worst case in Qt5, we should
use as little as possible, which this patch ensures.
We reduce the memory usage from 3 to 2 ints per section - which is
half of worst case in Qt4. There seems to be no bigger cost in
performance doing that. The recalcSectionStartPos is still very fast.
This patch limits the maximum section size to (2^20) ~ 1.000.000 pixels.
This alleviates
Task-number: QTBUG-32325
Change-Id: I9b7530030a31b4e35cf1ca9e32c6b936f5ea9790
Reviewed-by: Stephen Kelly <stephen.kelly@kdab.com>
bb10
parent
592c8bffd6
commit
f633bc7f7f
|
|
@ -80,6 +80,7 @@ QDataStream &operator>>(QDataStream &in, QHeaderViewPrivate::SectionItem §io
|
|||
}
|
||||
#endif // QT_NO_DATASTREAM
|
||||
|
||||
static const int maxSizeSection = 1048575; // since section size is in a bitfield (uint 20). See qheaderview_p.h
|
||||
|
||||
/*!
|
||||
\class QHeaderView
|
||||
|
|
@ -884,7 +885,7 @@ void QHeaderView::swapSections(int first, int second)
|
|||
void QHeaderView::resizeSection(int logical, int size)
|
||||
{
|
||||
Q_D(QHeaderView);
|
||||
if (logical < 0 || logical >= count() || size < 0)
|
||||
if (logical < 0 || logical >= count() || size < 0 || size > maxSizeSection)
|
||||
return;
|
||||
|
||||
if (isSectionHidden(logical)) {
|
||||
|
|
@ -1567,7 +1568,7 @@ int QHeaderView::defaultSectionSize() const
|
|||
void QHeaderView::setDefaultSectionSize(int size)
|
||||
{
|
||||
Q_D(QHeaderView);
|
||||
if (size < 0)
|
||||
if (size < 0 || size > maxSizeSection)
|
||||
return;
|
||||
d->setDefaultSectionSize(size);
|
||||
}
|
||||
|
|
@ -1602,7 +1603,7 @@ int QHeaderView::minimumSectionSize() const
|
|||
void QHeaderView::setMinimumSectionSize(int size)
|
||||
{
|
||||
Q_D(QHeaderView);
|
||||
if (size < 0)
|
||||
if (size < 0 || size > maxSizeSection)
|
||||
return;
|
||||
d->minimumSectionSize = size;
|
||||
}
|
||||
|
|
@ -3549,7 +3550,7 @@ QHeaderView::ResizeMode QHeaderViewPrivate::headerSectionResizeMode(int visual)
|
|||
{
|
||||
if (visual < 0 || visual >= sectionItems.count())
|
||||
return globalResizeMode;
|
||||
return sectionItems.at(visual).resizeMode;
|
||||
return static_cast<QHeaderView::ResizeMode>(sectionItems.at(visual).resizeMode);
|
||||
}
|
||||
|
||||
void QHeaderViewPrivate::setGlobalHeaderResizeMode(QHeaderView::ResizeMode mode)
|
||||
|
|
|
|||
|
|
@ -296,23 +296,27 @@ public:
|
|||
// header sections
|
||||
|
||||
struct SectionItem {
|
||||
int size;
|
||||
uint size : 20;
|
||||
uint reservedForIsHidden : 1;
|
||||
uint resizeMode : 5; // (holding QHeaderView::ResizeMode)
|
||||
uint currentlyUnusedPadding : 6;
|
||||
|
||||
union { // This union is made in order to save space and ensure good vector performance (on remove)
|
||||
mutable int calculated_startpos; // <- this is the primary used member.
|
||||
mutable int tmpLogIdx; // When one of these 'tmp'-members has been used we call
|
||||
int tmpDataStreamSectionCount; // recalcSectionStartPos() or set sectionStartposRecalc to true
|
||||
}; // to ensure that calculated_startpos will be calculated afterwards.
|
||||
QHeaderView::ResizeMode resizeMode;
|
||||
|
||||
inline SectionItem() : size(0), resizeMode(QHeaderView::Interactive) {}
|
||||
inline SectionItem(int length, QHeaderView::ResizeMode mode)
|
||||
: size(length), calculated_startpos(-1), resizeMode(mode) {}
|
||||
: size(length), resizeMode(mode), calculated_startpos(-1) {}
|
||||
inline int sectionSize() const { return size; }
|
||||
inline int calculatedEndPos() const { return calculated_startpos + size; }
|
||||
#ifndef QT_NO_DATASTREAM
|
||||
inline void write(QDataStream &out) const
|
||||
{ out << size; out << 1; out << (int)resizeMode; }
|
||||
{ out << static_cast<int>(size); out << 1; out << (int)resizeMode; }
|
||||
inline void read(QDataStream &in)
|
||||
{ in >> size; in >> tmpDataStreamSectionCount; int m; in >> m; resizeMode = (QHeaderView::ResizeMode)m; }
|
||||
{ int m; in >> m; size = m; in >> tmpDataStreamSectionCount; in >> m; resizeMode = m; }
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -341,8 +341,8 @@ void tst_QHeaderView::getSetCheck()
|
|||
QVERIFY(obj1.defaultSectionSize() >= 0);
|
||||
obj1.setDefaultSectionSize(0);
|
||||
QCOMPARE(0, obj1.defaultSectionSize());
|
||||
obj1.setDefaultSectionSize(INT_MAX);
|
||||
QCOMPARE(INT_MAX, obj1.defaultSectionSize());
|
||||
obj1.setDefaultSectionSize(99999);
|
||||
QCOMPARE(99999, obj1.defaultSectionSize());
|
||||
|
||||
// int QHeaderView::minimumSectionSize()
|
||||
// void QHeaderView::setMinimumSectionSize(int)
|
||||
|
|
@ -350,8 +350,8 @@ void tst_QHeaderView::getSetCheck()
|
|||
QVERIFY(obj1.minimumSectionSize() >= 0);
|
||||
obj1.setMinimumSectionSize(0);
|
||||
QCOMPARE(0, obj1.minimumSectionSize());
|
||||
obj1.setMinimumSectionSize(INT_MAX);
|
||||
QCOMPARE(INT_MAX, obj1.minimumSectionSize());
|
||||
obj1.setMinimumSectionSize(99999);
|
||||
QCOMPARE(99999, obj1.minimumSectionSize());
|
||||
|
||||
// int QHeaderView::offset()
|
||||
// void QHeaderView::setOffset(int)
|
||||
|
|
|
|||
Loading…
Reference in New Issue