Beispiel für einen zusammenhängenden Cache

Das Beispiel „Contiguous Cache“ zeigt, wie man mit „ QContiguousCache “ die Speicherauslastung bei sehr großen Modellen verwaltet. In manchen Umgebungen ist der Speicher begrenzt, und selbst wenn dies nicht der Fall ist, möchten Anwender nicht, dass eine Anwendung übermäßig viel Speicher belegt. Durch die Verwendung von „ QContiguousCache “ zur Verwaltung einer Liste – anstatt die gesamte Liste in den Speicher zu laden – kann die Anwendung den Speicherbedarf begrenzen, unabhängig von der Größe des Datensatzes, auf den sie zugreift.

Die einfachste Art, „ QContiguousCache “ zu nutzen, besteht darin, Elemente bei ihrer Anforderung zwischenzuspeichern. Wenn eine Ansicht ein Element in Zeile N anfordert, ist es wahrscheinlich, dass sie auch Elemente in Zeilen in der Nähe von N anfordert.

QVariant RandomListModel::data(const QModelIndex&index, int role) const
{
    if (role != Qt::DisplayRole)
        return QVariant();

    int row = index.row();

    if (row > m_rows.lastIndex()) {
        if (row - m_rows.lastIndex() > lookAhead)
            cacheRows(row - halfLookAhead, qMin(m_count, row + halfLookAhead));
        else while (row > m_rows.lastIndex())
                m_rows.append(fetchRow(m_rows.lastIndex() + 1));
    } else if (row < m_rows.firstIndex()) {
        if (m_rows.firstIndex() - row > lookAhead)
            cacheRows(qMax(0, row - halfLookAhead), row + halfLookAhead);
       else while (row < m_rows.firstIndex())
                m_rows.prepend(fetchRow(m_rows.firstIndex() - 1));
    }

    return m_rows.at(row);
}

void RandomListModel::cacheRows(int from, int to) const
{
    for (int i = from; i <= to;++i)
        m_rows.insert(i, fetchRow(i));
}

Nachdem die Zeile abgerufen wurde, prüft die Klasse, ob sich die Zeile innerhalb des aktuellen Bereichs des zusammenhängenden Caches befindet. Es wäre ebenso zulässig gewesen, stattdessen einfach den folgenden Code zu verwenden.

while (row > m_rows.lastIndex())
    m_rows.append(fetchWord(m_rows.lastIndex()+1);
while (row < m_rows.firstIndex())
    m_rows.prepend(fetchWord(m_rows.firstIndex()-1);

Allerdings springt eine Liste oft über Zeilen hinweg, wenn die Bildlaufleiste direkt verwendet wird, was dazu führt, dass der obige Code dazu führt, dass jede Zeile zwischen der alten und der neuen Zeile abgerufen wird.

Durch die Verwendung von ` QContiguousCache::lastIndex()` und ` QContiguousCache::firstIndex()` kann das Beispiel ermitteln, welchen Teil der Liste der Cache derzeit zwischenspeichert. Diese Werte stellen nicht die Indizes im eigenen Speicher des Caches dar, sondern vielmehr ein virtuelles, unendliches Array, das der Cache repräsentiert.

Durch die Verwendung von ` QContiguousCache::append()` und ` QContiguousCache::prepend()` stellt der Code sicher, dass Elemente, die möglicherweise noch auf dem Bildschirm zu sehen sind, nicht verloren gehen, wenn sich die angeforderte Zeile nicht weit vom aktuellen Cache-Bereich entfernt hat. ` QContiguousCache::insert()` kann potenziell mehr als ein Element aus dem Cache entfernen, da ` QContiguousCache ` keine Lücken zulässt. Wenn Ihr Cache schnell zwischen Zeilen mit erheblichen Lücken hin- und herspringen muss, sollten Sie stattdessen die Verwendung von ` QCache ` in Betracht ziehen.

Und das war’s schon. Ein durchaus sinnvoller Cache, der bei einer sehr großen Liste nur minimalen Speicherplatz beansprucht. In diesem Fall generiert der Zugriffsoperator zum Einlesen der Wörter in den Cache zufällige statt fester Werte. So können Sie beim Ausführen des Beispiels beobachten, wie der Cache-Bereich für eine bestimmte Anzahl von Zeilen beibehalten wird.

QString RandomListModel::fetchRow(int position) const
{
    return QString::number(QRandomGenerator::global()->bounded(++position));
}

Es lohnt sich außerdem, das Vorabrufen von Elementen in den Cache außerhalb der Zeichnungsroutine der Anwendung in Betracht zu ziehen. Dies kann entweder mit einem separaten Thread oder mithilfe eines „ QTimer “ erfolgen, um den Bereich des Caches schrittweise zu erweitern, bevor Zeilen außerhalb des aktuellen Cache-Bereichs angefordert werden.

Beispielprojekt @ code.qt.io

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.