LCOV - code coverage report
Current view: top level - funkier - fd_funkier_val.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 30 0.0 %
Date: 2025-03-20 12:08:36 Functions: 0 1 0.0 %

          Line data    Source code
       1             : #include "fd_funkier.h"
       2             : 
       3             : void *
       4             : fd_funkier_val_truncate( fd_funkier_rec_t * rec,
       5             :                          ulong           new_val_sz,
       6             :                          fd_alloc_t *    alloc,
       7             :                          fd_wksp_t *     wksp,
       8           0 :                          int *           opt_err ) {
       9             : 
      10             :   /* Check input args */
      11             : 
      12             : #ifdef FD_FUNKIER_HANDHOLDING
      13             :   if( FD_UNLIKELY( (!rec) | (new_val_sz>FD_FUNKIER_REC_VAL_MAX) | (!alloc) | (!wksp) ) ||  /* NULL rec,too big,NULL alloc,NULL wksp */
      14             :       FD_UNLIKELY( rec->flags & FD_FUNKIER_REC_FLAG_ERASE                            ) ) { /* Marked erase */
      15             :     fd_int_store_if( !!opt_err, opt_err, FD_FUNKIER_ERR_INVAL );
      16             :     return NULL;
      17             :   }
      18             : #endif
      19             : 
      20           0 :   ulong val_sz = (ulong)rec->val_sz;
      21           0 :   ulong val_max = (ulong)rec->val_max;
      22             : 
      23           0 :   if( FD_UNLIKELY( !new_val_sz ) ) {
      24             : 
      25             :     /* User asked to truncate to 0.  Flush the any existing value. */
      26             : 
      27           0 :     fd_funkier_val_flush( rec, alloc, wksp );
      28             : 
      29           0 :     fd_int_store_if( !!opt_err, opt_err, FD_FUNKIER_SUCCESS );
      30           0 :     return NULL;
      31             : 
      32           0 :   } else if( FD_LIKELY( new_val_sz > val_max ) ) {
      33             : 
      34             :     /* User requested to increase the value size.  We presume they are
      35             :        asking for a specific size (as opposed to bumping up the size ala
      36             :        append) so we don't build in extra padding to amortize the cost
      37             :        of future truncates.  Note that new_val_sz is at least 1 at this
      38             :        point but val_sz / val_gaddr could be zero / zero. */
      39             : 
      40           0 :     ulong   val_gaddr = rec->val_gaddr;
      41           0 :     uchar * val       = val_max ? fd_wksp_laddr_fast( wksp, val_gaddr ) : NULL; /* TODO: branchless */
      42             : 
      43           0 :     ulong   new_val_max;
      44           0 :     uchar * new_val = (uchar *)fd_alloc_malloc_at_least( alloc, FD_FUNKIER_VAL_ALIGN, new_val_sz, &new_val_max );
      45           0 :     if( FD_UNLIKELY( !new_val ) ) { /* Allocation failure! */
      46           0 :       fd_int_store_if( !!opt_err, opt_err, FD_FUNKIER_ERR_MEM );
      47           0 :       return NULL;
      48           0 :     }
      49             : 
      50           0 :     if( val_sz ) fd_memcpy( new_val, val, val_sz ); /* Copy the existing value */
      51           0 :     fd_memset( new_val + val_sz, 0, new_val_max - val_sz ); /* Clear out trailing padding to be on the safe side */
      52             : 
      53           0 :     rec->val_gaddr = fd_wksp_gaddr_fast( wksp, new_val );
      54           0 :     rec->val_sz    = (uint)new_val_sz;
      55           0 :     rec->val_max   = (uint)fd_ulong_min( new_val_max, FD_FUNKIER_REC_VAL_MAX );
      56             : 
      57           0 :     if( val ) fd_alloc_free( alloc, val ); /* Free the old value (if any) */
      58             : 
      59           0 :     fd_int_store_if( !!opt_err, opt_err, FD_FUNKIER_SUCCESS );
      60           0 :     return new_val;
      61             : 
      62           0 :   } else {
      63             : 
      64             :     /* Just set the new size */
      65             : 
      66           0 :     rec->val_sz = (uint)new_val_sz;
      67             : 
      68           0 :     fd_int_store_if( !!opt_err, opt_err, FD_FUNKIER_SUCCESS );
      69           0 :     return (uchar *)fd_wksp_laddr_fast( wksp, rec->val_gaddr );
      70             : 
      71           0 :   }
      72           0 : }
      73             : 
      74             : #ifdef FD_FUNKIER_HANDHOLDING
      75             : int
      76             : fd_funkier_val_verify( fd_funkier_t * funk ) {
      77             :   fd_wksp_t * wksp = fd_funkier_wksp( funk );
      78             :   ulong wksp_tag = funk->wksp_tag;
      79             : 
      80             :   /* At this point, rec_map has been extensively verified */
      81             : 
      82             : # define TEST(c) do {                                                                           \
      83             :     if( FD_UNLIKELY( !(c) ) ) { FD_LOG_WARNING(( "FAIL: %s", #c )); return FD_FUNKIER_ERR_INVAL; } \
      84             :   } while(0)
      85             : 
      86             :   /* Iterate over all records in use */
      87             : 
      88             :   fd_funkier_all_iter_t iter[1];
      89             :   for( fd_funkier_all_iter_new( funk, iter ); !fd_funkier_all_iter_done( iter ); fd_funkier_all_iter_next( iter ) ) {
      90             :     fd_funkier_rec_t const * rec = fd_funkier_all_iter_ele_const( iter );
      91             : 
      92             :     /* Make sure values look sane */
      93             :     /* TODO: consider doing an alias analysis on allocated values?
      94             :        (tricky to do algo efficient in place) */
      95             : 
      96             :     ulong val_sz    = (ulong)rec->val_sz;
      97             :     ulong val_max   = (ulong)rec->val_max;
      98             :     ulong val_gaddr = rec->val_gaddr;
      99             : 
     100             :     TEST( val_sz<=val_max );
     101             : 
     102             :     if( rec->flags & FD_FUNKIER_REC_FLAG_ERASE ) {
     103             :       TEST( !val_max   );
     104             :       TEST( !val_gaddr );
     105             :     } else {
     106             :       TEST( val_max<=FD_FUNKIER_REC_VAL_MAX );
     107             :       if( !val_gaddr ) TEST( !val_max );
     108             :       else {
     109             :         TEST( (0UL<val_max) & (val_max<=FD_FUNKIER_REC_VAL_MAX) );
     110             :         TEST( fd_wksp_tag( wksp, val_gaddr )==wksp_tag );
     111             :       }
     112             :     }
     113             :   }
     114             : 
     115             : # undef TEST
     116             : 
     117             :   return FD_FUNKIER_SUCCESS;
     118             : }
     119             : #endif

Generated by: LCOV version 1.14