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: consider aligning key 16 or 32 and/or AVX accelerating? */ 48 : 49 : #define FD_GROOVE_KEY_ALIGN (8UL) 50 132020616 : #define FD_GROOVE_KEY_FOOTPRINT (32UL) 51 : 52 : union __attribute__((aligned(FD_GROOVE_KEY_ALIGN))) fd_groove_key { 53 : char c[ FD_GROOVE_KEY_FOOTPRINT ]; 54 : uchar uc[ FD_GROOVE_KEY_FOOTPRINT ]; 55 : ulong ul[ FD_GROOVE_KEY_FOOTPRINT / sizeof(ulong) ]; 56 : }; 57 : 58 : typedef union fd_groove_key fd_groove_key_t; 59 : 60 : FD_PROTOTYPES_BEGIN 61 : 62 : /* fd_groove_key_init initializes the key pointed to by k to src_sz 63 : bytes pointed ito by src. If src_sz is {less than,greater than} 64 : FD_GROOVE_KEY_FOOTPRINT, it will be {zero padded,truncated} to 65 : FD_GROOVE_KEY_FOOTPRINT bytes. Assumes k and src point to valid 66 : non-overlapping regions in the caller's address stable for the 67 : duration of the call. Retains no interest in k or src. Returns k. */ 68 : 69 : static inline fd_groove_key_t * 70 : fd_groove_key_init( fd_groove_key_t * k, 71 : void const * FD_RESTRICT src, 72 6000000 : ulong src_sz ) { 73 6000000 : void * FD_RESTRICT dst = k->c; 74 6000000 : ulong csz = fd_ulong_min( src_sz, FD_GROOVE_KEY_FOOTPRINT ); /* typically compile time */ 75 6000000 : ulong zsz = FD_GROOVE_KEY_FOOTPRINT - csz; /* " */ 76 6000000 : if( zsz ) memset( dst, 0, FD_GROOVE_KEY_FOOTPRINT ); /* " */ 77 6000000 : if( csz ) memcpy( dst, src, csz ); /* " */ 78 6000000 : return k; 79 6000000 : } 80 : 81 : /* fd_groove_key_ulong initializes the key pointed to by k with the 82 : ulongs k0, k1, k2, and k3. Assumes k points in the caller's address 83 : space to the location to store the key. Retains no interest in k. 84 : Returns k. */ 85 : 86 : static inline fd_groove_key_t * 87 : fd_groove_key_init_ulong( fd_groove_key_t * k, 88 : ulong k0, 89 : ulong k1, 90 : ulong k2, 91 13498173 : ulong k3 ) { 92 13498173 : k->ul[0] = k0; k->ul[1] = k1; k->ul[2] = k2; k->ul[3] = k3; 93 13498173 : return k; 94 13498173 : } 95 : 96 : /* fd_groove_key_eq tests keys ka and kb for equality. Assumes ka and 97 : kb point in the caller's address space to valid keys for the duration 98 : of the call. Retains no interest in ka or kb. Returns 1 if the keys 99 : are equal and 0 otherwise. */ 100 : 101 : FD_FN_PURE static inline int 102 : fd_groove_key_eq( fd_groove_key_t const * ka, 103 51219165 : fd_groove_key_t const * kb ) { 104 51219165 : ulong const * a = ka->ul; 105 51219165 : ulong const * b = kb->ul; 106 51219165 : return !(((a[0]^b[0]) | (a[1]^b[1])) | ((a[2]^b[2]) | (a[3]^b[3]))); /* tons of ILP and vectorizable */ 107 51219165 : } 108 : 109 : /* fd_groove_key_hash provides a family of hashes that hash the key 110 : pointed to by k to a uniform quasi-random 64-bit integer. seed 111 : selects the particular hash function to use and can be an arbitrary 112 : 64-bit value. The hash functions are high quality but not 113 : cryptographically secure. Assumes ka points in the caller's address 114 : space to a valid key for the duration of the call. Retains no 115 : interest in ka. Returns the hash. */ 116 : 117 : FD_FN_UNUSED FD_FN_PURE static ulong /* Workaround -Winline */ 118 : fd_groove_key_hash( fd_groove_key_t const * ka, 119 48821844 : ulong seed ) { 120 48821844 : ulong const * a = ka->ul; 121 48821844 : return (fd_ulong_hash( a[0] ^ seed ) ^ fd_ulong_hash( a[1] ^ seed )) ^ 122 48821844 : (fd_ulong_hash( a[2] ^ seed ) ^ fd_ulong_hash( a[3] ^ seed )); /* tons of ILP and vectorizable */ 123 48821844 : } 124 : 125 : FD_PROTOTYPES_END 126 : 127 : /* fd_groove_block API ************************************************/ 128 : 129 : /* Groove data objects are backed by FD_GROOVE_BLOCK_ALIGN aligned 130 : FD_GROOVE_BLOCK_FOOTPRINT byte blocks. ALIGN==FOOTPRINT and are a 131 : power of 2. 512 is used for tight coupling to typical HPC I/O API, 132 : operating system, driver and hardware limits. */ 133 : 134 159938490 : #define FD_GROOVE_BLOCK_ALIGN (512UL) 135 236790330 : #define FD_GROOVE_BLOCK_FOOTPRINT (512UL) 136 : 137 : #endif /* HEADER_fd_src_groove_fd_groove_base_h */