인접 캐시 예제
연속 캐시 예제는 QContiguousCache 을 사용하여 매우 큰 모델의 메모리 사용량을 관리하는 방법을 보여줍니다. 일부 환경에서는 메모리가 제한되어 있고, 제한되어 있지 않더라도 사용자는 과도한 메모리를 사용하는 애플리케이션을 싫어합니다. 전체 목록을 메모리에 로드하는 대신 QContiguousCache 을 사용하여 목록을 관리하면 액세스하는 데이터 집합의 크기에 관계없이 애플리케이션이 사용하는 메모리 양을 제한할 수 있습니다.
QContiguousCache 을 사용하는 가장 간단한 방법은 항목이 요청될 때 캐싱하는 것입니다. 뷰가 N 행에 있는 항목을 요청하면 N에 가까운 행에 있는 항목도 요청할 가능성이 높습니다.
QVariant 랜덤리스트모델::데이터(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)); }
행을 가져온 후 클래스는 해당 행이 인접한 캐시의 현재 범위 내에 있는지 확인합니다. 대신 다음과 같은 코드를 사용하는 것도 똑같이 유효했을 것입니다.
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);
그러나 스크롤 막대를 직접 사용하는 경우 목록에서 행을 건너뛰는 경우가 많기 때문에 위 코드는 이전 행과 새 행 사이의 모든 행을 가져오는 결과를 초래합니다.
QContiguousCache::lastIndex() 및 QContiguousCache::firstIndex()을 사용하면 이 예제에서 캐시가 현재 캐싱하고 있는 목록의 어느 부분을 확인할 수 있습니다. 이 값은 캐시 자체 메모리에 있는 인덱스가 아니라 캐시가 나타내는 가상의 무한 배열을 나타냅니다.
QContiguousCache::append() 및 QContiguousCache::prepend()를 사용하면 요청된 행이 현재 캐시 범위에서 멀리 이동하지 않았을 때 화면에 남아 있을 수 있는 항목이 손실되지 않도록 보장합니다. QContiguousCache::insert()는 QContiguousCache 이 간격을 허용하지 않으므로 캐시에서 두 개 이상의 항목을 제거할 수 있습니다. 캐시가 행 사이에 상당한 간격이 있는 행 사이를 빠르게 앞뒤로 이동해야 하는 경우 대신 QCache 을 사용하는 것이 좋습니다.
이상입니다. 매우 큰 목록에 최소한의 메모리를 사용하는 완벽하게 합리적인 캐시입니다. 이 경우 단어를 캐시에 가져오는 접근자는 고정된 정보가 아닌 임의의 정보를 생성합니다. 이를 통해 예제를 실행할 때 로컬 행 수에 대해 캐시 범위가 어떻게 유지되는지 확인할 수 있습니다.
QString RandomListModel::fetchRow(int position) const { return QString::number(QRandomGenerator::global()->bounded(++position)); }
애플리케이션의 페인트 루틴 외부에서 항목을 캐시로 미리 가져오는 것도 고려해 볼 가치가 있습니다. 이는 별도의 스레드를 사용하거나 QTimer 을 사용하여 현재 캐시 범위에서 행이 요청되기 전에 캐시 범위를 점진적으로 확장하는 방식으로 수행할 수 있습니다.
© 2025 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.