Line data Source code
1 : #ifndef HEADER_fd_src_flamenco_accdb_fd_accdb_pipe_h 2 : #define HEADER_fd_src_flamenco_accdb_fd_accdb_pipe_h 3 : 4 : /* fd_accdb_pipe.h provides APIs for fast bulk account access. */ 5 : 6 : #include "fd_accdb_base.h" 7 : #include "fd_accdb_ref.h" 8 : #include "fd_accdb_user.h" 9 : 10 : /* fd_accdb_ro_pipe_t is an API for pipelining account read requests. 11 : 12 : This API flexibly adapts to the style of underlying I/O backend and 13 : queue depths without requiring the caller to know database config 14 : specifics. 15 : 16 : General usage as follows: 17 : 18 : pipe = fd_accdb_ro_pipe_init( ... ); 19 : for each (i, address) in request_list { 20 : 21 : // enqueue another request 22 : fd_accdb_ro_pipe_enqueue( pipe, address ); 23 : 24 : if( i==len(request_list)-1 ) { 25 : // ensure that all results are read on the last iteration 26 : fd_accdb_ro_pipe_flush( pipe ); 27 : } 28 : 29 : // handle completions (may be delivered in subsequent iterations) 30 : while( ro = fd_accdb_ro_pipe_poll( pipe ) ) { 31 : ... process an account result ... 32 : } 33 : 34 : } 35 : fd_accdb_ro_pipe_fini( ... ); 36 : 37 : The pattern above enqueues read requests and asynchronously processes 38 : results as they become available. The loop blocks as appropriate 39 : when backpressured. */ 40 : 41 0 : #define FD_ACCDB_RO_PIPE_MAX (1024UL) 42 : 43 : struct fd_accdb_ro_pipe { 44 : fd_accdb_user_t * accdb; 45 : fd_funk_txn_xid_t xid; 46 : 47 : ulong batch_idx; /* index of req batch */ 48 : uint req_max; 49 : uint req_cnt; /* batch element count */ 50 : uint req_comp; /* index of next completion */ 51 : uint state; 52 : 53 : fd_accdb_ro_t ro_nx[1]; /* ro describing a not-found record */ 54 : 55 : uchar addr[ FD_ACCDB_RO_PIPE_MAX ][ 32 ]; 56 : fd_accdb_ro_t ro [ FD_ACCDB_RO_PIPE_MAX ]; 57 : }; 58 : 59 : typedef struct fd_accdb_ro_pipe fd_accdb_ro_pipe_t; 60 : 61 : FD_PROTOTYPES_BEGIN 62 : 63 : /* fd_accdb_ro_pipe_init creates a new ro_pipe. */ 64 : 65 : fd_accdb_ro_pipe_t * 66 : fd_accdb_ro_pipe_init( fd_accdb_ro_pipe_t * pipe, 67 : fd_accdb_user_t * accdb, 68 : fd_funk_txn_xid_t const * xid ); 69 : 70 : void 71 : fd_accdb_ro_pipe_fini( fd_accdb_ro_pipe_t * pipe ); 72 : 73 : /* fd_accdb_ro_pipe_enqueue asynchronously enqueues a read request. 74 : May block internally if queues are full. The user must drain all 75 : completions (fd_accdb_ro_pipe_poll) before calling enqueue. */ 76 : 77 : void 78 : fd_accdb_ro_pipe_enqueue( fd_accdb_ro_pipe_t * pipe, 79 : void const * address ); 80 : 81 : /* fd_accdb_ro_pipe_flush dispatches all enqueued read requests and 82 : blocks until all results become available. (All calls made to poll 83 : after the flush are guaranteed to return non-NULL for requests 84 : enqueued before the flush.) */ 85 : 86 : void 87 : fd_accdb_ro_pipe_flush( fd_accdb_ro_pipe_t * pipe ); 88 : 89 : /* fd_accdb_ro_pipe_poll polls for the next read completion. Returns an 90 : ro handle if a request completed. Returns NULL if no completion is 91 : ready. This may happen because the ro_pipe is waiting for the DB to 92 : respond, or if ro_pipe is internally buffering up a request batch 93 : (use ro_pipe_flush to explicitly dispatch a batch), or if there are 94 : no enqueued requests. 95 : 96 : The lifetime of the returned ro ends when the next call to 97 : ro_pipe_{enqueue,flush,poll} is made on this pipe object, or when the 98 : pipe object is destroyed. 99 : 100 : Results are delivered in enqueued order. 101 : 102 : NOTE: If an account was not found, returns a non-NULL ro (to a dummy 103 : account with zero lamports), which differs from fd_accdb_open_ro. */ 104 : 105 : fd_accdb_ro_t * 106 : fd_accdb_ro_pipe_poll( fd_accdb_ro_pipe_t * pipe ); 107 : 108 : FD_PROTOTYPES_END 109 : 110 : #endif /* HEADER_fd_src_flamenco_accdb_fd_accdb_pipe_h */