|
| 1 | +#include "fd_vinyl.h" |
| 2 | + |
| 3 | +ulong |
| 4 | +fd_vinyl_align( void ) { |
| 5 | + return alignof(fd_vinyl_t); |
| 6 | +} |
| 7 | + |
| 8 | +ulong |
| 9 | +fd_vinyl_footprint( void ) { |
| 10 | + return sizeof(fd_vinyl_t); |
| 11 | +} |
| 12 | + |
| 13 | +fd_vinyl_t * |
| 14 | +fd_vinyl_init( fd_tpool_t * tpool, ulong t0, ulong t1, int level, |
| 15 | + void * _vinyl, |
| 16 | + void * _cnc, ulong cnc_footprint, |
| 17 | + void * _meta, ulong meta_footprint, |
| 18 | + void * _line, ulong line_footprint, |
| 19 | + void * _ele, ulong ele_footprint, |
| 20 | + void * _obj, ulong obj_footprint, |
| 21 | + fd_vinyl_io_t * io, |
| 22 | + ulong seed, |
| 23 | + void * obj_laddr0, |
| 24 | + ulong async_min, |
| 25 | + ulong async_max, |
| 26 | + ulong part_thresh, |
| 27 | + ulong gc_thresh, |
| 28 | + int gc_eager, |
| 29 | + int style ) { |
| 30 | + if( t1<=t0 ) t0 = 0UL, t1 = 1UL; |
| 31 | + |
| 32 | + FD_LOG_NOTICE(( "Testing vinyl configuration" )); |
| 33 | + |
| 34 | +# define TEST( c ) do { if( FD_UNLIKELY( !(c) ) ) { FD_LOG_WARNING(( "FAIL: %s", #c )); return NULL; } } while(0) |
| 35 | + |
| 36 | + TEST( _vinyl ); TEST( fd_ulong_is_aligned( (ulong)_vinyl, fd_vinyl_align() ) ); |
| 37 | + TEST( _cnc ); TEST( fd_ulong_is_aligned( (ulong)_cnc, fd_cnc_align() ) ); |
| 38 | + TEST( _meta ); TEST( fd_ulong_is_aligned( (ulong)_meta, fd_vinyl_meta_align() ) ); |
| 39 | + TEST( _line ); TEST( fd_ulong_is_aligned( (ulong)_line, alignof(fd_vinyl_line_t) ) ); |
| 40 | + TEST( _ele ); TEST( fd_ulong_is_aligned( (ulong)_ele, alignof(fd_vinyl_meta_ele_t) ) ); |
| 41 | + TEST( _obj ); TEST( fd_ulong_is_aligned( (ulong)_obj, alignof(fd_vinyl_data_obj_t) ) ); |
| 42 | + |
| 43 | + TEST( cnc_footprint >= fd_cnc_footprint( FD_VINYL_CNC_APP_SZ ) ); |
| 44 | + |
| 45 | + ulong ele_max = fd_ulong_pow2_dn( ele_footprint / sizeof( fd_vinyl_meta_ele_t ) ); |
| 46 | + ulong lock_cnt = fd_vinyl_meta_lock_cnt_est( ele_max ); |
| 47 | + ulong probe_max = ele_max; |
| 48 | + |
| 49 | + TEST( ele_max>=4UL ); |
| 50 | + TEST( meta_footprint >= fd_vinyl_meta_footprint( ele_max, lock_cnt, probe_max ) ); |
| 51 | + |
| 52 | + ulong pair_max = ele_max - 1UL; |
| 53 | + ulong line_cnt = fd_ulong_min( line_footprint / sizeof( fd_vinyl_line_t ), pair_max ); |
| 54 | + |
| 55 | + TEST( (3UL<=line_cnt) & (line_cnt<=FD_VINYL_LINE_MAX) ); |
| 56 | + |
| 57 | + TEST( io ); |
| 58 | + |
| 59 | + /* seed is arb */ |
| 60 | + |
| 61 | + TEST( (0UL<async_min) & (async_min<=async_max) ); |
| 62 | + |
| 63 | + /* part_thresh is arb */ |
| 64 | + |
| 65 | + /* gc_thresh is arb */ |
| 66 | + |
| 67 | + TEST( (-1<=gc_eager) & (gc_eager<=63) ); |
| 68 | + |
| 69 | + TEST( (style==FD_VINYL_BSTREAM_CTL_STYLE_RAW) | (style==FD_VINYL_BSTREAM_CTL_STYLE_LZ4) ); |
| 70 | + |
| 71 | + FD_LOG_NOTICE(( "Vinyl config" |
| 72 | + "\n\tline_cnt %lu pairs" |
| 73 | + "\n\tpair_max %lu pairs" |
| 74 | + "\n\tseed 0x%016lx" |
| 75 | + "\n\tasync_min %lu min iterations per async" |
| 76 | + "\n\tasync_max %lu max iterations per async" |
| 77 | + "\n\tpart_thresh %lu bytes" |
| 78 | + "\n\tgc_thresh %lu bytes" |
| 79 | + "\n\tgc_eager %i" |
| 80 | + "\n\tstyle \"%s\" (0x%x)", |
| 81 | + line_cnt, pair_max, seed, async_min, async_max, part_thresh, gc_thresh, gc_eager, |
| 82 | + fd_vinyl_bstream_ctl_style_cstr( style ), (uint)style )); |
| 83 | + |
| 84 | + fd_vinyl_t * vinyl = (fd_vinyl_t *)_vinyl; |
| 85 | + |
| 86 | + /* Note that fd_vinyl_meta_new does not initialize the underlying meta |
| 87 | + element cache. Similarly, fd_vinyl_data_init does not initialize |
| 88 | + the underlying data object cache. Those initializations are |
| 89 | + handled (and then massively thread parallel) by the recover below. */ |
| 90 | + |
| 91 | + memset( vinyl, 0, fd_vinyl_footprint() ); |
| 92 | + |
| 93 | + vinyl->cnc = fd_cnc_join( fd_cnc_new( _cnc, FD_VINYL_CNC_APP_SZ, FD_VINYL_CNC_TYPE, fd_log_wallclock() ) ); TEST( vinyl->cnc ); |
| 94 | + vinyl->line = (fd_vinyl_line_t *)_line; |
| 95 | + vinyl->io = io; |
| 96 | + |
| 97 | + vinyl->line_cnt = line_cnt; |
| 98 | + vinyl->pair_max = pair_max; |
| 99 | + vinyl->async_min = async_min; |
| 100 | + vinyl->async_max = async_max; |
| 101 | + |
| 102 | + vinyl->part_thresh = part_thresh; |
| 103 | + vinyl->gc_thresh = gc_thresh; |
| 104 | + vinyl->gc_eager = gc_eager; |
| 105 | + vinyl->style = style; |
| 106 | + vinyl->line_idx_lru = 0U; |
| 107 | + vinyl->pair_cnt = 0UL; |
| 108 | + vinyl->garbage_sz = 0UL; |
| 109 | + |
| 110 | + TEST( fd_vinyl_meta_join( vinyl->meta, fd_vinyl_meta_new( _meta, ele_max, lock_cnt, probe_max, seed ), _ele )==vinyl->meta ); |
| 111 | + |
| 112 | + TEST( fd_vinyl_data_init( vinyl->data, _obj, obj_footprint, obj_laddr0 )==vinyl->data ); |
| 113 | + |
| 114 | + vinyl->cnc_footprint = cnc_footprint; |
| 115 | + vinyl->meta_footprint = meta_footprint; |
| 116 | + vinyl->line_footprint = line_footprint; |
| 117 | + vinyl->ele_footprint = ele_footprint; |
| 118 | + vinyl->obj_footprint = obj_footprint; |
| 119 | + |
| 120 | + FD_LOG_NOTICE(( "Recovering bstream past (level %i)", level )); |
| 121 | + |
| 122 | + TEST( fd_vinyl_seq_eq( fd_vinyl_recover( tpool,t0,t1, level, vinyl ), fd_vinyl_io_seq_present( io ) ) ); |
| 123 | + |
| 124 | +# undef TEST |
| 125 | + |
| 126 | + FD_LOG_NOTICE(( "Initializing complete" )); |
| 127 | + |
| 128 | + return vinyl; |
| 129 | +} |
| 130 | + |
| 131 | +void * |
| 132 | +fd_vinyl_fini( fd_vinyl_t * vinyl ) { |
| 133 | + |
| 134 | + if( FD_UNLIKELY( !vinyl ) ) { |
| 135 | + FD_LOG_WARNING(( "NULL vinyl" )); |
| 136 | + return NULL; |
| 137 | + } |
| 138 | + |
| 139 | + /* Note: does not sync. App should decide if sync is appropriate |
| 140 | + before calling fini. */ |
| 141 | + |
| 142 | + fd_vinyl_data_fini( vinyl->data ); |
| 143 | + |
| 144 | + void * _meta = fd_vinyl_meta_shmap( vinyl->meta ); |
| 145 | + fd_vinyl_meta_leave( vinyl->meta ); |
| 146 | + fd_vinyl_meta_delete( _meta ); |
| 147 | + |
| 148 | + fd_cnc_delete( fd_cnc_leave( vinyl->cnc ) ); |
| 149 | + |
| 150 | + return vinyl; |
| 151 | +} |
0 commit comments