mesa/src/util/mesa_cache_db.h

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

149 lines
2.9 KiB
C
Raw Normal View History

/*
* Copyright © 2022 Collabora, Ltd.
*
* Based on Fossilize DB:
* Copyright © 2020 Valve Corporation
*
* SPDX-License-Identifier: MIT
*/
#ifndef MESA_CACHE_DB_H
#define MESA_CACHE_DB_H
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include "detect_os.h"
#include "simple_mtx.h"
#ifdef __cplusplus
extern "C" {
#endif
struct mesa_cache_db_file {
FILE *file;
char *path;
off_t offset;
uint64_t uuid;
};
struct mesa_cache_db {
struct hash_table_u64 *index_db;
struct mesa_cache_db_file cache;
struct mesa_cache_db_file index;
uint64_t max_cache_size;
simple_mtx_t flock_mtx;
void *mem_ctx;
uint64_t uuid;
bool alive;
};
#if DETECT_OS_WINDOWS == 0
bool
mesa_cache_db_open(struct mesa_cache_db *db, const char *cache_path);
void
mesa_cache_db_close(struct mesa_cache_db *db);
void
mesa_cache_db_set_size_limit(struct mesa_cache_db *db,
uint64_t max_cache_size);
unsigned int
mesa_cache_db_file_entry_size(void);
void *
mesa_cache_db_read_entry(struct mesa_cache_db *db,
const uint8_t *cache_key_160bit,
size_t *size);
bool
mesa_cache_db_entry_write(struct mesa_cache_db *db,
const uint8_t *cache_key_160bit,
const void *blob, size_t blob_size);
bool
mesa_cache_db_entry_remove(struct mesa_cache_db *db,
const uint8_t *cache_key_160bit);
util/mesa-db: Introduce multipart mesa-db cache Whenever a single file mesa-db cache hits max size limit, a half of cache is evicted and the cache file is defragmented. The downside of this eviction strategy is that it causes high disk IO usage during eviction if mesa-db cache file size is large. In order to mitigate this downside, we will split mesa-db into multiple part such that only one part will be evicted at a time. Each part will be an individual single file mesa-db cache, like a DB shard. The new multipart mesa-db cache will merge the parts into a single virtual cache. This patch introduces two new environment variables: 1. MESA_DISK_CACHE_DATABASE_NUM_PARTS: Controls number of mesa-db cache file parts. By default 50 parts will be created. The old pre-multipart mesa-db cache files will be auto-removed if they exist, i.e. Mesa will switch to the new DB version automatically. 2. MESA_DISK_CACHE_DATABASE_EVICTION_SCORE_2X_PERIOD: Controls the eviction score doubling time period. The evicted DB part selection is based on cache entries size weighted by 'last_access_time' of the entries. By default the cache eviction score is doubled for each month of cache entry age, i.e. for two equally sized entries where one entry is older by one month than the other, the older entry will have x2 eviction score than the other entry. Database part with a highest total eviction score is selected for eviction. This patch brings x40 performance improvement of cache eviction time using multipart cache vs a single file cache due to a smaller eviction portions and more optimized eviction algorithm. Acked-by: Timothy Arceri <tarceri@itsqueeze.com> Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/20256>
2022-10-24 13:24:16 +03:00
bool
mesa_db_wipe_path(const char *cache_path);
bool
mesa_cache_db_has_space(struct mesa_cache_db *db, size_t blob_size);
double
mesa_cache_db_eviction_score(struct mesa_cache_db *db);
#else
static inline bool
mesa_cache_db_open(struct mesa_cache_db *db, const char *cache_path)
{
return false;
}
static inline void
mesa_cache_db_close(struct mesa_cache_db *db)
{
}
static inline void
mesa_cache_db_set_size_limit(struct mesa_cache_db *db,
uint64_t max_cache_size)
{
}
static inline unsigned int
mesa_cache_db_file_entry_size(void)
{
return 0;
}
static inline void *
mesa_cache_db_read_entry(struct mesa_cache_db *db,
const uint8_t *cache_key_160bit,
size_t *size)
{
return NULL;
}
static inline bool
mesa_cache_db_entry_write(struct mesa_cache_db *db,
const uint8_t *cache_key_160bit,
const void *blob, size_t blob_size)
{
return false;
}
static inline bool
mesa_cache_db_entry_remove(struct mesa_cache_db *db,
const uint8_t *cache_key_160bit)
{
return false;
}
util/mesa-db: Introduce multipart mesa-db cache Whenever a single file mesa-db cache hits max size limit, a half of cache is evicted and the cache file is defragmented. The downside of this eviction strategy is that it causes high disk IO usage during eviction if mesa-db cache file size is large. In order to mitigate this downside, we will split mesa-db into multiple part such that only one part will be evicted at a time. Each part will be an individual single file mesa-db cache, like a DB shard. The new multipart mesa-db cache will merge the parts into a single virtual cache. This patch introduces two new environment variables: 1. MESA_DISK_CACHE_DATABASE_NUM_PARTS: Controls number of mesa-db cache file parts. By default 50 parts will be created. The old pre-multipart mesa-db cache files will be auto-removed if they exist, i.e. Mesa will switch to the new DB version automatically. 2. MESA_DISK_CACHE_DATABASE_EVICTION_SCORE_2X_PERIOD: Controls the eviction score doubling time period. The evicted DB part selection is based on cache entries size weighted by 'last_access_time' of the entries. By default the cache eviction score is doubled for each month of cache entry age, i.e. for two equally sized entries where one entry is older by one month than the other, the older entry will have x2 eviction score than the other entry. Database part with a highest total eviction score is selected for eviction. This patch brings x40 performance improvement of cache eviction time using multipart cache vs a single file cache due to a smaller eviction portions and more optimized eviction algorithm. Acked-by: Timothy Arceri <tarceri@itsqueeze.com> Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/20256>
2022-10-24 13:24:16 +03:00
static inline bool
mesa_db_wipe_path(const char *cache_path)
{
return false;
}
static inline bool
mesa_cache_db_has_space(struct mesa_cache_db *db, size_t blob_size)
{
return false;
}
static inline double
mesa_cache_db_eviction_score(struct mesa_cache_db *db)
{
return 0;
}
#endif /* DETECT_OS_WINDOWS */
#ifdef __cplusplus
}
#endif
#endif /* MESA_CACHE_DB_H */