Line data Source code
1 : #ifndef HEADER_fd_src_funk_fd_funkier_val_h 2 : #define HEADER_fd_src_funk_fd_funkier_val_h 3 : 4 : /* This provides APIs for managing funk record values. It is generally 5 : not meant to be included directly. Use fd_funkier.h instead. */ 6 : 7 : #include "fd_funkier_rec.h" /* Includes fd_funkier_txn.h, fd_funkier_base.h */ 8 : 9 : /* FD_FUNKIER_REC_VAL_MAX is the maximum size of a record value. */ 10 : 11 0 : #define FD_FUNKIER_REC_VAL_MAX UINT_MAX 12 0 : #define FD_FUNKIER_VAL_ALIGN 8UL 13 : 14 : FD_PROTOTYPES_BEGIN 15 : 16 : /* Accessors */ 17 : 18 : /* fd_funkier_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_FUNKIER_REC_VAL_MAX. */ 23 : 24 : FD_FN_PURE static inline ulong /* Current size of the record's value in bytes */ 25 0 : fd_funkier_val_sz( fd_funkier_rec_t const * rec ) { /* Assumes pointer in caller's address space to a live funk record */ 26 0 : return (ulong)rec->val_sz; /* Covers the marked ERASE case too */ 27 0 : } 28 : 29 : FD_FN_PURE static inline ulong /* Current size of the record's value allocation in bytes */ 30 0 : fd_funkier_val_max( fd_funkier_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_funkier_val returns a pointer in the caller's address space to the 35 : current value associated with a record. fd_funkier_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_funkier_val( fd_funkier_rec_t const * rec, /* Assumes pointer in caller's address space to a live funk record */ 44 0 : fd_wksp_t const * wksp ) { /* ==fd_funkier_wksp( funk ) where funk is a current local join */ 45 0 : ulong val_gaddr = rec->val_gaddr; 46 0 : if( !val_gaddr ) return NULL; /* Covers the marked ERASE case too */ /* TODO: consider branchless */ 47 0 : return fd_wksp_laddr_fast( wksp, val_gaddr ); 48 0 : } 49 : 50 : FD_FN_PURE static inline void const * /* Lifetime is the lesser of rec or the value size is modified */ 51 : fd_funkier_val_const( fd_funkier_rec_t const * rec, /* Assumes pointer in caller's address space to a live funk record */ 52 0 : fd_wksp_t const * wksp ) { /* ==fd_funkier_wksp( funk ) where funk is a current local join */ 53 0 : ulong val_gaddr = rec->val_gaddr; 54 0 : if( !val_gaddr ) return NULL; /* Covers the marked ERASE case too */ /* TODO: consider branchless */ 55 0 : return fd_wksp_laddr_fast( wksp, val_gaddr ); 56 0 : } 57 : 58 : /* fd_funkier_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_FUNKIER_SUCCESS if successful or a FD_FUNKIER_ERR_* code on 73 : failure. Reasons for failure include FD_FUNKIER_ERR_INVAL (NULL 74 : rec, too large new_val_sz, rec is marked ERASE) and 75 : FD_FUNKIER_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_funkier_val_truncate( fd_funkier_rec_t * rec, /* Assumed in caller's address space to a live funk record (NULL returns NULL) */ 82 : ulong new_val_sz, /* Should be in [0,FD_FUNKIER_REC_VAL_MAX] (returns NULL otherwise) */ 83 : fd_alloc_t * alloc, /* ==fd_funkier_alloc( funk, wksp ) */ 84 : fd_wksp_t * wksp, /* ==fd_funkier_wksp( funk ) where funk is current local join */ 85 : int * opt_err ); /* If non-NULL, *opt_err returns operation error code */ 86 : 87 : /* Misc */ 88 : 89 : /* fd_funkier_val_init sets a record with uninitialized value metadata to 90 : the NULL value. Meant for internal use. */ 91 : 92 : static inline fd_funkier_rec_t * /* Returns rec */ 93 0 : fd_funkier_val_init( fd_funkier_rec_t * rec ) { /* Assumed record in caller's address space with uninitialized value metadata */ 94 0 : rec->val_sz = 0U; 95 0 : rec->val_max = 0U; 96 0 : rec->val_gaddr = 0UL; 97 0 : return rec; 98 0 : } 99 : 100 : /* fd_funkier_val_flush sets a record to the NULL value, discarding the 101 : current value if any. Meant for internal use. */ 102 : 103 : static inline fd_funkier_rec_t * /* Returns rec */ 104 : fd_funkier_val_flush( fd_funkier_rec_t * rec, /* Assumed live funk record in caller's address space */ 105 : fd_alloc_t * alloc, /* ==fd_funkier_alloc( funk, wksp ) */ 106 0 : fd_wksp_t * wksp ) { /* ==fd_funkier_wksp( funk ) where funk is a current local join */ 107 0 : ulong val_gaddr = rec->val_gaddr; 108 0 : fd_funkier_val_init( rec ); 109 0 : if( val_gaddr ) fd_alloc_free( alloc, fd_wksp_laddr_fast( wksp, val_gaddr ) ); 110 0 : return rec; 111 0 : } 112 : 113 : #ifdef FD_FUNKIER_HANDHOLDING 114 : 115 : /* fd_funkier_val_verify verifies the record values. Returns 116 : FD_FUNKIER_SUCCESS if the values appear intact and FD_FUNKIER_ERR_INVAL if 117 : not (logs details). Meant to be called as part of fd_funkier_verify. 118 : As such, it assumes funk is non-NULL, fd_funkier_{wksp,rec_map,wksp_tag} 119 : have been verified to work and the rec_map has been verified. */ 120 : 121 : int 122 : fd_funkier_val_verify( fd_funkier_t * funk ); 123 : 124 : #endif 125 : 126 : FD_PROTOTYPES_END 127 : 128 : /* TODO: Retune fd_alloc and fd_wksp for Solana record size optimized 129 : size classes and transition point to fd_wksp backing. */ 130 : 131 : #endif /* HEADER_fd_src_funk_fd_funkier_val_h */