LCOV - code coverage report
Current view: top level - disco/store - fd_shredb.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 23 23 100.0 %
Date: 2026-06-23 08:01:55 Functions: 8 12 66.7 %

          Line data    Source code
       1             : #ifndef HEADER_fd_src_disco_store_fd_shredb_h
       2             : #define HEADER_fd_src_disco_store_fd_shredb_h
       3             : 
       4             : #include "../../ballet/shred/fd_shred.h"
       5             : 
       6             : /* An on-disk shred store for serving repair requests.
       7             : 
       8             :    Unlike fd_store, fd_shredb stores individual raw shreds keyed
       9             :    by (slot, shred_index) and is optimized for random lookups.
      10             : 
      11             :    To speedup the HighestShred query, we have two hashmaps.
      12             :       - A per-slot map, which tracks what the highest known index for a slot is.
      13             :       - A per-shred map, keyed by (slot, shred_index) and
      14             :         contains the ring buffer position for a shred.
      15             : 
      16             :    The ring buffer is file-backend, and maps to a fixed-size circular array
      17             :    of shred entries. FIFO evicition by advancing the write head allows us
      18             :    to retain only the newest entries.
      19             : 
      20             :    NOTE: For now, this design does not have any WAL or crash recovery.
      21             : 
      22             :    NOTE: In the current design, the Rserve tile subscribes to the
      23             :    shred_out link for getting the shreds, but we may have the shred tile
      24             :    write directly into the store in the future. */
      25             : 
      26             : 
      27             : FD_FN_CONST static inline ulong
      28     3120981 : fd_shredb_key_pack( ulong slot, uint shred_idx ) {
      29     3120981 :   return (slot << 16) | (ulong)(ushort)shred_idx;
      30     3120981 : }
      31             : 
      32             : FD_FN_CONST static inline ulong
      33      483864 : fd_shredb_key_slot( ulong key ) {
      34      483864 :   return fd_ulong_extract( key, 16, 63 );
      35      483864 : }
      36             : 
      37             : FD_FN_CONST static inline uint
      38      483867 : fd_shredb_key_shred_idx( ulong key ) {
      39      483867 :   return (uint)fd_ulong_extract( key, 0, 15 );
      40      483867 : }
      41             : 
      42             : /* per-shred entry, (slot, shred_index) -> ring_idx */
      43             : struct fd_shredb_shred_entry {
      44             :   ulong key;
      45             :   ulong ring_idx;
      46             : };
      47             : typedef struct fd_shredb_shred_entry fd_shredb_shred_entry_t;
      48             : 
      49             : #define MAP_NAME              fd_shredb_shred_map
      50     6665571 : #define MAP_T                 fd_shredb_shred_entry_t
      51    36444027 : #define MAP_KEY_T             ulong
      52    30727272 : #define MAP_KEY_NULL          ULONG_MAX
      53    36444027 : #define MAP_KEY_INVAL(k)      ((k)==ULONG_MAX)
      54    25180875 : #define MAP_KEY_EQUAL(k0,k1)  ((k0)==(k1))
      55    14384118 : #define MAP_KEY_HASH(k,seed)  ((uint)fd_ulong_hash( (k) ^ (seed) ))
      56             : #define MAP_MEMOIZE           0
      57             : #define MAP_KEY_EQUAL_IS_SLOW 0
      58             : #include "../../util/tmpl/fd_map_dynamic.c"
      59             : 
      60             : /* per-slot entry, slot -> (highest_shred_idx, cnt) */
      61             : struct fd_shredb_slot_entry {
      62             :   ulong key;
      63             :   uint  highest_shred_idx; /* highest shred_idx we have for this slot */
      64             :   ulong cnt;               /* number of shreds we have for this slot */
      65             : };
      66             : typedef struct fd_shredb_slot_entry fd_shredb_slot_entry_t;
      67             : 
      68             : #define MAP_NAME              fd_shredb_slot_map
      69     3730668 : #define MAP_T                 fd_shredb_slot_entry_t
      70    14930151 : #define MAP_KEY_T             ulong
      71      958230 : #define MAP_KEY_NULL          ULONG_MAX
      72    14930151 : #define MAP_KEY_INVAL(k)      ((k)==ULONG_MAX)
      73    14582982 : #define MAP_KEY_EQUAL(k0,k1)  ((k0)==(k1))
      74     3966786 : #define MAP_KEY_HASH(k,seed)  ((uint)fd_ulong_hash( (k) ^ (seed) ))
      75             : #define MAP_MEMOIZE           0
      76             : #define MAP_KEY_EQUAL_IS_SLOW 0
      77             : #include "../../util/tmpl/fd_map_dynamic.c"
      78             : 
      79             : /* On-disk ring buffer entry. */
      80             : struct __attribute__((aligned(64))) fd_shredb_entry {
      81             :   ulong  key;                      /* for reverse lookups on eviction */
      82             :   ushort shred_sz;                /* actual shred byte count */
      83             :   uchar  occupied;                /* 1 if this slot holds valid data */
      84             :   uchar  shred[FD_SHRED_MAX_SZ];
      85             : };
      86             : typedef struct fd_shredb_entry fd_shredb_entry_t;
      87             : 
      88             : struct fd_shredb {
      89             :   ulong  max_shreds;                  /* ring buffer capacity */
      90             :   ulong  write_head;                  /* next ring position to write */
      91             :   ulong  cnt;                         /* current number of entries */
      92             :   void * mapped;
      93             :   ulong  mapped_sz;                   /* the size of `mapped` in bytes */
      94             :   int    fd;                          /* file descriptor for the backing file */
      95             :   ulong  file_shreds;                 /* current file capacity in shred entries */
      96             :   fd_shredb_shred_entry_t * shred_map;
      97             :   fd_shredb_slot_entry_t  * slot_map;
      98             : };
      99             : typedef struct fd_shredb fd_shredb_t;
     100             : 
     101             : FD_PROTOTYPES_BEGIN
     102             : 
     103             : FD_FN_CONST static inline ulong
     104         288 : fd_shredb_align( void ) {
     105             :   return alignof(fd_shredb_t);
     106         288 : }
     107             : 
     108             : FD_FN_CONST ulong
     109             : fd_shredb_footprint( ulong max_size_gib );
     110             : 
     111             : void *
     112             : fd_shredb_new( void       * shmem,
     113             :                ulong        max_size_gib,
     114             :                char const * file_path,
     115             :                ulong        seed );
     116             : 
     117             : fd_shredb_t *
     118             : fd_shredb_join( void * shstore );
     119             : 
     120             : void *
     121             : fd_shredb_leave( fd_shredb_t const * store );
     122             : 
     123             : void *
     124             : fd_shredb_delete( void * shstore );
     125             : 
     126             : /* Insert a complete shred into the store.  shred_sz is the result of
     127             :    fd_shred_sz( shred ).  Derives (slot, shred_idx) from the header. */
     128             : void
     129             : fd_shredb_insert( fd_shredb_t      * store,
     130             :                   fd_shred_t const * shred,
     131             :                   ulong              shred_sz );
     132             : 
     133             : /* Given a (slot, shred_index), returns the corresponding entry.
     134             :    If no entry was found, returns -1, otherwise returns the amount
     135             :    of bytes written to out. */
     136             : int
     137             : fd_shredb_query( fd_shredb_t * store,
     138             :                  ulong         slot,
     139             :                  uint          shred_idx,
     140             :                  uchar         out[ FD_SHRED_MAX_SZ ] );
     141             : 
     142             : /* Given a (slot, min_shred_idx), returns the highest shred the store
     143             :    knows of for that slot.
     144             : 
     145             :    If the store has no shreds for the given slot, or does not have a shred
     146             :    with a high enough index, returns -1, otherwise returns the amount of
     147             :    bytes written to out. */
     148             : int
     149             : fd_shredb_query_highest( fd_shredb_t * store,
     150             :                          ulong         slot,
     151             :                          uint          min_shred_idx,
     152             :                          uchar         out[ FD_SHRED_MAX_SZ ] );
     153             : 
     154             : FD_PROTOTYPES_END
     155             : 
     156             : #endif /* HEADER_fd_src_disco_store_fd_shredb_h */

Generated by: LCOV version 1.14