Line data Source code
1 : #ifndef HEADER_fd_src_groove_fd_groove_base_h 2 : #define HEADER_fd_src_groove_fd_groove_base_h 3 : 4 : #include "../util/fd_util.h" 5 : 6 : /* FD_GROOVE_PARANOID enables extra integrity checking in various 7 : operations. */ 8 : 9 : #ifndef FD_GROOVE_PARANOID 10 : #define FD_GROOVE_PARANOID 1 11 : #endif 12 : 13 : /* fd_groove error code API *******************************************/ 14 : 15 : /* Note: Harmonized with fd_*_para error codes */ 16 : 17 6670971 : #define FD_GROOVE_SUCCESS (0) 18 51 : #define FD_GROOVE_ERR_INVAL (-1) 19 3 : #define FD_GROOVE_ERR_AGAIN (-2) 20 3 : #define FD_GROOVE_ERR_CORRUPT (-3) 21 3 : #define FD_GROOVE_ERR_EMPTY (-4) 22 2107311 : #define FD_GROOVE_ERR_FULL (-5) 23 3 : #define FD_GROOVE_ERR_KEY (-6) 24 : 25 : FD_PROTOTYPES_BEGIN 26 : 27 : /* fd_groove_strerror converts an FD_GROOVE_SUCCESS / FD_GROOVE_ERR_* 28 : code into a human readable cstr. The lifetime of the returned 29 : pointer is infinite. The returned pointer is always to a non-NULL 30 : cstr. */ 31 : 32 : FD_FN_CONST char const * 33 : fd_groove_strerror( int err ); 34 : 35 : FD_PROTOTYPES_END 36 : 37 : /* fd_groove_key API **************************************************/ 38 : 39 : /* A fd_groove_key_t identifies a groove record. Compact binary keys 40 : are encouraged but a cstr can be used so long as it has 41 : strlen(cstr)<FD_FUNK_REC_KEY_FOOTPRINT and the characters c[i] for i 42 : in [strlen(cstr),FD_FUNK_REC_KEY_FOOTPRINT) are zero. (Also, if 43 : encoding a cstr in a key, recommend using first byte to encode the 44 : strlen for accelerating cstr operations further but this is up to the 45 : user.) */ 46 : 47 : /* FIXME: binary compat with funk key? */ 48 : /* FIXME: consider aligning key 16 or 32 and/or AVX accelerating? */ 49 : 50 : #define FD_GROOVE_KEY_ALIGN (8UL) 51 73510308 : #define FD_GROOVE_KEY_FOOTPRINT (32UL) 52 : 53 : union __attribute__((aligned(FD_GROOVE_KEY_ALIGN))) fd_groove_key { 54 : char c[ FD_GROOVE_KEY_FOOTPRINT ]; 55 : uchar uc[ FD_GROOVE_KEY_FOOTPRINT ]; 56 : ulong ul[ FD_GROOVE_KEY_FOOTPRINT / sizeof(ulong) ]; 57 : }; 58 : 59 : typedef union fd_groove_key fd_groove_key_t; 60 : 61 : FD_PROTOTYPES_BEGIN 62 : 63 : /* fd_groove_key_init initializes the key pointed to by k to src_sz 64 : bytes pointed ito by src. If src_sz is {less than,greater than} 65 : FD_GROOVE_KEY_FOOTPRINT, it will be {zero padded,truncated} to 66 : FD_GROOVE_KEY_FOOTPRINT bytes. Assumes k and src point to valid 67 : non-overlapping regions in the caller's address stable for the 68 : duration of the call. Retains no interest in k or src. Returns k. */ 69 : 70 : static inline fd_groove_key_t * 71 : fd_groove_key_init( fd_groove_key_t * k, 72 : void const * FD_RESTRICT src, 73 6000000 : ulong src_sz ) { 74 6000000 : void * FD_RESTRICT dst = k->c; 75 6000000 : ulong csz = fd_ulong_min( src_sz, FD_GROOVE_KEY_FOOTPRINT ); /* typically compile time */ 76 6000000 : ulong zsz = FD_GROOVE_KEY_FOOTPRINT - csz; /* " */ 77 6000000 : if( zsz ) memset( dst, 0, FD_GROOVE_KEY_FOOTPRINT ); /* " */ 78 6000000 : if( csz ) memcpy( dst, src, csz ); /* " */ 79 6000000 : return k; 80 6000000 : } 81 : 82 : /* fd_groove_key_ulong initializes the key pointed to by k with the 83 : ulongs k0, k1, k2, and k3. Assumes k points in the caller's address 84 : space to the location to store the key. Retains no interest in k. 85 : Returns k. */ 86 : 87 : static inline fd_groove_key_t * 88 : fd_groove_key_init_ulong( fd_groove_key_t * k, 89 : ulong k0, 90 : ulong k1, 91 : ulong k2, 92 13498173 : ulong k3 ) { 93 13498173 : k->ul[0] = k0; k->ul[1] = k1; k->ul[2] = k2; k->ul[3] = k3; 94 13498173 : return k; 95 13498173 : } 96 : 97 : /* fd_groove_key_eq tests keys ka and kb for equality. Assumes ka and 98 : kb point in the caller's address space to valid keys for the duration 99 : of the call. Retains no interest in ka or kb. Returns 1 if the keys 100 : are equal and 0 otherwise. */ 101 : 102 : FD_FN_PURE static inline int 103 : fd_groove_key_eq( fd_groove_key_t const * ka, 104 51219165 : fd_groove_key_t const * kb ) { 105 51219165 : ulong const * a = ka->ul; 106 51219165 : ulong const * b = kb->ul; 107 51219165 : return !(((a[0]^b[0]) | (a[1]^b[1])) | ((a[2]^b[2]) | (a[3]^b[3]))); /* tons of ILP and vectorizable */ 108 51219165 : } 109 : 110 : /* fd_groove_key_hash provides a family of hashes that hash the key 111 : pointed to by k to a uniform quasi-random 64-bit integer. seed 112 : selects the particular hash function to use and can be an arbitrary 113 : 64-bit value. The hash functions are high quality but not 114 : cryptographically secure. Assumes ka points in the caller's address 115 : space to a valid key for the duration of the call. Retains no 116 : interest in ka. Returns the hash. */ 117 : 118 : FD_FN_UNUSED FD_FN_PURE static ulong /* Workaround -Winline */ 119 : fd_groove_key_hash( fd_groove_key_t const * ka, 120 46946271 : ulong seed ) { 121 46946271 : ulong const * a = ka->ul; 122 46946271 : return (fd_ulong_hash( a[0] ^ seed ) ^ fd_ulong_hash( a[1] ^ seed )) ^ 123 46946271 : (fd_ulong_hash( a[2] ^ seed ) ^ fd_ulong_hash( a[3] ^ seed )); /* tons of ILP and vectorizable */ 124 46946271 : } 125 : 126 : FD_PROTOTYPES_END 127 : 128 : /* fd_groove_block API ************************************************/ 129 : 130 : /* Groove data objects are backed by FD_GROOVE_BLOCK_ALIGN aligned 131 : FD_GROOVE_BLOCK_FOOTPRINT byte blocks. ALIGN==FOOTPRINT and are a 132 : power of 2. 512 is used for tight coupling to typical HPC I/O API, 133 : operating system, driver and hardware limits. */ 134 : 135 159938490 : #define FD_GROOVE_BLOCK_ALIGN (512UL) 136 236790330 : #define FD_GROOVE_BLOCK_FOOTPRINT (512UL) 137 : 138 : #endif /* HEADER_fd_src_groove_fd_groove_base_h */