diff options
author | Thorbjørn Martsum <tmartsum@gmail.com> | 2013-08-07 08:15:58 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-08-16 05:34:18 +0200 |
commit | f633bc7f7fb72ba261b46e979603376f0016c085 (patch) | |
tree | b8e6aef18069d144052cb6c8151c80ba531d0102 | |
parent | 592c8bffd6afd485063e9339e0707829884180ac (diff) |
QHeaderView - reduce memory usage
Though the worst case memory usage was improved in
b800d8b94a7861ecf8853621f6556fca186fb5b7 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>
-rw-r--r-- | src/widgets/itemviews/qheaderview.cpp | 9 | ||||
-rw-r--r-- | src/widgets/itemviews/qheaderview_p.h | 14 | ||||
-rw-r--r-- | tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp | 8 |
3 files changed, 18 insertions, 13 deletions
diff --git a/src/widgets/itemviews/qheaderview.cpp b/src/widgets/itemviews/qheaderview.cpp index c9a845fc7b..e0034d1298 100644 --- a/src/widgets/itemviews/qheaderview.cpp +++ b/src/widgets/itemviews/qheaderview.cpp @@ -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) diff --git a/src/widgets/itemviews/qheaderview_p.h b/src/widgets/itemviews/qheaderview_p.h index c56e0d6196..2bbd21a942 100644 --- a/src/widgets/itemviews/qheaderview_p.h +++ b/src/widgets/itemviews/qheaderview_p.h @@ -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 }; diff --git a/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp b/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp index fa67e16db9..ba3a150154 100644 --- a/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp +++ b/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp @@ -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) |