mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-27 07:20:49 +00:00
Reorganize disk cache to allow for dynamic size.
This commit is contained in:
parent
ba2adb8502
commit
f0ec6fab4d
@ -117,6 +117,7 @@ void DiskCachingFileLoaderCache::InitCache(const std::string &path) {
|
||||
cacheSize_ = 0;
|
||||
indexCount_ = 0;
|
||||
oldestGeneration_ = 0;
|
||||
maxBlocks_ = MAX_BLOCKS_LOWER_BOUND;
|
||||
generation_ = 0;
|
||||
|
||||
const std::string cacheFilePath = MakeCacheFilePath(path);
|
||||
@ -248,7 +249,7 @@ size_t DiskCachingFileLoaderCache::SaveIntoCache(FileLoader *backend, s64 pos, s
|
||||
}
|
||||
|
||||
bool DiskCachingFileLoaderCache::MakeCacheSpaceFor(size_t blocks) {
|
||||
size_t goal = MAX_BLOCKS_CACHED - blocks;
|
||||
size_t goal = (size_t)maxBlocks_ - blocks;
|
||||
|
||||
while (cacheSize_ > goal) {
|
||||
u16 minGeneration = generation_;
|
||||
@ -414,6 +415,9 @@ bool DiskCachingFileLoaderCache::LoadCacheFile(const std::string &path) {
|
||||
valid = false;
|
||||
} else if (header.filesize != filesize_) {
|
||||
valid = false;
|
||||
} else if (header.maxBlocks < MAX_BLOCKS_LOWER_BOUND || header.maxBlocks > MAX_BLOCKS_UPPER_BOUND) {
|
||||
// This means it's not in our safety bounds, reject.
|
||||
valid = false;
|
||||
}
|
||||
|
||||
// If it's valid, retain the file pointer.
|
||||
@ -427,6 +431,7 @@ bool DiskCachingFileLoaderCache::LoadCacheFile(const std::string &path) {
|
||||
|
||||
// Now let's load the index.
|
||||
blockSize_ = header.blockSize;
|
||||
maxBlocks_ = header.maxBlocks;
|
||||
LoadCacheIndex();
|
||||
} else {
|
||||
ERROR_LOG(LOADER, "Disk cache file header did not match, recreating cache file");
|
||||
@ -446,8 +451,8 @@ void DiskCachingFileLoaderCache::LoadCacheIndex() {
|
||||
|
||||
indexCount_ = (filesize_ + blockSize_ - 1) / blockSize_;
|
||||
index_.resize(indexCount_);
|
||||
blockIndexLookup_.resize(MAX_BLOCKS_CACHED);
|
||||
memset(&blockIndexLookup_[0], INVALID_INDEX, MAX_BLOCKS_CACHED * sizeof(blockIndexLookup_[0]));
|
||||
blockIndexLookup_.resize(maxBlocks_);
|
||||
memset(&blockIndexLookup_[0], INVALID_INDEX, maxBlocks_ * sizeof(blockIndexLookup_[0]));
|
||||
|
||||
if (fread(&index_[0], sizeof(BlockInfo), indexCount_, f_) != indexCount_) {
|
||||
fclose(f_);
|
||||
@ -462,7 +467,7 @@ void DiskCachingFileLoaderCache::LoadCacheIndex() {
|
||||
cacheSize_ = 0;
|
||||
|
||||
for (size_t i = 0; i < index_.size(); ++i) {
|
||||
if (index_[i].block > MAX_BLOCKS_CACHED) {
|
||||
if (index_[i].block > maxBlocks_) {
|
||||
index_[i].block = INVALID_BLOCK;
|
||||
}
|
||||
if (index_[i].block == INVALID_BLOCK) {
|
||||
@ -482,6 +487,14 @@ void DiskCachingFileLoaderCache::LoadCacheIndex() {
|
||||
}
|
||||
|
||||
void DiskCachingFileLoaderCache::CreateCacheFile(const std::string &path) {
|
||||
maxBlocks_ = DetermineMaxBlocks();
|
||||
if (maxBlocks_ < MAX_BLOCKS_LOWER_BOUND) {
|
||||
// There's not enough free space to cache, disable.
|
||||
f_ = nullptr;
|
||||
ERROR_LOG(LOADER, "Not enough free space; disabling disk cache");
|
||||
return;
|
||||
}
|
||||
|
||||
f_ = File::OpenCFile(path, "wb+");
|
||||
if (!f_) {
|
||||
ERROR_LOG(LOADER, "Could not create disk cache file");
|
||||
@ -499,6 +512,7 @@ void DiskCachingFileLoaderCache::CreateCacheFile(const std::string &path) {
|
||||
header.version = CACHE_VERSION;
|
||||
header.blockSize = blockSize_;
|
||||
header.filesize = filesize_;
|
||||
header.maxBlocks = maxBlocks_;
|
||||
|
||||
if (fwrite(&header, sizeof(header), 1, f_) != 1) {
|
||||
fclose(f_);
|
||||
@ -509,8 +523,8 @@ void DiskCachingFileLoaderCache::CreateCacheFile(const std::string &path) {
|
||||
|
||||
indexCount_ = (filesize_ + blockSize_ - 1) / blockSize_;
|
||||
index_.resize(indexCount_);
|
||||
blockIndexLookup_.resize(MAX_BLOCKS_CACHED);
|
||||
memset(&blockIndexLookup_[0], INVALID_INDEX, MAX_BLOCKS_CACHED * sizeof(blockIndexLookup_[0]));
|
||||
blockIndexLookup_.resize(maxBlocks_);
|
||||
memset(&blockIndexLookup_[0], INVALID_INDEX, maxBlocks_ * sizeof(blockIndexLookup_[0]));
|
||||
|
||||
if (fwrite(&index_[0], sizeof(BlockInfo), indexCount_, f_) != indexCount_) {
|
||||
fclose(f_);
|
||||
@ -519,3 +533,8 @@ void DiskCachingFileLoaderCache::CreateCacheFile(const std::string &path) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
u32 DiskCachingFileLoaderCache::DetermineMaxBlocks() {
|
||||
// TODO (don't forget to clamp UPPER)
|
||||
return 4096;
|
||||
}
|
||||
|
@ -104,24 +104,27 @@ private:
|
||||
void LoadCacheIndex();
|
||||
void CreateCacheFile(const std::string &path);
|
||||
|
||||
u32 DetermineMaxBlocks();
|
||||
|
||||
// File format:
|
||||
// 64 magic
|
||||
// 32 version
|
||||
// 32 blockSize
|
||||
// 64 filesize
|
||||
// 32 maxBlocks
|
||||
// index[filesize / blockSize] <-- ~500 KB for 4GB
|
||||
// 32 (fileoffset - headersize) / blockSize -> -1=not present
|
||||
// 16 generation?
|
||||
// 16 hits?
|
||||
// blocks[MAX_BLOCKS]
|
||||
// blocks[up to maxBlocks]
|
||||
// 8 * blockSize
|
||||
|
||||
enum {
|
||||
CACHE_VERSION = 1,
|
||||
CACHE_VERSION = 2,
|
||||
DEFAULT_BLOCK_SIZE = 65536,
|
||||
MAX_BLOCKS_PER_READ = 16,
|
||||
// TODO: Dynamic.
|
||||
MAX_BLOCKS_CACHED = 4096, // 256 MB
|
||||
MAX_BLOCKS_LOWER_BOUND = 256, // 16 MB
|
||||
MAX_BLOCKS_UPPER_BOUND = 8192, // 512 MB
|
||||
INVALID_BLOCK = 0xFFFFFFFF,
|
||||
INVALID_INDEX = 0xFFFFFFFF,
|
||||
};
|
||||
@ -131,6 +134,7 @@ private:
|
||||
u32 blockSize_;
|
||||
u16 generation_;
|
||||
u16 oldestGeneration_;
|
||||
u32 maxBlocks_;
|
||||
size_t cacheSize_;
|
||||
size_t indexCount_;
|
||||
recursive_mutex lock_;
|
||||
@ -140,6 +144,7 @@ private:
|
||||
u32_le version;
|
||||
u32_le blockSize;
|
||||
s64_le filesize;
|
||||
s32_le maxBlocks;
|
||||
};
|
||||
|
||||
struct BlockInfo {
|
||||
|
Loading…
Reference in New Issue
Block a user