LCOV - code coverage report
Current view: top level - src/include/access - slru.h (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 100.0 % 3 3
Test Date: 2026-03-04 20:14:49 Functions: 100.0 % 1 1
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /*-------------------------------------------------------------------------
       2              :  *
       3              :  * slru.h
       4              :  *      Simple LRU buffering for transaction status logfiles
       5              :  *
       6              :  * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
       7              :  * Portions Copyright (c) 1994, Regents of the University of California
       8              :  *
       9              :  * src/include/access/slru.h
      10              :  *
      11              :  *-------------------------------------------------------------------------
      12              :  */
      13              : #ifndef SLRU_H
      14              : #define SLRU_H
      15              : 
      16              : #include "access/xlogdefs.h"
      17              : #include "storage/lwlock.h"
      18              : #include "storage/sync.h"
      19              : 
      20              : /*
      21              :  * To avoid overflowing internal arithmetic and the size_t data type, the
      22              :  * number of buffers must not exceed this number.
      23              :  */
      24              : #define SLRU_MAX_ALLOWED_BUFFERS ((1024 * 1024 * 1024) / BLCKSZ)
      25              : 
      26              : /*
      27              :  * Page status codes.  Note that these do not include the "dirty" bit.
      28              :  * page_dirty can be true only in the VALID or WRITE_IN_PROGRESS states;
      29              :  * in the latter case it implies that the page has been re-dirtied since
      30              :  * the write started.
      31              :  */
      32              : typedef enum
      33              : {
      34              :     SLRU_PAGE_EMPTY,            /* buffer is not in use */
      35              :     SLRU_PAGE_READ_IN_PROGRESS, /* page is being read in */
      36              :     SLRU_PAGE_VALID,            /* page is valid and not being written */
      37              :     SLRU_PAGE_WRITE_IN_PROGRESS,    /* page is being written out */
      38              : } SlruPageStatus;
      39              : 
      40              : /*
      41              :  * Shared-memory state
      42              :  *
      43              :  * SLRU bank locks are used to protect access to the other fields, except
      44              :  * latest_page_number, which uses atomics; see comment in slru.c.
      45              :  */
      46              : typedef struct SlruSharedData
      47              : {
      48              :     /* Number of buffers managed by this SLRU structure */
      49              :     int         num_slots;
      50              : 
      51              :     /*
      52              :      * Arrays holding info for each buffer slot.  Page number is undefined
      53              :      * when status is EMPTY, as is page_lru_count.
      54              :      */
      55              :     char      **page_buffer;
      56              :     SlruPageStatus *page_status;
      57              :     bool       *page_dirty;
      58              :     int64      *page_number;
      59              :     int        *page_lru_count;
      60              : 
      61              :     /* The buffer_locks protects the I/O on each buffer slots */
      62              :     LWLockPadded *buffer_locks;
      63              : 
      64              :     /* Locks to protect the in memory buffer slot access in SLRU bank. */
      65              :     LWLockPadded *bank_locks;
      66              : 
      67              :     /*----------
      68              :      * A bank-wise LRU counter is maintained because we do a victim buffer
      69              :      * search within a bank. Furthermore, manipulating an individual bank
      70              :      * counter avoids frequent cache invalidation since we update it every time
      71              :      * we access the page.
      72              :      *
      73              :      * We mark a page "most recently used" by setting
      74              :      *      page_lru_count[slotno] = ++bank_cur_lru_count[bankno];
      75              :      * The oldest page in the bank is therefore the one with the highest value
      76              :      * of
      77              :      *      bank_cur_lru_count[bankno] - page_lru_count[slotno]
      78              :      * The counts will eventually wrap around, but this calculation still
      79              :      * works as long as no page's age exceeds INT_MAX counts.
      80              :      *----------
      81              :      */
      82              :     int        *bank_cur_lru_count;
      83              : 
      84              :     /*
      85              :      * Optional array of WAL flush LSNs associated with entries in the SLRU
      86              :      * pages.  If not zero/NULL, we must flush WAL before writing pages (true
      87              :      * for pg_xact, false for everything else).  group_lsn[] has
      88              :      * lsn_groups_per_page entries per buffer slot, each containing the
      89              :      * highest LSN known for a contiguous group of SLRU entries on that slot's
      90              :      * page.
      91              :      */
      92              :     XLogRecPtr *group_lsn;
      93              :     int         lsn_groups_per_page;
      94              : 
      95              :     /*
      96              :      * latest_page_number is the page number of the current end of the log;
      97              :      * this is not critical data, since we use it only to avoid swapping out
      98              :      * the latest page.
      99              :      */
     100              :     pg_atomic_uint64 latest_page_number;
     101              : 
     102              :     /* SLRU's index for statistics purposes (might not be unique) */
     103              :     int         slru_stats_idx;
     104              : } SlruSharedData;
     105              : 
     106              : typedef SlruSharedData *SlruShared;
     107              : 
     108              : /*
     109              :  * SlruCtlData is an unshared structure that points to the active information
     110              :  * in shared memory.
     111              :  */
     112              : typedef struct SlruCtlData
     113              : {
     114              :     SlruShared  shared;
     115              : 
     116              :     /* Number of banks in this SLRU. */
     117              :     uint16      nbanks;
     118              : 
     119              :     /*
     120              :      * If true, use long segment file names.  Otherwise, use short file names.
     121              :      *
     122              :      * For details about the file name format, see SlruFileName().
     123              :      */
     124              :     bool        long_segment_names;
     125              : 
     126              :     /*
     127              :      * Which sync handler function to use when handing sync requests over to
     128              :      * the checkpointer.  SYNC_HANDLER_NONE to disable fsync (eg pg_notify).
     129              :      */
     130              :     SyncRequestHandler sync_handler;
     131              : 
     132              :     /*
     133              :      * Decide whether a page is "older" for truncation and as a hint for
     134              :      * evicting pages in LRU order.  Return true if every entry of the first
     135              :      * argument is older than every entry of the second argument.  Note that
     136              :      * !PagePrecedes(a,b) && !PagePrecedes(b,a) need not imply a==b; it also
     137              :      * arises when some entries are older and some are not.  For SLRUs using
     138              :      * SimpleLruTruncate(), this must use modular arithmetic.  (For others,
     139              :      * the behavior of this callback has no functional implications.)  Use
     140              :      * SlruPagePrecedesUnitTests() in SLRUs meeting its criteria.
     141              :      */
     142              :     bool        (*PagePrecedes) (int64, int64);
     143              : 
     144              :     /*
     145              :      * Dir is set during SimpleLruInit and does not change thereafter. Since
     146              :      * it's always the same, it doesn't need to be in shared memory.
     147              :      */
     148              :     char        Dir[64];
     149              : } SlruCtlData;
     150              : 
     151              : typedef SlruCtlData *SlruCtl;
     152              : 
     153              : /*
     154              :  * Get the SLRU bank lock for given SlruCtl and the pageno.
     155              :  *
     156              :  * This lock needs to be acquired to access the slru buffer slots in the
     157              :  * respective bank.
     158              :  */
     159              : static inline LWLock *
     160      9724987 : SimpleLruGetBankLock(SlruCtl ctl, int64 pageno)
     161              : {
     162              :     int         bankno;
     163              : 
     164      9724987 :     bankno = pageno % ctl->nbanks;
     165      9724987 :     return &(ctl->shared->bank_locks[bankno].lock);
     166              : }
     167              : 
     168              : extern Size SimpleLruShmemSize(int nslots, int nlsns);
     169              : extern int  SimpleLruAutotuneBuffers(int divisor, int max);
     170              : extern void SimpleLruInit(SlruCtl ctl, const char *name, int nslots, int nlsns,
     171              :                           const char *subdir, int buffer_tranche_id,
     172              :                           int bank_tranche_id, SyncRequestHandler sync_handler,
     173              :                           bool long_segment_names);
     174              : extern int  SimpleLruZeroPage(SlruCtl ctl, int64 pageno);
     175              : extern void SimpleLruZeroAndWritePage(SlruCtl ctl, int64 pageno);
     176              : extern int  SimpleLruReadPage(SlruCtl ctl, int64 pageno, bool write_ok,
     177              :                               TransactionId xid);
     178              : extern int  SimpleLruReadPage_ReadOnly(SlruCtl ctl, int64 pageno,
     179              :                                        TransactionId xid);
     180              : extern void SimpleLruWritePage(SlruCtl ctl, int slotno);
     181              : extern void SimpleLruWriteAll(SlruCtl ctl, bool allow_redirtied);
     182              : #ifdef USE_ASSERT_CHECKING
     183              : extern void SlruPagePrecedesUnitTests(SlruCtl ctl, int per_page);
     184              : #else
     185              : #define SlruPagePrecedesUnitTests(ctl, per_page) do {} while (0)
     186              : #endif
     187              : extern void SimpleLruTruncate(SlruCtl ctl, int64 cutoffPage);
     188              : extern bool SimpleLruDoesPhysicalPageExist(SlruCtl ctl, int64 pageno);
     189              : 
     190              : typedef bool (*SlruScanCallback) (SlruCtl ctl, char *filename, int64 segpage,
     191              :                                   void *data);
     192              : extern bool SlruScanDirectory(SlruCtl ctl, SlruScanCallback callback, void *data);
     193              : extern void SlruDeleteSegment(SlruCtl ctl, int64 segno);
     194              : 
     195              : extern int  SlruSyncFileTag(SlruCtl ctl, const FileTag *ftag, char *path);
     196              : 
     197              : /* SlruScanDirectory public callbacks */
     198              : extern bool SlruScanDirCbReportPresence(SlruCtl ctl, char *filename,
     199              :                                         int64 segpage, void *data);
     200              : extern bool SlruScanDirCbDeleteAll(SlruCtl ctl, char *filename, int64 segpage,
     201              :                                    void *data);
     202              : extern bool check_slru_buffers(const char *name, int *newval);
     203              : 
     204              : #endif                          /* SLRU_H */
        

Generated by: LCOV version 2.0-1