連続キャッシュの例
Contiguous Cacheの例では、QContiguousCache 、非常に大きなモデルのメモリ使用量を管理する方法を示しています。環境によってはメモリが制限されている場合があり、そうでない場合でも、ユーザは過剰なメモリを使用するアプリケーションを嫌います。リスト全体をメモリにロードするのではなく、QContiguousCache を使用してリストを管理することで、アクセスするデータセットのサイズに関係なく、アプリケーションが使用するメモリ量を制限することができます。
QContiguousCache を使用する最も簡単な方法は、アイテムが要求されたときにキャッシュすることです。ビューがN行目の項目を要求すると、N行目に近い行の項目も要求する可能性があります。
QVariantRandomListModel::data(constQModelIndexindex, introle)const{if(role!= Qt::DisplayRole)returnQVariant();introw=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); }returnm_rows.at(row); }voidRandomListModel::cacheRows(intfrom, intto)const{for(inti=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.