LCOV - code coverage report
Current view: top level - funk - fd_funk_val.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 48 54 88.9 %
Date: 2026-05-26 08:02:49 Functions: 2 2 100.0 %

          Line data    Source code
       1             : #include "fd_funk_private.h"
       2             : 
       3             : void *
       4             : fd_funk_val_truncate( fd_funk_rec_t * rec,
       5             :                       fd_alloc_t *    alloc,
       6             :                       fd_wksp_t *     wksp,
       7             :                       ulong           align,
       8             :                       ulong           sz,
       9     4285395 :                       int *           opt_err ) {
      10             : 
      11             :   /* Check input args */
      12             : 
      13             : #ifdef FD_FUNK_HANDHOLDING
      14             :   if( FD_UNLIKELY( (!rec) | (sz>FD_FUNK_REC_VAL_MAX) | (!alloc) | (!wksp) ) ||  /* NULL rec,too big,NULL alloc,NULL wksp */
      15             :       FD_UNLIKELY( !fd_ulong_is_pow2( align ) & (align != 0UL)            ) ) { /* Align is not a power of 2 or == 0 */
      16             :     fd_int_store_if( !!opt_err, opt_err, FD_FUNK_ERR_INVAL );
      17             :     return NULL;
      18             :   }
      19             : #endif
      20             : 
      21     4285395 :   ulong val_sz = (ulong)rec->val_sz;
      22     4285395 :   ulong val_max = (ulong)rec->val_max;
      23             : 
      24     4285395 :   if( FD_UNLIKELY( !sz ) ) {
      25             : 
      26             :     /* User asked to truncate to 0.  Flush the any existing value. */
      27             : 
      28           0 :     fd_funk_val_flush( rec, alloc, wksp );
      29             : 
      30           0 :     fd_int_store_if( !!opt_err, opt_err, FD_FUNK_SUCCESS );
      31           0 :     return NULL;
      32             : 
      33     4285395 :   } else if( FD_LIKELY( (sz > val_max) | fd_funk_val_shrink_compacts( sz, val_max ) ) ) {
      34             : 
      35     1277010 :     ulong   val_gaddr = rec->val_gaddr;
      36     1277010 :     uchar * val       = val_max ? fd_wksp_laddr_fast( wksp, val_gaddr ) : NULL; /* TODO: branchless */
      37             : 
      38             :     /* NOTE: if the align is 0, we use the default alignment for
      39             :        fd_alloc_malloc_at_least */
      40     1277010 :     ulong   new_val_max;
      41     1277010 :     uchar * new_val = fd_alloc_malloc_at_least( alloc, align, sz, &new_val_max );
      42     1277010 :     if( FD_UNLIKELY( !new_val ) ) { /* Allocation failure! */
      43           0 :       fd_int_store_if( !!opt_err, opt_err, FD_FUNK_ERR_MEM );
      44           0 :       return NULL;
      45           0 :     }
      46             : 
      47     1277010 :     ulong copy_sz = fd_ulong_min( val_sz, sz );
      48     1277010 :     if( copy_sz ) fd_memcpy( new_val, val, copy_sz ); /* Copy the existing value */
      49     1277010 :     fd_memset( new_val + copy_sz, 0, new_val_max - copy_sz ); /* Clear out trailing padding to be on the safe side */
      50             : 
      51     1277010 :     rec->val_gaddr = fd_wksp_gaddr_fast( wksp, new_val );
      52     1277010 :     rec->val_sz    = (uint)( sz & FD_FUNK_REC_VAL_MAX );
      53     1277010 :     rec->val_max   = (uint)( fd_ulong_min( new_val_max, FD_FUNK_REC_VAL_MAX ) & FD_FUNK_REC_VAL_MAX );
      54             : 
      55     1277010 :     if( val ) fd_alloc_free( alloc, val ); /* Free the old value (if any) */
      56             : 
      57     1277010 :     fd_int_store_if( !!opt_err, opt_err, FD_FUNK_SUCCESS );
      58     1277010 :     return new_val;
      59             : 
      60     3008385 :   } else {
      61             : 
      62             :     /* Just set the new size */
      63             : 
      64     3008385 :     rec->val_sz = (uint)( sz & FD_FUNK_REC_VAL_MAX );
      65             : 
      66     3008385 :     fd_int_store_if( !!opt_err, opt_err, FD_FUNK_SUCCESS );
      67     3008385 :     return (uchar *)fd_wksp_laddr_fast( wksp, rec->val_gaddr );
      68             : 
      69     3008385 :   }
      70     4285395 : }
      71             : 
      72             : int
      73         201 : fd_funk_val_verify( fd_funk_t * funk ) {
      74         201 :   fd_wksp_t * wksp = fd_funk_wksp( funk );
      75         201 :   ulong wksp_tag = funk->shmem->wksp_tag;
      76             : 
      77             :   /* At this point, rec_map has been extensively verified */
      78             : 
      79       53172 : # define TEST(c) do {                                                                           \
      80       53172 :     if( FD_UNLIKELY( !(c) ) ) { FD_LOG_WARNING(( "FAIL: %s", #c )); return FD_FUNK_ERR_INVAL; } \
      81       53172 :   } while(0)
      82             : 
      83             :   /* Iterate over all records in use */
      84             : 
      85         201 :   fd_funk_all_iter_t iter[1];
      86       13494 :   for( fd_funk_all_iter_new( funk, iter ); !fd_funk_all_iter_done( iter ); fd_funk_all_iter_next( iter ) ) {
      87       13293 :     fd_funk_rec_t const * rec = fd_funk_all_iter_ele_const( iter );
      88             : 
      89             :     /* Make sure values look sane */
      90             :     /* TODO: consider doing an alias analysis on allocated values?
      91             :        (tricky to do algo efficient in place) */
      92             : 
      93       13293 :     ulong val_sz    = (ulong)rec->val_sz;
      94       13293 :     ulong val_max   = (ulong)rec->val_max;
      95       13293 :     ulong val_gaddr = rec->val_gaddr;
      96             : 
      97       13293 :     TEST( val_sz<=val_max );
      98             : 
      99       13293 :     TEST( val_max<=FD_FUNK_REC_VAL_MAX );
     100       13293 :     if( !val_gaddr ) TEST( !val_max );
     101       13293 :     else {
     102       13293 :       TEST( (0UL<val_max) & (val_max<=FD_FUNK_REC_VAL_MAX) );
     103       13293 :       TEST( fd_wksp_tag( wksp, val_gaddr )==wksp_tag );
     104       13293 :     }
     105       13293 :   }
     106             : 
     107         201 : # undef TEST
     108             : 
     109         201 :   return FD_FUNK_SUCCESS;
     110         201 : }

Generated by: LCOV version 1.14