From 74be42ca598c4f13486191c0b8c58bee3d1f1090 Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Tue, 24 Apr 2018 17:06:49 +0200 Subject: [PATCH] ItemModels: Cache last-known child index Instead of caching the last index of a search for a child item, cache the index of the child in the child item. When the item model is not changed, the index is valid. Otherwise, the index can only change when items get inserted or removed before the child. So in that case, start searching in the vicinity of the previously known index. As an example: a selectAll() on the view will always hit the cached index, so no search is performed for any item in the model/view. Task-number: QTBUG-61368 Change-Id: I85d085299987237fae23451d9e8bbb6060464ef2 Reviewed-by: David Faure --- src/gui/itemmodels/qstandarditemmodel.cpp | 8 +++++++ src/gui/itemmodels/qstandarditemmodel_p.h | 28 ++++++++++++++--------- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/src/gui/itemmodels/qstandarditemmodel.cpp b/src/gui/itemmodels/qstandarditemmodel.cpp index f55e90c153..235bc5bd7d 100644 --- a/src/gui/itemmodels/qstandarditemmodel.cpp +++ b/src/gui/itemmodels/qstandarditemmodel.cpp @@ -142,6 +142,8 @@ void QStandardItemPrivate::setChild(int row, int column, QStandardItem *item, oldItem->d_func()->setModel(0); delete oldItem; children.replace(index, item); + if (item) + item->d_func()->lastKnownIndex = index; if (model && emitChanged) emit model->layoutChanged(); @@ -475,6 +477,8 @@ bool QStandardItemPrivate::insertRows(int row, const QList &item item->d_func()->parent = q; int index = childIndex(i + row, 0); children.replace(index, item); + if (item) + item->d_func()->lastKnownIndex = index; } if (model) model->d_func()->rowsInserted(q, row, count); @@ -512,6 +516,8 @@ bool QStandardItemPrivate::insertRows(int row, int count, const QListd_func()->lastKnownIndex = index; ++index; } } @@ -558,6 +564,8 @@ bool QStandardItemPrivate::insertColumns(int column, int count, const QListd_func()->lastKnownIndex = index; } } if (model) diff --git a/src/gui/itemmodels/qstandarditemmodel_p.h b/src/gui/itemmodels/qstandarditemmodel_p.h index 4589a62223..00e83f7b08 100644 --- a/src/gui/itemmodels/qstandarditemmodel_p.h +++ b/src/gui/itemmodels/qstandarditemmodel_p.h @@ -114,7 +114,7 @@ public: rows(0), columns(0), q_ptr(0), - lastIndexOf(-1) + lastKnownIndex(-1) { } inline int childIndex(int row, int column) const { @@ -126,32 +126,38 @@ public: } inline int childIndex(const QStandardItem *child) const { const int lastChild = children.size() - 1; - if (lastIndexOf == -1) - lastIndexOf = lastChild / 2; - // assuming the item is in the vicinity of the last search, iterate forwards and + int &childsLastIndexInParent = child->d_func()->lastKnownIndex; + if (childsLastIndexInParent != -1 && childsLastIndexInParent <= lastChild) { + if (children.at(childsLastIndexInParent) == child) + return childsLastIndexInParent; + } else { + childsLastIndexInParent = lastChild / 2; + } + + // assuming the item is in the vicinity of the previous index, iterate forwards and // backwards through the children - int backwardIter = lastIndexOf - 1; - int forwardIter = lastIndexOf; + int backwardIter = childsLastIndexInParent - 1; + int forwardIter = childsLastIndexInParent; Q_FOREVER { if (forwardIter <= lastChild) { if (children.at(forwardIter) == child) { - lastIndexOf = forwardIter; + childsLastIndexInParent = forwardIter; break; } ++forwardIter; } else if (backwardIter < 0) { - lastIndexOf = -1; + childsLastIndexInParent = -1; break; } if (backwardIter >= 0) { if (children.at(backwardIter) == child) { - lastIndexOf = backwardIter; + childsLastIndexInParent = backwardIter; break; } --backwardIter; } } - return lastIndexOf; + return childsLastIndexInParent; } QPair position() const; void setChild(int row, int column, QStandardItem *item, @@ -192,7 +198,7 @@ public: QStandardItem *q_ptr; - mutable int lastIndexOf; + mutable int lastKnownIndex; // this is a cached value }; class QStandardItemModelPrivate : public QAbstractItemModelPrivate