+ const QUrl urlToFind = url.adjusted(QUrl::StripTrailingSlash);
+
+ const int itemCount = m_itemData.count();
+ int itemsInHash = m_items.count();
+
+ int index = m_items.value(urlToFind, -1);
+ while (index < 0 && itemsInHash < itemCount) {
+ // Not all URLs are stored yet in m_items. We grow m_items until either
+ // urlToFind is found, or all URLs have been stored in m_items.
+ // Note that we do not add the URLs to m_items one by one, but in
+ // larger blocks. After each block, we check if urlToFind is in
+ // m_items. We could in principle compare urlToFind with each URL while
+ // we are going through m_itemData, but comparing two QUrls will,
+ // unlike calling qHash for the URLs, trigger a parsing of the URLs
+ // which costs both CPU cycles and memory.
+ const int blockSize = 1000;
+ const int currentBlockEnd = qMin(itemsInHash + blockSize, itemCount);
+ for (int i = itemsInHash; i < currentBlockEnd; ++i) {
+ const QUrl nextUrl = m_itemData.at(i)->item.url();
+ m_items.insert(nextUrl, i);
+ }
+
+ itemsInHash = currentBlockEnd;
+ index = m_items.value(urlToFind, -1);
+ }
+
+ if (index < 0) {
+ // The item could not be found, even though all items from m_itemData
+ // should be in m_items now. We print some diagnostic information which
+ // might help to find the cause of the problem, but only once. This
+ // prevents that obtaining and printing the debugging information
+ // wastes CPU cycles and floods the shell or .xsession-errors.
+ static bool printDebugInfo = true;
+
+ if (m_items.count() != m_itemData.count() && printDebugInfo) {
+ printDebugInfo = false;
+
+ qCWarning(DolphinDebug) << "The model is in an inconsistent state.";
+ qCWarning(DolphinDebug) << "m_items.count() ==" << m_items.count();
+ qCWarning(DolphinDebug) << "m_itemData.count() ==" << m_itemData.count();
+
+ // Check if there are multiple items with the same URL.
+ QMultiHash<QUrl, int> indexesForUrl;
+ for (int i = 0; i < m_itemData.count(); ++i) {
+ indexesForUrl.insert(m_itemData.at(i)->item.url(), i);
+ }
+
+ foreach (const QUrl& url, indexesForUrl.uniqueKeys()) {
+ if (indexesForUrl.count(url) > 1) {
+ qCWarning(DolphinDebug) << "Multiple items found with the URL" << url;
+
+ auto it = indexesForUrl.find(url);
+ while (it != indexesForUrl.end() && it.key() == url) {
+ const ItemData* data = m_itemData.at(it.value());
+ qCWarning(DolphinDebug) << "index" << it.value() << ":" << data->item;
+ if (data->parent) {
+ qCWarning(DolphinDebug) << "parent" << data->parent->item;
+ }
+ ++it;
+ }
+ }
+ }
+ }
+ }
+
+ return index;