Repository: valkey-io/valkey
File: src/lazyfree.c (C)

Code before:
void lazyFreeFunctionsCtx(void *args[]) {
    functionsLibCtx *functions_lib_ctx = args[0];
    list *engine_callbacks = args[1];
    size_t len = functionsLibCtxFunctionsLen(functions_lib_ctx);
    functionsLibCtxFree(functions_lib_ctx, NULL, engine_callbacks);
    atomic_fetch_sub_explicit(&lazyfree_objects, len, memory_order_relaxed);
    atomic_fetch_add_explicit(&lazyfreed_objects, len, memory_order_relaxed);
}

/* Release replication backlog referencing memory. */
void lazyFreeReplicationBacklogRefMem(void *args[]) {
    list *blocks = args[0];
    rax *index = args[1];
    long long len = listLength(blocks);
    len += raxSize(index);
    listRelease(blocks);
    raxFree(index);
    atomic_fetch_sub_explicit(&lazyfree_objects, len, memory_order_relaxed);
    atomic_fetch_add_explicit(&lazyfreed_objects, len, memory_order_relaxed);
}

/* Release the replicaKeysWithExpire dict. */
void lazyFreeReplicaKeysWithExpire(void *args[]) {
    dict *replica_keys_with_expire = args[0];
    dictRelease(replica_keys_with_expire);
}

/* Return the number of currently pending objects to free. */
size_t lazyfreeGetPendingObjectsCount(void) {
    size_t aux = atomic_load_explicit(&lazyfree_objects, memory_order_relaxed);
    return aux;
}

/* Return the number of objects that have been freed. */
size_t lazyfreeGetFreedObjectsCount(void) {
    size_t aux = atomic_load_explicit(&lazyfreed_objects, memory_order_relaxed);
    return aux;
}

void lazyfreeResetStats(void) {
    atomic_store_explicit(&lazyfreed_objects, 0, memory_order_relaxed);
}

/* Return the amount of work needed in order to free an object.
 * The return value is not always the actual number of allocations the
 * object is composed of, but a number proportional to it.
 *
 * For strings the function always returns 1.
 *
 * For aggregated objects represented by hash tables or other data structures
 * the function just returns the number of elements the object is composed of.

Review comment (suggestion):
```suggestion
    dict *replica_keys_with_expire = args[0];
    size_t len = dictSize(replica_keys_with_expire);
    dictRelease(replica_keys_with_expire);
    atomic_fetch_sub_explicit(&lazyfree_objects, len, memory_order_relaxed);
    atomic_fetch_add_explicit(&lazyfreed_objects, len, memory_order_relaxed);
```

Code after:
void lazyFreeFunctionsCtx(void *args[]) {
    functionsLibCtx *functions_lib_ctx = args[0];
    list *engine_callbacks = args[1];
    size_t len = functionsLibCtxFunctionsLen(functions_lib_ctx);
    functionsLibCtxFree(functions_lib_ctx, NULL, engine_callbacks);
    atomic_fetch_sub_explicit(&lazyfree_objects, len, memory_order_relaxed);
    atomic_fetch_add_explicit(&lazyfreed_objects, len, memory_order_relaxed);
}

/* Release replication backlog referencing memory. */
void lazyFreeReplicationBacklogRefMem(void *args[]) {
    list *blocks = args[0];
    rax *index = args[1];
    long long len = listLength(blocks);
    len += raxSize(index);
    listRelease(blocks);
    raxFree(index);
    atomic_fetch_sub_explicit(&lazyfree_objects, len, memory_order_relaxed);
    atomic_fetch_add_explicit(&lazyfreed_objects, len, memory_order_relaxed);
}

/* Release the replicaKeysWithExpire dict. */
void lazyFreeReplicaKeysWithExpire(void *args[]) {
    dict *replica_keys_with_expire = args[0];
    size_t len = dictSize(replica_keys_with_expire);
    dictRelease(replica_keys_with_expire);
    atomic_fetch_sub_explicit(&lazyfree_objects, len, memory_order_relaxed);
    atomic_fetch_add_explicit(&lazyfreed_objects, len, memory_order_relaxed);
}

/* Return the number of currently pending objects to free. */
size_t lazyfreeGetPendingObjectsCount(void) {
    size_t aux = atomic_load_explicit(&lazyfree_objects, memory_order_relaxed);
    return aux;
}

/* Return the number of objects that have been freed. */
size_t lazyfreeGetFreedObjectsCount(void) {
    size_t aux = atomic_load_explicit(&lazyfreed_objects, memory_order_relaxed);
    return aux;
}

void lazyfreeResetStats(void) {
    atomic_store_explicit(&lazyfreed_objects, 0, memory_order_relaxed);
}

/* Return the amount of work needed in order to free an object.
 * The return value is not always the actual number of allocations the
 * object is composed of, but a number proportional to it.
 *
 * For strings the function always returns 1.