From 2ce402fa41508d45e2d30b56502c00ef92efff7b Mon Sep 17 00:00:00 2001 From: Andrew Opalach Date: Wed, 30 Apr 2025 17:42:08 -0400 Subject: Refactor the way cache backing sizes are tracked Signed-off-by: Andrew Opalach --- src/cache/backings/file.c | 60 +++++++++++++++++++++---------------- src/cache/backings/file.h | 1 - src/cache/backings/file_common.h | 28 +++++++++-------- src/cache/backings/file_mapped.c | 41 ++++++++++++++----------- src/cache/backings/memory.c | 65 +++++++++++++++++++++++++++------------- src/cache/backings/memory.h | 4 +-- 6 files changed, 121 insertions(+), 78 deletions(-) (limited to 'src/cache/backings') diff --git a/src/cache/backings/file.c b/src/cache/backings/file.c index 500e16f..06cc600 100644 --- a/src/cache/backings/file.c +++ b/src/cache/backings/file.c @@ -7,40 +7,48 @@ static void file_backing_lock(struct cch_backing *backing) nn_mutex_lock(&file->mutex); } -static void file_backing_write(struct cch_backing *backing, u8 *buf, off_t index, size_t *size) +static void maybe_seek_to_index(struct cch_backing_file *file, off_t index) { - struct cch_backing_file *file = (struct cch_backing_file *)backing; - nn_mutex_lock(&file->mutex); if (file->u.pointer != index) { file->u.pointer = nn_file_seek(&file->file, index, SEEK_SET); al_assert(file->u.pointer == index); } - off_t n = (off_t)*size; - if (file->size >= 0 && index + n >= file->size) { - n = MAX(file->size - index, (off_t)0); +} + +static void file_backing_write(struct cch_backing *backing, u8 *buf, off_t index, size_t *count) +{ + struct cch_backing_file *file = (struct cch_backing_file *)backing; + off_t n = (off_t)*count; + nn_mutex_lock(&file->mutex); + maybe_seek_to_index(file, index); + off_t size = file->backing.size; + if (size > 0 && index + n >= size) { + n = MAX(size - index, (off_t)0); + } + if (n > 0) { + nn_file_write(&file->file, buf, n); + file->u.pointer += n; + cch_backing_fill_range(&file->backing, index, n); } - nn_file_write(&file->file, buf, n); - file->u.pointer += n; - cch_backing_fill_range(&file->backing, index, n); - *size = (size_t)n; + *count = (size_t)n; nn_mutex_unlock(&file->mutex); } -static void file_backing_read(struct cch_backing *backing, u8 *buf, off_t index, size_t *size) +static void file_backing_read(struct cch_backing *backing, u8 *buf, off_t index, size_t *count) { struct cch_backing_file *file = (struct cch_backing_file *)backing; + off_t n = (off_t)*count; nn_mutex_lock(&file->mutex); - if (file->u.pointer != index) { - file->u.pointer = nn_file_seek(&file->file, index, SEEK_SET); - al_assert(file->u.pointer == index); + maybe_seek_to_index(file, index); + off_t size = file->backing.size; + if (size > 0 && index + n >= size) { + n = MAX(size - index, (off_t)0); } - off_t n = (off_t)*size; - if (file->size >= 0 && index + n >= file->size) { - n = MAX(file->size - index, (off_t)0); + if (n > 0) { + nn_file_read(&file->file, buf, n); + file->u.pointer += n; } - nn_file_read(&file->file, buf, n); - file->u.pointer += n; - *size = (size_t)n; + *count = (size_t)n; nn_mutex_unlock(&file->mutex); } @@ -50,12 +58,12 @@ static void file_backing_unlock(struct cch_backing *backing) nn_mutex_unlock(&file->mutex); } -static void file_backing_resize(struct cch_backing *backing, size_t size) +static void file_backing_set_size(struct cch_backing *backing, off_t size, bool expand_to_size) { struct cch_backing_file *file = (struct cch_backing_file *)backing; nn_mutex_lock(&file->mutex); - file->size = size; - if (size > file->file.size) { + file->backing.size = size; + if (expand_to_size && (size_t)size > file->file.size) { nn_file_truncate(&file->file, size); } nn_mutex_unlock(&file->mutex); @@ -74,13 +82,15 @@ struct cch_backing *cch_backing_file_create(str *path, size_t size) { struct cch_backing_file *file = al_alloc_object(struct cch_backing_file); file->backing.mode = CACHE_BACKING_READ; + file->backing.size = -1; file->backing.lock = file_backing_lock; file->backing.write = file_backing_write; file->backing.read = file_backing_read; file->backing.get_ptr = NULL; file->backing.unlock = file_backing_unlock; - file->backing.get_size_estimate = file_backing_get_size_estimate; - file->backing.resize = file_backing_resize; + file->backing.set_size = file_backing_set_size; + file->backing.get_size_if_known = file_backing_get_size_if_known; + file->backing.finalize = file_backing_finalize; file->backing.free = file_backing_free; al_array_init(file->backing.available); if (!file_open_internal(file, path, size)) { diff --git a/src/cache/backings/file.h b/src/cache/backings/file.h index 06daac9..361aad6 100644 --- a/src/cache/backings/file.h +++ b/src/cache/backings/file.h @@ -10,7 +10,6 @@ struct cch_backing_file { struct cch_backing backing; struct nn_file file; - off_t size; union { off_t pointer; // CACHE_BACKING_READ void *map; // CACHE_BACKING_MAPPED diff --git a/src/cache/backings/file_common.h b/src/cache/backings/file_common.h index 3f4ed3b..936babe 100644 --- a/src/cache/backings/file_common.h +++ b/src/cache/backings/file_common.h @@ -7,29 +7,33 @@ AL_IGNORE_WARNING("-Wunused-function") -static off_t file_backing_get_size_estimate(struct cch_backing *backing) +static off_t file_backing_get_size_if_known(struct cch_backing *backing) { struct cch_backing_file *file = (struct cch_backing_file *)backing; nn_mutex_lock(&file->mutex); - off_t size = file->size; + off_t size = file->backing.size; nn_mutex_unlock(&file->mutex); return size; } +static void file_backing_finalize(struct cch_backing *backing) +{ + struct cch_backing_file *file = (struct cch_backing_file *)backing; + nn_mutex_lock(&file->mutex); + file->backing.size = file->file.size; + nn_mutex_unlock(&file->mutex); +} + static bool file_open_internal(struct cch_backing_file *file, str *path, size_t size) { s32 flags = size != 0 ? NNWT_FILE_CREATE : NNWT_FILE_READONLY; - if (!nn_file_open(&file->file, path, flags)) { - return false; - } + if (!nn_file_open(&file->file, path, flags)) return false; + size_t filesize = file->file.size; if (!size) { - file->size = file->file.size; - cch_backing_fill_range(&file->backing, 0, file->size); - } else { - file->size = -1; - if (file->file.size < size) { - nn_file_truncate(&file->file, size); - } + file->backing.size = filesize; + cch_backing_fill_range(&file->backing, 0, filesize); + } else if (filesize < size) { + nn_file_truncate(&file->file, size); } return true; } diff --git a/src/cache/backings/file_mapped.c b/src/cache/backings/file_mapped.c index adb840c..7657a21 100644 --- a/src/cache/backings/file_mapped.c +++ b/src/cache/backings/file_mapped.c @@ -7,29 +7,33 @@ static void file_backing_lock(struct cch_backing *backing) nn_mutex_lock(&file->mutex); } -static void file_backing_write(struct cch_backing *backing, u8 *buf, off_t index, size_t *size) +static void file_backing_write(struct cch_backing *backing, u8 *buf, off_t index, size_t *count) { struct cch_backing_file *file = (struct cch_backing_file *)backing; + off_t n = (off_t)*count; nn_mutex_lock(&file->mutex); - off_t n = (off_t)*size; - if (file->size >= 0 && index + n >= file->size) { - n = MAX(file->size - index, (off_t)0); + off_t size = file->backing.size; + if (size > 0 && index + n >= size) { + n = MAX(size - index, (off_t)0); } - al_memcpy(file->u.map + index, buf, n); - cch_backing_fill_range(&file->backing, index, n); - *size = (size_t)n; + if (n > 0) { + al_memcpy(file->u.map + index, buf, n); + cch_backing_fill_range(&file->backing, index, n); + } + *count = (size_t)n; nn_mutex_unlock(&file->mutex); } -static u8 *file_backing_get_ptr(struct cch_backing *backing, off_t index, size_t *size) +static u8 *file_backing_get_ptr(struct cch_backing *backing, off_t index, size_t *count) { struct cch_backing_file *file = (struct cch_backing_file *)backing; + off_t n = (off_t)*count; nn_mutex_lock(&file->mutex); - off_t n = (off_t)*size; - if (file->size >= 0 && index + n >= file->size) { - n = MAX(file->size - index, (off_t)0); + off_t size = file->backing.size; + if (size > 0 && index + n >= size) { + n = MAX(size - index, (off_t)0); } - *size = (size_t)n; + *count = (size_t)n; return (u8 *)(file->u.map + index); } @@ -39,12 +43,13 @@ static void file_backing_unlock(struct cch_backing *backing) nn_mutex_unlock(&file->mutex); } -static void file_backing_resize(struct cch_backing *backing, size_t size) +static void file_backing_set_size(struct cch_backing *backing, off_t size, bool expand_to_size) { struct cch_backing_file *file = (struct cch_backing_file *)backing; + al_assert(expand_to_size || size == 0); nn_mutex_lock(&file->mutex); - file->size = size; - if (size > file->file.size) { + file->backing.size = size; + if ((size_t)size > file->file.size) { nn_file_munmap(&file->file, file->u.map); nn_file_truncate(&file->file, size); file->u.map = nn_file_mmap(&file->file); @@ -67,13 +72,15 @@ struct cch_backing *cch_backing_file_create(str *path, size_t size) { struct cch_backing_file *file = al_alloc_object(struct cch_backing_file); file->backing.mode = CACHE_BACKING_MAPPED; + file->backing.size = -1; file->backing.lock = file_backing_lock; file->backing.write = file_backing_write; file->backing.read = NULL; file->backing.get_ptr = file_backing_get_ptr; file->backing.unlock = file_backing_unlock; - file->backing.get_size_estimate = file_backing_get_size_estimate; - file->backing.resize = file_backing_resize; + file->backing.set_size = file_backing_set_size; + file->backing.get_size_if_known = file_backing_get_size_if_known; + file->backing.finalize = file_backing_finalize; file->backing.free = file_backing_free; al_array_init(file->backing.available); if (!file_open_internal(file, path, size)) { diff --git a/src/cache/backings/memory.c b/src/cache/backings/memory.c index 8e0306a..6b3da62 100644 --- a/src/cache/backings/memory.c +++ b/src/cache/backings/memory.c @@ -2,10 +2,11 @@ #include "memory.h" -static void ensure_alloced(struct cch_backing_memory *mem, size_t size) +static void ensure_allocated(struct cch_backing_memory *mem, off_t amount) { - if (size > mem->alloc) { - mem->alloc = al_next_power_of_two(size); + if (amount > mem->expanse) mem->expanse = amount; + if (amount > mem->alloc) { + mem->alloc = al_next_power_of_two(amount); mem->data = al_realloc(mem->data, mem->alloc); } } @@ -16,26 +17,35 @@ static void memory_backing_lock(struct cch_backing *backing) nn_mutex_lock(&mem->mutex); } -static void memory_backing_write(struct cch_backing *backing, u8 *buf, off_t index, size_t *size) +static void memory_backing_write(struct cch_backing *backing, u8 *buf, off_t index, size_t *count) { struct cch_backing_memory *mem = (struct cch_backing_memory *)backing; + off_t n = (off_t)*count; nn_mutex_lock(&mem->mutex); - if (mem->size >= 0 && index + (off_t)*size >= mem->size) { - *size = MAX(mem->size - index, (off_t)0); + off_t size = mem->backing.size; + if (size > 0 && index + n >= size) { + n = MAX(size - index, (off_t)0); } - ensure_alloced(mem, index + *size); - al_memcpy(mem->data + index, buf, *size); - cch_backing_fill_range(&mem->backing, index, *size); + if (n > 0) { + ensure_allocated(mem, index + n); + al_memcpy(mem->data + index, buf, n); + cch_backing_fill_range(&mem->backing, index, n); + } + *count = (size_t)n; nn_mutex_unlock(&mem->mutex); } -static u8 *memory_backing_get_ptr(struct cch_backing *backing, off_t index, size_t *size) +static u8 *memory_backing_get_ptr(struct cch_backing *backing, off_t index, size_t *count) { struct cch_backing_memory *mem = (struct cch_backing_memory *)backing; + off_t n = (off_t)*count; nn_mutex_lock(&mem->mutex); - if (mem->size >= 0 && index + (off_t)*size >= mem->size) { - *size = MAX(mem->size - index, (off_t)0); + off_t size = mem->backing.size; + if (size > 0 && index + n >= size) { + n = MAX(size - index, (off_t)0); } + *count = (size_t)n; + al_assert(mem->alloc >= index + n); return (u8 *)(mem->data + index); } @@ -45,21 +55,32 @@ static void memory_backing_unlock(struct cch_backing *backing) nn_mutex_unlock(&mem->mutex); } -static off_t memory_backing_get_size_estimate(struct cch_backing *backing) +static void memory_backing_set_size(struct cch_backing *backing, off_t size, bool expand_to_size) +{ + struct cch_backing_memory *mem = (struct cch_backing_memory *)backing; + nn_mutex_lock(&mem->mutex); + mem->backing.size = size; + if (expand_to_size) { + al_assert(size > 0); + ensure_allocated(mem, size); + } + nn_mutex_unlock(&mem->mutex); +} + +static off_t memory_backing_get_size_if_known(struct cch_backing *backing) { struct cch_backing_memory *mem = (struct cch_backing_memory *)backing; nn_mutex_lock(&mem->mutex); - off_t size = mem->size; + off_t size = mem->backing.size; nn_mutex_unlock(&mem->mutex); return size; } -static void memory_backing_resize(struct cch_backing *backing, size_t size) +static void memory_backing_finalize(struct cch_backing *backing) { struct cch_backing_memory *mem = (struct cch_backing_memory *)backing; nn_mutex_lock(&mem->mutex); - ensure_alloced(mem, size); - mem->size = size; + mem->backing.size = mem->expanse; nn_mutex_unlock(&mem->mutex); } @@ -77,16 +98,18 @@ struct cch_backing *cch_backing_memory_create(size_t size) { struct cch_backing_memory *mem = al_alloc_object(struct cch_backing_memory); mem->backing.mode = CACHE_BACKING_MAPPED; + mem->backing.size = -1; mem->backing.lock = memory_backing_lock; mem->backing.write = memory_backing_write; mem->backing.get_ptr = memory_backing_get_ptr; mem->backing.unlock = memory_backing_unlock; - mem->backing.get_size_estimate = memory_backing_get_size_estimate; - mem->backing.resize = memory_backing_resize; + mem->backing.set_size = memory_backing_set_size; + mem->backing.get_size_if_known = memory_backing_get_size_if_known; + mem->backing.finalize = memory_backing_finalize; mem->backing.free = memory_backing_free; - mem->data = al_malloc(size); + if (size > 0) mem->data = al_malloc(size); + else mem->data = NULL; mem->alloc = size; - mem->size = -1; nn_mutex_init(&mem->mutex); al_array_init(mem->backing.available); return (struct cch_backing *)mem; diff --git a/src/cache/backings/memory.h b/src/cache/backings/memory.h index e290b48..4737eba 100644 --- a/src/cache/backings/memory.h +++ b/src/cache/backings/memory.h @@ -8,8 +8,8 @@ struct cch_backing_memory { struct cch_backing backing; u8 *data; - size_t alloc; - off_t size; + off_t alloc; + off_t expanse; struct nn_mutex mutex; }; -- cgit v1.2.3-101-g0448