Skip to content

Commit

Permalink
attempt to add size to cache to reduce calls to stat and speed up loa…
Browse files Browse the repository at this point in the history
…ding times
  • Loading branch information
KrahJohlito committed Dec 19, 2024
1 parent bfa5366 commit 16c7910
Showing 1 changed file with 57 additions and 39 deletions.
96 changes: 57 additions & 39 deletions src/supportbase.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,11 @@ struct game_list_t
struct game_cache_list
{
unsigned int count;
base_game_info_t *games;
struct {
base_game_info_t info;
unsigned int sizeMB;
char filename[256];
} *games;
};

int sbIsSameSize(const char *prefix, int prevSize)
Expand Down Expand Up @@ -145,23 +149,25 @@ static int loadISOGameListCache(const char *path, struct game_cache_list *cache)
{
char filename[256];
FILE *file;
base_game_info_t *games;
int result, size, count;
struct {
base_game_info_t info;
unsigned int sizeMB;
char filename[256];
} *games;

freeISOGameListCache(cache);

sprintf(filename, "%s/games.bin", path);
file = fopen(filename, "rb");
if (file != NULL) {
fseek(file, 0, SEEK_END);
size = ftell(file);
rewind(file);

count = size / sizeof(base_game_info_t);
count = size / sizeof(*games);
if (count > 0) {
games = memalign(64, count * sizeof(base_game_info_t));
games = memalign(64, count * sizeof(*games));
if (games != NULL) {
if (fread(games, sizeof(base_game_info_t), count, file) == count) {
if (fread(games, sizeof(*games), count, file) == count) {
LOG("loadISOGameListCache: %d games loaded.\n", count);
cache->count = count;
cache->games = games;
Expand All @@ -178,12 +184,10 @@ static int loadISOGameListCache(const char *path, struct game_cache_list *cache)
} else {
result = -1; // Empty file (should not happen)
}

fclose(file);
} else {
result = ENOENT;
}

return result;
}

Expand All @@ -202,28 +206,29 @@ static int updateISOGameList(const char *path, const struct game_cache_list *cac
FILE *file;
const struct game_list_t *game;
int result, i, j, modified;
base_game_info_t *list;
struct {
base_game_info_t info;
unsigned int sizeMB;
char filename[256];
} *list;

modified = 0;
if (cache != NULL) {
if ((head != NULL) && (count > 0)) {
game = head;

for (i = 0; i < count; i++) {
for (j = 0; j < cache->count; j++) {
if (strncmp(cache->games[i].name, game->gameinfo.name, ISO_GAME_NAME_MAX + 1) == 0 && strncmp(cache->games[i].extension, game->gameinfo.extension, ISO_GAME_EXTENSION_MAX + 1) == 0)
if (strncmp(cache->games[j].info.name, game->gameinfo.name, ISO_GAME_NAME_MAX + 1) == 0 &&
strncmp(cache->games[j].info.extension, game->gameinfo.extension, ISO_GAME_EXTENSION_MAX + 1) == 0)
break;
}

if (j == cache->count) {
LOG("updateISOGameList: game added.\n");
modified = 1;
break;
}

game = game->next;
}

if ((!modified) && (count != cache->count)) {
LOG("updateISOGameList: game removed.\n");
modified = 1;
Expand All @@ -237,27 +242,30 @@ static int updateISOGameList(const char *path, const struct game_cache_list *cac

if (!modified)
return 0;
LOG("updateISOGameList: caching new game list.\n");

LOG("updateISOGameList: caching new game list.\n");
result = 0;
sprintf(filename, "%s/games.bin", path);
if ((head != NULL) && (count > 0)) {
list = (base_game_info_t *)memalign(64, sizeof(base_game_info_t) * count);

if ((head != NULL) && (count > 0)) {
list = (typeof(list))memalign(64, sizeof(*list) * count);
if (list != NULL) {
// Convert the linked list into a flat array, for writing performance.
game = head;
for (i = 0; (i < count) && (game != NULL); i++, game = game->next) {
// copy one game, advance
memcpy(&list[i], &game->gameinfo, sizeof(base_game_info_t));
// copy game info
memcpy(&list[i].info, &game->gameinfo, sizeof(base_game_info_t));
list[i].sizeMB = game->gameinfo.sizeMB;

// create filename from name and extension
snprintf(list[i].filename, sizeof(list[i].filename), "%s%s",
game->gameinfo.name, game->gameinfo.extension);
}

file = fopen(filename, "wb");
if (file != NULL) {
result = fwrite(list, sizeof(base_game_info_t), count, file) == count ? 0 : EIO;

result = fwrite(list, sizeof(*list), count, file) == count ? 0 : EIO;
fclose(file);

if (result != 0)
remove(filename);
} else
Expand All @@ -275,31 +283,41 @@ static int updateISOGameList(const char *path, const struct game_cache_list *cac
}

// Queries for the game entry, based on filename. Only the new filename format is supported (filename.ext).
static int queryISOGameListCache(const struct game_cache_list *cache, base_game_info_t *ginfo, const char *filename)
static int queryISOGameListCache(const struct game_cache_list *cache, void *ginfo, const char *filename)
{
struct {
base_game_info_t info;
unsigned int sizeMB;
char filename[256];
} *cached_info = (typeof(cached_info))ginfo;

char isoname[ISO_GAME_FNAME_MAX + 1];
int i;

for (i = 0; i < cache->count; i++) {
snprintf(isoname, sizeof(isoname), "%s%s", cache->games[i].name, cache->games[i].extension);

snprintf(isoname, sizeof(isoname), "%s%s", cache->games[i].info.name, cache->games[i].info.extension);
if (strcmp(filename, isoname) == 0) {
memcpy(ginfo, &cache->games[i], sizeof(base_game_info_t));
memcpy(&cached_info->info, &cache->games[i].info, sizeof(base_game_info_t));
cached_info->sizeMB = cache->games[i].sizeMB;
strncpy(cached_info->filename, filename, sizeof(cached_info->filename) - 1);
cached_info->filename[sizeof(cached_info->filename) - 1] = '\0';
return 0;
}
}

return ENOENT;
}

static int scanForISO(char *path, char type, struct game_list_t **glist)
{
int count = 0;
struct game_cache_list cache = {0, NULL};
base_game_info_t cachedGInfo;
char fullpath[256];
struct dirent *dirent;
DIR *dir;
struct {
base_game_info_t info;
unsigned int sizeMB;
char filename[256];
} cachedGInfo;

int cacheLoaded = loadISOGameListCache(path, &cache) == 0;

Expand Down Expand Up @@ -337,8 +355,9 @@ static int scanForISO(char *path, char type, struct game_list_t **glist)
strncpy(game->extension, &dirent->d_name[GAME_STARTUP_MAX + NameLen], sizeof(game->extension) - 1);
game->extension[sizeof(game->extension) - 1] = '\0';
} else if (cacheLoaded && queryISOGameListCache(&cache, &cachedGInfo, dirent->d_name) == 0) {
// use cached entry
memcpy(game, &cachedGInfo, sizeof(base_game_info_t));
// use cached entry including size
memcpy(game, &cachedGInfo.info, sizeof(base_game_info_t));
game->sizeMB = cachedGInfo.sizeMB;
} else {
// need to mount and read SYSTEM.CNF
char startup[GAME_STARTUP_MAX];
Expand All @@ -357,20 +376,19 @@ static int scanForISO(char *path, char type, struct game_list_t **glist)
strncpy(game->extension, &dirent->d_name[NameLen], sizeof(game->extension) - 1);
game->extension[sizeof(game->extension) - 1] = '\0';

if (stat(fullpath, &statbuf) == 0) {
game->sizeMB = statbuf.st_size >> 20;
} else {
game->sizeMB = 0;
}

fileXioUmount("iso:");
}

game->parts = 1;
game->media = type;
game->format = format;


if (stat(fullpath, &statbuf) == 0) {
game->sizeMB = statbuf.st_size >> 20;
} else {
game->sizeMB = 0;
}

count++;
}
closedir(dir);
Expand Down

0 comments on commit 16c7910

Please sign in to comment.