libaaruformat
1.0
Aaru Data Preservation Suite - Format Library
Toggle main menu visibility
Loading...
Searching...
No Matches
lru.c
Go to the documentation of this file.
1
#include <stddef.h>
2
#include <stdint.h>
3
#include <stdlib.h>
4
#include <uthash.h>
5
6
#include <
aaruformat.h
>
7
8
// LRU cache using uthash with native integer keys.
9
// Based on uthash LRU example by Jehiah Czebotar 2011 (public domain).
10
// Rewritten to use HASH_FIND/HASH_ADD with uint64_t keys directly,
11
// eliminating all string conversion, malloc, and snprintf overhead
12
// from the hot path.
13
20
static
void
drop_entry
(
struct
CacheHeader
*cache,
struct
CacheEntry
*entry)
21
{
22
HASH_DELETE(hh, cache->
cache
, entry);
23
24
cache->
cur_bytes
-= entry->
size
;
25
26
if
(cache->
free_func
&& entry->
value
) cache->
free_func
(entry->
value
);
27
28
free(entry);
29
}
30
41
void
*
find_in_cache_uint64
(
struct
CacheHeader
*cache,
const
uint64_t key)
42
{
43
struct
CacheEntry
*entry = NULL;
44
HASH_FIND(
hh
, cache->
cache
, &
key
,
sizeof
(uint64_t), entry);
45
if
(entry)
46
{
47
// Remove and re-add to move to front of insertion-order list (LRU refresh).
48
HASH_DELETE(
hh
, cache->
cache
, entry);
49
HASH_ADD(
hh
, cache->
cache
,
key
,
sizeof
(uint64_t), entry);
50
return
entry->
value
;
51
}
52
return
NULL;
53
}
54
68
void
add_to_cache_uint64
(
struct
CacheHeader
*cache,
const
uint64_t
key
,
void
*
value
,
const
size_t
size
)
69
{
70
struct
CacheEntry
*entry = NULL;
71
72
// Replace an existing entry for this key. A blind HASH_ADD would leave the old entry in the
73
// table unreachable by HASH_FIND, and its value alive until the whole cache is freed.
74
HASH_FIND(
hh
, cache->
cache
, &
key
,
sizeof
(uint64_t), entry);
75
76
if
(entry)
77
{
78
cache->
cur_bytes
-= entry->
size
;
79
80
if
(cache->
free_func
&& entry->
value
&& entry->
value
!=
value
) cache->
free_func
(entry->
value
);
81
82
HASH_DELETE(
hh
, cache->
cache
, entry);
83
}
84
else
85
{
86
entry = malloc(
sizeof
(
struct
CacheEntry
));
87
if
(!entry)
return
;
88
}
89
90
entry->
key
=
key
;
91
entry->
value
=
value
;
92
entry->
size
=
size
;
93
HASH_ADD(
hh
, cache->
cache
,
key
,
sizeof
(uint64_t), entry);
94
cache->
cur_bytes
+=
size
;
95
96
if
(cache->
max_bytes
== 0)
return
;
97
98
// Evict least recently used entries until back under budget. Never evict the entry just
99
// inserted: the caller still uses that pointer after this returns.
100
while
(cache->
cur_bytes
> cache->
max_bytes
&& HASH_COUNT(cache->
cache
) > 1)
101
{
102
struct
CacheEntry
*oldest = cache->
cache
;
103
104
if
(oldest == NULL || oldest == entry)
break
;
105
106
drop_entry
(cache, oldest);
107
}
108
}
109
118
void
free_cache
(
struct
CacheHeader
*cache)
119
{
120
struct
CacheEntry
*entry, *tmp;
121
122
if
(!cache || !cache->
cache
)
return
;
123
124
HASH_ITER(
hh
, cache->
cache
, entry, tmp) {
drop_entry
(cache, entry); }
125
126
cache->
cache
= NULL;
127
cache->
cur_bytes
= 0;
128
}
aaruformat.h
drop_entry
static void drop_entry(struct CacheHeader *cache, struct CacheEntry *entry)
Frees a cache entry's value and unlinks it from the cache.
Definition
lru.c:20
add_to_cache_uint64
void add_to_cache_uint64(struct CacheHeader *cache, uint64_t key, void *value, size_t size)
Adds a value to the cache with a uint64_t key, evicting LRU entries if over budget.
Definition
lru.c:68
find_in_cache_uint64
void * find_in_cache_uint64(struct CacheHeader *cache, uint64_t key)
Finds a value in the cache by uint64_t key.
Definition
lru.c:41
free_cache
void free_cache(struct CacheHeader *cache)
Frees all entries in the cache and clears it.
Definition
lru.c:118
CacheEntry
Single hash entry in the in-memory cache.
Definition
lru.h:25
CacheEntry::value
void * value
Opaque value pointer associated with key.
Definition
lru.h:27
CacheEntry::size
size_t size
Size in bytes of the memory pointed to by value.
Definition
lru.h:28
CacheEntry::key
uint64_t key
64-bit integer key (unique within the cache).
Definition
lru.h:26
CacheEntry::hh
UT_hash_handle hh
uthash handle (must remain per uthash docs).
Definition
lru.h:29
CacheHeader
Cache top-level descriptor encapsulating the hash table root and capacity limit.
Definition
lru.h:51
CacheHeader::cache
struct CacheEntry * cache
Hash root (uthash). NULL when empty.
Definition
lru.h:54
CacheHeader::free_func
void(*) free_func(void *)
Optional callback to free cached values. NULL if not needed.
Definition
lru.h:55
CacheHeader::cur_bytes
uint64_t cur_bytes
Bytes currently held by the cached values.
Definition
lru.h:53
CacheHeader::max_bytes
uint64_t max_bytes
Memory budget in bytes for the cached values. 0 means unlimited.
Definition
lru.h:52
src
lru.c
Generated by
1.18.0