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
Thorbjørn Martsum 2013-08-07 08:15:58 +02:00 committed by The Qt Project
parent 592c8bffd6
commit f633bc7f7f
3 changed files with 18 additions and 13 deletions

View File

@ -80,6 +80,7 @@ QDataStream &operator>>(QDataStream &in, QHeaderViewPrivate::SectionItem &sectio
}
#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)

View File

@ -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
};

View File

@ -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)