@@ -111,12 +111,14 @@ export fn ddac_cache_init(
111111 .allocator = allocator ,
112112 };
113113
114+ // SAFETY: state was just allocated by c_allocator.create(CacheState), which returns a well-aligned *CacheState
114115 return @ptrCast (state );
115116}
116117
117118/// Free the LMDB cache. Safe to call with null.
118119export fn ddac_cache_free (handle : ? * anyopaque ) void {
119120 const ptr = handle orelse return ;
121+ // SAFETY: ptr originates from ddac_cache_init() which stores a *CacheState via @ptrCast; alignment is guaranteed by c_allocator
120122 const state : * CacheState = @ptrCast (@alignCast (ptr ));
121123
122124 lmdb .mdb_env_close (state .env );
@@ -139,6 +141,7 @@ export fn ddac_cache_lookup(
139141 result_size : usize ,
140142) c_int {
141143 const ptr = handle orelse return 0 ;
144+ // SAFETY: ptr originates from ddac_cache_init() which stores a *CacheState via @ptrCast; alignment is guaranteed by c_allocator
142145 const state : * CacheState = @ptrCast (@alignCast (ptr ));
143146 const path = doc_path orelse return 0 ;
144147 const out = result_out orelse return 0 ;
@@ -150,6 +153,8 @@ export fn ddac_cache_lookup(
150153
151154 // Look up by path
152155 const path_slice = std .mem .span (path );
156+ // SAFETY: @constCast is required by LMDB's C API which takes void* for keys; the data is only read, never written by mdb_get
157+ // SAFETY: @ptrCast converts [*]const u8 to *anyopaque as required by MDB_val.mv_data field
153158 var key = lmdb.MDB_val { .mv_size = path_slice .len , .mv_data = @constCast (@ptrCast (path_slice .ptr )) };
154159 var data : lmdb.MDB_val = undefined ;
155160
@@ -160,6 +165,7 @@ export fn ddac_cache_lookup(
160165 if (data .mv_size < expected_size ) return 0 ;
161166
162167 // Check mtime and file_size
168+ // SAFETY: LMDB mdb_get returns mv_data pointing into the memory-mapped database; valid for the transaction lifetime
163169 const value_bytes : [* ]const u8 = @ptrCast (data .mv_data );
164170 const cached_mtime = std .mem .readInt (i64 , value_bytes [0.. 8], .little );
165171 const cached_size = std .mem .readInt (i64 , value_bytes [8.. 16], .little );
@@ -187,6 +193,7 @@ export fn ddac_cache_store(
187193 result_size : usize ,
188194) void {
189195 const ptr = handle orelse return ;
196+ // SAFETY: ptr originates from ddac_cache_init() which stores a *CacheState via @ptrCast; alignment is guaranteed by c_allocator
190197 const state : * CacheState = @ptrCast (@alignCast (ptr ));
191198 const path = doc_path orelse return ;
192199 const result_bytes = result orelse return ;
@@ -205,7 +212,10 @@ export fn ddac_cache_store(
205212 if (lmdb .mdb_txn_begin (state .env , null , 0 , & txn ) != 0 ) return ;
206213
207214 const path_slice = std .mem .span (path );
215+ // SAFETY: @constCast is required by LMDB's C API which takes void* for keys; the data is only read, never written by mdb_put for keys
216+ // SAFETY: @ptrCast converts [*]const u8 to *anyopaque as required by MDB_val.mv_data field
208217 var key = lmdb.MDB_val { .mv_size = path_slice .len , .mv_data = @constCast (@ptrCast (path_slice .ptr )) };
218+ // SAFETY: value_buf is a stack-allocated array; @ptrCast converts *[N]u8 to *anyopaque for MDB_val.mv_data; valid for the transaction scope
209219 var data = lmdb.MDB_val { .mv_size = value_size , .mv_data = @ptrCast (& value_buf ) };
210220
211221 if (lmdb .mdb_put (txn , state .dbi , & key , & data , 0 ) != 0 ) {
@@ -219,6 +229,7 @@ export fn ddac_cache_store(
219229/// Return the number of entries in the cache.
220230export fn ddac_cache_count (handle : ? * anyopaque ) u64 {
221231 const ptr = handle orelse return 0 ;
232+ // SAFETY: ptr originates from ddac_cache_init() which stores a *CacheState via @ptrCast; alignment is guaranteed by c_allocator
222233 const state : * CacheState = @ptrCast (@alignCast (ptr ));
223234
224235 var txn : ? * lmdb.MDB_txn = null ;
@@ -235,6 +246,7 @@ export fn ddac_cache_count(handle: ?*anyopaque) u64 {
235246/// Call this periodically for durability or before graceful shutdown.
236247export fn ddac_cache_sync (handle : ? * anyopaque ) void {
237248 const ptr = handle orelse return ;
249+ // SAFETY: ptr originates from ddac_cache_init() which stores a *CacheState via @ptrCast; alignment is guaranteed by c_allocator
238250 const state : * CacheState = @ptrCast (@alignCast (ptr ));
239251 _ = lmdb .mdb_env_sync (state .env , 1 );
240252}
0 commit comments