Line data Source code
1 : #ifndef HEADER_fd_src_funk_fd_funk_part_h 2 : #define HEADER_fd_src_funk_fd_funk_part_h 3 : 4 : #include "fd_funk_rec.h" 5 : 6 : /* This provides APIs for managing funk record partitions. */ 7 : 8 : struct fd_funk_parthead { 9 : ulong head_idx; /* Record map index of the first record in partition, FD_FUNK_REC_IDX_NULL if none */ 10 : ulong tail_idx; /* " last " */ 11 : }; 12 : 13 : typedef struct fd_funk_parthead fd_funk_parthead_t; 14 : 15 : struct fd_funk_partvec { 16 : uint num_part; /* Number of partitions */ 17 : fd_funk_parthead_t heads[1]; /* Partition headers indexed by partition number */ 18 : }; 19 : 20 : typedef struct fd_funk_partvec fd_funk_partvec_t; 21 : 22 0 : FD_FN_PURE static inline ulong fd_funk_partvec_align(void) { 23 0 : return alignof(fd_funk_partvec_t); 24 0 : } 25 : FD_FN_PURE static inline ulong 26 1569435 : fd_funk_partvec_footprint(uint num_part) { 27 1569435 : return sizeof(fd_funk_partvec_t) + (fd_uint_max(num_part, 1U) - 1U)*sizeof(fd_funk_parthead_t); 28 1569435 : } 29 : 30 : /* Get the partition vector structure which controls the partitions */ 31 : fd_funk_partvec_t * 32 : fd_funk_get_partvec( fd_funk_t * funk, 33 : fd_wksp_t * wksp /* Assumes wksp == fd_funk_wksp( funk ) */); 34 : 35 : /* Initialize partition fields in a record to default values */ 36 : void fd_funk_part_init( fd_funk_rec_t * rec ); 37 : 38 : /* Set the partition number of a record. Use FD_FUNK_PART_NULL to 39 : remove the record from its current partition. Otherwise, the 40 : partition number must be less than the num_part value given in the 41 : last call to fd_funk_repartition. Returns an error code. */ 42 : int fd_funk_part_set_intern( fd_funk_partvec_t * partvec, 43 : fd_funk_rec_t * rec_map, 44 : fd_funk_rec_t * rec, 45 : uint part ); 46 : 47 : int fd_funk_part_set( fd_funk_t * funk, 48 : fd_funk_rec_t * rec, 49 : uint part ); 50 : 51 : /* Resize the partition vector and reassign partition numbers to all 52 : records using a callback function to get the value. num_part must 53 : be a relatively small integer (i.e. < 1,000,000). The internal data 54 : structure if a vector of size num_part. */ 55 : typedef uint (*fd_funk_repartition_cb)(fd_funk_rec_t * rec, uint num_part, void * cb_arg); 56 : 57 : void fd_funk_repartition(fd_funk_t * funk, 58 : uint num_part, 59 : fd_funk_repartition_cb cb, 60 : void * cb_arg); 61 : 62 : /* Resize the partition vector but don't reassign any records. */ 63 : void fd_funk_set_num_partitions( fd_funk_t * funk, 64 : uint num_part ); 65 : 66 : /* Get the first record in the partition. Used for iteration. */ 67 : FD_FN_PURE static inline fd_funk_rec_t const * 68 : fd_funk_part_head( fd_funk_partvec_t * partvec, 69 : uint part, 70 0 : fd_funk_rec_t const * rec_map ) { /* Assumes == fd_funk_rec_map( funk, fd_funk_wksp( funk ) ) */ 71 0 : if( part >= partvec->num_part ) return NULL; 72 0 : ulong rec_head_idx = partvec->heads[part].head_idx; 73 0 : if( fd_funk_rec_idx_is_null( rec_head_idx ) ) return NULL; 74 0 : return rec_map + rec_head_idx; 75 0 : } 76 : 77 : /* Get the next record in the partition. Used for iteration. */ 78 : FD_FN_PURE static inline fd_funk_rec_t const * 79 : fd_funk_part_next( fd_funk_rec_t const * rec, 80 0 : fd_funk_rec_t const * rec_map ) { /* Assumes == fd_funk_rec_map( funk, fd_funk_wksp( funk ) ) */ 81 0 : ulong rec_idx = rec->next_part_idx; 82 0 : if( fd_funk_rec_idx_is_null( rec_idx ) ) return NULL; 83 0 : return rec_map + rec_idx; 84 0 : } 85 : 86 : /* Misc */ 87 : 88 : /* fd_funk_part_verify verifies the partitions. Returns FD_FUNK_SUCCESS 89 : if the record map appears intact and FD_FUNK_ERR_INVAL if not (logs 90 : details). Meant to be called as part of fd_funk_verify. */ 91 : 92 : int 93 : fd_funk_part_verify( fd_funk_t * funk ); 94 : 95 : #endif /* HEADER_fd_src_funk_fd_funk_part_h */