Line data Source code
1 : #ifndef HEADER_fd_src_funk_fd_funk_val_h 2 : #define HEADER_fd_src_funk_fd_funk_val_h 3 : 4 : /* This provides APIs for managing funk record values. It is generally 5 : not meant to be included directly. Use fd_funk.h instead. */ 6 : 7 : #include "fd_funk_rec.h" /* Includes fd_funk_txn.h, fd_funk_base.h */ 8 : 9 : /* FD_FUNK_REC_VAL_MAX is the maximum size of a record value. */ 10 : 11 23286633 : #define FD_FUNK_REC_VAL_MAX (UINT_MAX) 12 : #define FD_FUNK_VAL_ALIGN (8UL) 13 : 14 : FD_PROTOTYPES_BEGIN 15 : 16 : /* Accessors */ 17 : 18 : /* fd_funk_val_{sz,max} returns the current size of the value associated 19 : with a record and the amount of wksp allocated currently for a value. 20 : Assumes funk is a current local join. These value might change on 21 : subsequent calls if the record is resized. 22 : 0<=sz<=max<=FD_FUNK_REC_VAL_MAX. */ 23 : 24 : FD_FN_PURE static inline ulong /* Current size of the record's value in bytes */ 25 42241246 : fd_funk_val_sz( fd_funk_rec_t const * rec ) { /* Assumes pointer in caller's address space to a live funk record */ 26 42241246 : return (ulong)rec->val_sz; /* Covers the marked ERASE case too */ 27 42241246 : } 28 : 29 : FD_FN_PURE static inline ulong /* Current size of the record's value allocation in bytes */ 30 0 : fd_funk_val_max( fd_funk_rec_t const * rec ) { /* Assumes pointer in caller's address space to a live funk record */ 31 0 : return (ulong)rec->val_max; /* Covers the marked ERASE case too */ 32 0 : } 33 : 34 : /* fd_funk_val returns a pointer in the caller's address space to the 35 : current value associated with a record. fd_funk_rec_val_const is a 36 : const-correct version. There are sz bytes at the returned pointer. 37 : IMPORTANT SAFETY TIP! There are _no_ alignment guarantees on the 38 : returned value. Returns NULL if the record has a zero sz (which also 39 : covers the case where rec has been marked ERASE). max 0 implies val 40 : NULL and vice versa. Assumes no concurrent operations on rec. */ 41 : 42 : FD_FN_PURE static inline void * /* Lifetime is the lesser of rec or the value size is modified */ 43 : fd_funk_val( fd_funk_rec_t const * rec, /* Assumes pointer in caller's address space to a live funk record */ 44 61003207 : fd_wksp_t const * wksp ) { /* ==fd_funk_wksp( funk ) where funk is a current local join */ 45 61003207 : ulong val_gaddr = rec->val_gaddr; 46 61003207 : if( !val_gaddr ) return NULL; /* Covers the marked ERASE case too */ /* TODO: consider branchless */ 47 59058229 : return fd_wksp_laddr_fast( wksp, val_gaddr ); 48 61003207 : } 49 : 50 : FD_FN_PURE static inline void const * /* Lifetime is the lesser of rec or the value size is modified */ 51 : fd_funk_val_const( fd_funk_rec_t const * rec, /* Assumes pointer in caller's address space to a live funk record */ 52 15 : fd_wksp_t const * wksp ) { /* ==fd_funk_wksp( funk ) where funk is a current local join */ 53 15 : ulong val_gaddr = rec->val_gaddr; 54 15 : if( !val_gaddr ) return NULL; /* Covers the marked ERASE case too */ /* TODO: consider branchless */ 55 15 : return fd_wksp_laddr_fast( wksp, val_gaddr ); 56 15 : } 57 : 58 : /* fd_funk_val_truncate resizes a record to be new_val_sz bytes in 59 : size. 60 : 61 : This function is optimized for the user knowing the actual long term 62 : record size when they call this. 63 : 64 : Regardless of the current and new value sizes, this will 65 : always attempt to resize the record in order to minimize the amount 66 : of excess allocation used by the record. So this function should be 67 : assumed to kill any existing pointers into this record's value 68 : storage. 69 : 70 : Returns a pointer to the value memory on success and NULL on 71 : failure. If opt_err is non-NULL, on return, *opt_err will hold 72 : FD_FUNK_SUCCESS if successful or a FD_FUNK_ERR_* code on 73 : failure. Reasons for failure include FD_FUNK_ERR_INVAL (NULL 74 : rec, too large new_val_sz, rec is marked ERASE) and 75 : FD_FUNK_ERR_MEM (allocation failure, need a larger wksp). On 76 : failure, the current value is unchanged. 77 : 78 : Assumes no concurrent operations on rec. */ 79 : 80 : void * /* Returns record value on success, NULL on failure */ 81 : fd_funk_val_truncate( fd_funk_rec_t * rec, /* Assumed in caller's address space to a live funk record (NULL returns NULL) */ 82 : fd_alloc_t * alloc, /* ==fd_funk_alloc( funk, wksp ) */ 83 : fd_wksp_t * wksp, /* ==fd_funk_wksp( funk ) where funk is current local join */ 84 : ulong align, /* Must be a power of 2. 0 uses the fd_funk_alloc_malloc default alignment. */ 85 : ulong sz, /* Should be in [0,FD_FUNK_REC_VAL_MAX] (returns NULL otherwise) */ 86 : int * opt_err ); /* If non-NULL, *opt_err returns operation error code */ 87 : 88 : /* Misc */ 89 : 90 : /* fd_funk_val_init sets a record with uninitialized value metadata to 91 : the NULL value. Meant for internal use. */ 92 : 93 : static inline fd_funk_rec_t * /* Returns rec */ 94 48418560 : fd_funk_val_init( fd_funk_rec_t * rec ) { /* Assumed record in caller's address space with uninitialized value metadata */ 95 48418560 : rec->val_sz = 0U; 96 48418560 : rec->val_max = 0U; 97 48418560 : rec->val_gaddr = 0UL; 98 48418560 : return rec; 99 48418560 : } 100 : 101 : /* fd_funk_val_flush sets a record to the NULL value, discarding the 102 : current value if any. Meant for internal use. */ 103 : 104 : static inline fd_funk_rec_t * /* Returns rec */ 105 : fd_funk_val_flush( fd_funk_rec_t * rec, /* Assumed live funk record in caller's address space */ 106 : fd_alloc_t * alloc, /* ==fd_funk_alloc( funk, wksp ) */ 107 24516456 : fd_wksp_t * wksp ) { /* ==fd_funk_wksp( funk ) where funk is a current local join */ 108 24516456 : ulong val_gaddr = rec->val_gaddr; 109 24516456 : fd_funk_val_init( rec ); 110 24516456 : if( val_gaddr ) fd_alloc_free( alloc, fd_wksp_laddr_fast( wksp, val_gaddr ) ); 111 24516456 : return rec; 112 24516456 : } 113 : 114 : /* fd_funk_val_verify verifies the record values. Returns 115 : FD_FUNK_SUCCESS if the values appear intact and FD_FUNK_ERR_INVAL if 116 : not (logs details). Meant to be called as part of fd_funk_verify. 117 : As such, it assumes funk is non-NULL, fd_funk_{wksp,rec_map,wksp_tag} 118 : have been verified to work and the rec_map has been verified. */ 119 : 120 : int 121 : fd_funk_val_verify( fd_funk_t * funk ); 122 : 123 : FD_PROTOTYPES_END 124 : 125 : /* TODO: Retune fd_alloc and fd_wksp for Solana record size optimized 126 : size classes and transition point to fd_wksp backing. */ 127 : 128 : #endif /* HEADER_fd_src_funk_fd_funk_val_h */