6 n__disk__cache_8h
gullradriel edited this page 2026-10-09 00:55:18 +02:00

include/nilorea/n_disk_cache.h

A bounded cache of files in one directory, keyed by content. More...

Detailed Description

A bounded cache of files in one directory, keyed by content.

Author: Castagnier Mickael

Version: 1.0

Date: 24/09/2026

A program that derives something expensive from a source, a thumbnail from a photograph, a transcoded file, a downloaded page, keeps the result on disk under a key that names everything it was derived from: change any of it and the key changes, so a stale entry is a miss rather than a wrong answer.

A key is any bytes. It is hashed (MurmurHash3, 128 bits) into a file name of 32 hexadecimal digits, followed by the caller's extension, in the cache's directory. Nothing else is stored: no index file to corrupt or keep in step.

Entries go in with n_disk_cache_put() (written atomically, so a crash leaves the old entry or the new one) and come out with n_disk_cache_get(). A caller whose data is written and read by another library, an image codec saving straight to a path, asks for the path with n_disk_cache_path() instead.

The cache is bounded by n_disk_cache_prune(), which removes least recently used entries until the directory is under a size, and n_disk_cache_expire(), which removes entries unused for longer than an age. "Used" is the access time where the filesystem keeps one, else the write time.

Both only ever remove files whose names this module could have made: 32 lowercase hexadecimal digits, then nothing or a '.'. A cache pointed at a directory that holds other files leaves them alone.

Nothing is kept in memory but the directory name, so any number of threads may use one cache; two writing the same key at once leave one of the two.

Source code

/*
 * Nilorea Library
 * Copyright (C) 2005-2026 Castagnier Mickael
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied. See the License for the specific language governing
 * permissions and limitations under the License.
 *
 * SPDX-License-Identifier: Apache-2.0
 */


#ifndef __NILOREA_DISK_CACHE__
#define __NILOREA_DISK_CACHE__

#ifdef __cplusplus
extern "C" {
#endif


#include <stddef.h>
#include <stdint.h>

#include "nilorea/n_common.h"

#define N_DISK_CACHE_NAME_LEN 32

typedef struct N_DISK_CACHE N_DISK_CACHE;

N_DISK_CACHE* n_disk_cache_open(const char* dir);

void n_disk_cache_close(N_DISK_CACHE** cache);

const char* n_disk_cache_dir(const N_DISK_CACHE* cache);

int n_disk_cache_path(const N_DISK_CACHE* cache, const void* key, size_t key_len, const char* ext, char* out, size_t out_len);

int n_disk_cache_put(const N_DISK_CACHE* cache, const void* key, size_t key_len, const char* ext, const void* data, size_t len);

int n_disk_cache_get(const N_DISK_CACHE* cache, const void* key, size_t key_len, const char* ext, size_t max_len, unsigned char** data, size_t* len);

int n_disk_cache_remove(const N_DISK_CACHE* cache, const void* key, size_t key_len, const char* ext);

int n_disk_cache_size(const N_DISK_CACHE* cache, uint64_t* total);

int n_disk_cache_prune(const N_DISK_CACHE* cache, uint64_t max_bytes);

int n_disk_cache_prune_group(const N_DISK_CACHE* const* caches, int count, uint64_t max_bytes);

int n_disk_cache_expire(const N_DISK_CACHE* cache, int64_t max_age_seconds);


#ifdef __cplusplus
}
#endif
#endif /* __NILOREA_DISK_CACHE__ */