LCOV - code coverage report
Current view: top level - vinyl/line - fd_vinyl_line.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 7 9 77.8 %
Date: 2025-12-07 04:58:33 Functions: 3 72 4.2 %

          Line data    Source code
       1             : #ifndef HEADER_fd_src_vinyl_line_fd_vinyl_line_h
       2             : #define HEADER_fd_src_vinyl_line_fd_vinyl_line_h
       3             : 
       4             : /* A vinyl tile caches key-val pairs in DRAM for performance reasons
       5             :    and to faciliate operations like creating a new pair or asynchronous
       6             :    I/O.  This cache can be _completely_ lost without impacting the
       7             :    recoverabilty exactly key-val state at the time the bstream was most
       8             :    recently sync'd.
       9             : 
      10             :    This cache is logically organized into line_cnt cache lines.
      11             : 
      12             :    An eviction sequence gives the preferred order in which lines should
      13             :    be reused.  Though a line always has a position in the eviction
      14             :    sequence, a given line may not be evictable due to acquires for read
      15             :    or modify on that line.  A quota system bounds the worst case number
      16             :    of acquired lines in order to guarantee there are always some
      17             :    evictable lines.
      18             : 
      19             :    When a pair is evicted from a line, the line is moved to the least
      20             :    recently used (LRU) position in the eviction sequence so that unused
      21             :    lines can be quickly found and preferentially reused before any lines
      22             :    caching pairs.
      23             : 
      24             :    The eviction sequence is given by a circular doubly linked list and a
      25             :    cursor positioned at the LRU line.  Given the above, the sequence
      26             :    always contains exactly line_cnt lines.  Given the LRU line is
      27             :    tracked explicitly and circular list, the most recently used (MRU)
      28             :    line is tracked implicitly as the line "older" than the LRU line. */
      29             : 
      30             : #include "../meta/fd_vinyl_meta.h"
      31             : #include "../data/fd_vinyl_data.h"
      32             : 
      33             : /* FD_VINYL_LINE_EVICT_PRIO_* specify eviction priorties.  These should
      34             :    be compatible with fd_vinyl_req_evict_prio and FD_VINYL_REQ_FLAG_* */
      35             : 
      36           0 : #define FD_VINYL_LINE_EVICT_PRIO_MRU (0) /* <0 also treated as MRU */
      37     4497588 : #define FD_VINYL_LINE_EVICT_PRIO_LRU (1)
      38     3000000 : #define FD_VINYL_LINE_EVICT_PRIO_UNC (2) /* >2 also treated as UNC */
      39             : 
      40             : /* FD_VINYL_LINE_MAX gives the maximum number of lines that can be
      41             :    handled by a vinyl tile.  This is a large power of 2 minus 1.  The
      42             :    below value ensures that a value in [0,line_cnt] can be represented
      43             :    in 32-bits.  Note that larger is possible but requires more DRAM
      44             :    overhead.  For typical applications (where pair vals sizes are
      45             :    measured in KiB to MiB), a line_cnt at this LINE_MAX would require
      46             :    impractically large amounts of DRAM for the vinyl cache ... TiB to
      47             :    PiB). */
      48             : 
      49           0 : #define FD_VINYL_LINE_MAX ((1UL<<32)-1UL)
      50             : 
      51             : /* FD_VINYL_LINE_REF_MAX gives the max acquires-for-read allowed on a
      52             :    vinyl cache line.  Like LINE_MAX, this could be made larger at the
      53             :    expense of more DRAM overhead (and, more theoretical, more frequent
      54             :    line version wrapping for speculative reads).  The current value is
      55             :    sufficient to support an impractical number of concurrent clients
      56             :    acquiring the same pair for concurrently read. */
      57             : 
      58             : #define FD_VINYL_LINE_REF_MAX ((1L<<32)-2L)
      59             : 
      60             : /* FD_VINYL_LINE_VER_MAX gives the maximum number of versions a line
      61             :    can have before its version number gets reused.  This is a large
      62             :    power of 2 minus 1 such that version number reuse is impractical over
      63             :    the duration of any speculative reads. */
      64             : 
      65             : #define FD_VINYL_LINE_VER_MAX ((1UL<<32)-1UL)
      66             : 
      67             : /* A fd_vinyl_line_t stores information the vinyl tile uses to track
      68             :    how a key-val pair has been cached in DRAM.  If the val field is
      69             :    NULL, there is no pair cached in that line and all other fields are
      70             :    ignored.  Practically speaking, the vinyl tile uses this (local)
      71             :    structure to tie together the (shared) pair meta map and the (shared)
      72             :    data cache region.
      73             : 
      74             :    ctl contains:
      75             : 
      76             :      ver: This is bumped every time the line is changed to allow clients
      77             :      to do reliable lockfree speculative reads of the line under the
      78             :      assumption speculative reader will complete and test their
      79             :      speculative read before the version number can wrap.
      80             : 
      81             :      ref: -1 - the line is acquired for modify, 0 - the line is not
      82             :      acquired for anything (and thus is evictable), >0 - the line is
      83             :      acquired-for-read ref times. */
      84             : 
      85             : struct __attribute__((aligned(32))) fd_vinyl_line {
      86             :   fd_vinyl_data_obj_t * obj;            /* location in the data cache of the data_obj storing val, NULL if not caching a pair */
      87             :   ulong                 ele_idx;        /* map element storing key and the pair metadata (app and key), in [0,map_cnt) */
      88             :   ulong                 ctl;            /* packs the line version and line reference count */
      89             :   uint                  line_idx_older; /* older line in eviction sequence, in [0,line_cnt) */
      90             :   uint                  line_idx_newer; /* newer line in eviction sequence, in [0,line_cnt) */
      91             : };
      92             : 
      93             : typedef struct fd_vinyl_line fd_vinyl_line_t;
      94             : 
      95             : FD_PROTOTYPES_BEGIN
      96             : 
      97             : /* fd_vinyl_line_ctl returns ver and ref encoded as a line ctl.  ver is
      98             :    wrapped to be in [0,FD_VINYL_LINE_VER_MAX].  ref is assumed to be in
      99             :    [-1,FD_VINYL_LINE_REF_MAX].
     100             : 
     101             :    fd_vinyl_line_ctl_{ver,ref} returns the decoded eponymous field from
     102             :    a line ctl.  The return will be in
     103             :    {[0,FD_VINYL_LINE_VER_MAX]),[-1,FD_VINYL_LINE_REF_MAX]}. */
     104             : 
     105             : FD_FN_CONST static inline ulong
     106             : fd_vinyl_line_ctl( ulong ver,
     107     3000000 :                    long  ref ) {
     108     3000000 :   return (ver<<32) | ((ulong)(ref+1L));
     109     3000000 : }
     110             : 
     111     3000000 : FD_FN_CONST static inline ulong fd_vinyl_line_ctl_ver( ulong ctl ) { return ctl>>32; }
     112     3000000 : FD_FN_CONST static inline long  fd_vinyl_line_ctl_ref( ulong ctl ) { return ((long)(ctl & ((1UL<<32)-1UL)))-1L; }
     113             : 
     114             : /* fd_vinyl_line_evict_prio changes the eviction priority of line
     115             :    line_idx to evict_prio.  Cannot fail from the caller's perspective
     116             :    (will FD_LOG_CRIT if line corruption was detected). */
     117             : 
     118             : void
     119             : fd_vinyl_line_evict_prio( uint *            _line_idx_lru, /* Pointer to the LRU line idx */
     120             :                           fd_vinyl_line_t * line,          /* Indexed [0,line_cnt) */
     121             :                           ulong             _line_cnt,     /* In [3,FD_VINYL_LINE_MAX] */
     122             :                           ulong             _line_idx,     /* In [0,line_cnt) */
     123             :                           int               evict_prio );  /* FD_VINYL_LINE_EVICT_PRIO_* */
     124             : 
     125             : /* fd_vinyl_line_evict_lru finds the least recently used evictable line
     126             :    and evicts it.  Returns the line_idx of that line (will be free to
     127             :    use).  Cannot fail from the caller's perspecitve (will FD_LOG_CRIT if
     128             :    corruption was detected or quotas were misconfigured). */
     129             : 
     130             : ulong
     131             : fd_vinyl_line_evict_lru( uint *                _line_idx_lru, /* Pointer to the LRU line idx */
     132             :                          fd_vinyl_line_t *     line,          /* Indexed [0,line_cnt) */
     133             :                          ulong                 line_cnt,      /* In [3,FD_VINYL_LINE_MAX] */
     134             :                          fd_vinyl_meta_ele_t * ele0,          /* Indexed [0,ele_max) */
     135             :                          ulong                 ele_max,
     136             :                          fd_vinyl_data_t *     data );
     137             : 
     138             : FD_PROTOTYPES_END
     139             : 
     140             : #endif /* HEADER_fd_src_vinyl_line_fd_vinyl_line_h */

Generated by: LCOV version 1.14