Ejemplo de caché contigua

El ejemplo de caché contigua muestra cómo utilizar QContiguousCache para gestionar el uso de memoria en modelos muy grandes. En algunos entornos, la memoria es limitada y, aunque no lo sea, a los usuarios no les gusta que una aplicación utilice demasiada memoria. Utilizar QContiguousCache para gestionar una lista, en lugar de cargar toda la lista en memoria, permite a la aplicación limitar la cantidad de memoria que utiliza, independientemente del tamaño del conjunto de datos al que accede.

La forma más sencilla de utilizar QContiguousCache es almacenar en caché los elementos a medida que se solicitan. Cuando una vista solicita un elemento en la fila N, es probable que también solicite elementos en las filas cercanas a N.

QVariant RandomListModel::data(const QModelIndex &index, int rol) const{ if (role! = Qt::DisplayRole) return QVariant(); int fila = indice.fila(); if (fila > m_filas.ultimoIndice()) { if (fila - m_filas.ultimoIndice() > miradaCabeza) cacheRows(fila - mediaMiradaCabeza, qMin(m_cuenta, fila + mediaMiradaCabeza)); else while (fila > m_filas.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)); }

Después de obtener la fila, la clase determina si la fila está dentro de los límites del rango actual de la caché contigua. Hubiera sido igualmente válido simplemente tener el siguiente código en su lugar.

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

Sin embargo, una lista a menudo saltará filas si la barra de desplazamiento se usa directamente, resultando en que el código de arriba causa que cada fila entre la vieja y la nueva fila sea obtenida.

El uso de QContiguousCache::lastIndex() y QContiguousCache::firstIndex() permite al ejemplo determinar qué parte de la lista está almacenando actualmente la caché. Estos valores no representan los índices en la propia memoria de la caché, sino un array virtual infinito que la caché representa.

Mediante el uso de QContiguousCache::append() y QContiguousCache::prepend() el código asegura que los elementos que puedan estar todavía en la pantalla no se pierdan cuando la fila solicitada no se ha movido mucho del rango actual de la caché. QContiguousCache::insert() puede eliminar potencialmente más de un elemento de la caché, ya que QContiguousCache no permite huecos. Si su caché necesita saltar rápidamente entre filas con espacios significativos entre ellas, considere utilizar QCache en su lugar.

Y eso es todo. Una caché perfectamente razonable, utilizando un mínimo de memoria para una lista muy grande. En este caso el accesor para introducir las palabras en la caché genera información aleatoria en lugar de información fija. Esto permite ver cómo se mantiene el rango de la caché para un número local de filas al ejecutar el ejemplo.

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

También merece la pena considerar la posibilidad de precargar elementos en la caché fuera de la rutina de pintado de la aplicación. Esto se puede hacer con un hilo separado o usando QTimer para expandir incrementalmente el rango de la caché antes de que se soliciten filas fuera del rango actual de la caché.

Proyecto de ejemplo @ 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.