LCOV - code coverage report
Current view: top level - src/include/access - slru.h (source / functions) Coverage Total Hit
Test: Code coverage Lines: 100.0 % 5 5
Test Date: 2026-01-26 10:56:24 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       263191 : SimpleLruGetBankLock(SlruCtl ctl, int64 pageno)
     161              : {
     162       263191 :         int                     bankno;
     163              : 
     164       263191 :         bankno = pageno % ctl->nbanks;
     165       526382 :         return &(ctl->shared->bank_locks[bankno].lock);
     166       263191 : }
     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.3.2-1