C++ (Qt) QHash<Paper*,bool>
C++ (Qt)typedef QSharedPointer <unsigned char *> TSharedPtr;typedef QWeakPointer <unsigned char *> TWeakPtr; // заголовок страницы - всегда в памятиstruct PageHeader { TSharedPtr mData; // данные - могут быть загружены или нет long long mFilePos; // смещение в файле страниц unsigned char * LoadPage( void ); // грузит страницу с диска TWeakPtr GetData( void ); // возвращает (слабый) указатель на данные}; TWeakPtr PageHeader::GetData( void ){ if (mData.isNull()) // страница не загружена? mData = TSharedPtr(LoadPage()); // загружаем ее, счетчик = 1 return mData.toWeakRef(); // теперь счетчик = 2, когда слабый указатель удалится, -1}
class Cache{public: typedef QSharedPointer<const char> PageData; Cache(QIODevice& file) : file_(file), pages_(CacheSize) {} // Возвращает страницу данных; вызывается одновременно из нескольких потоков. const PageData& pageData(qint64 offset) const { QMutexLocker locker(&mutex_); // страница уже содержится - просто вернуть ее Q_FOREACH(const Page& page, pages_) if (page.offset == offset) return page.data; // страница не содержится - вытеснить самую старую, загрузить и вернуть новую pages_.dequeue(); Page page(offset, PageData(loadPageFromDisk(offset), &pageDeleter)); pages_.enqueue(page) return page.data; }private: static const int CacheSize = 2; struct Page { qint64 offset; PageData data; Page() : offset(-1) {} Page(qint64 offset, const PageData& data) : offset(offset), data(data) {} } typedef QQueue<Page> Pages; File& file_; Pages pages_; mutable QMutex mutex_; // загружает страницу с диска; например, память выделяется с помощью operator new[] const char* loadPageFromDisk(qint64 offset) const {...} static void pageDeleter(const char* data) { delete[] data; }}