LCOV - differential code coverage report
Current view: top level - libs/postgres_ffi/src - nonrelfile_utils.rs (source / functions) Coverage Total Hit UBC CBC
Current: f6946e90941b557c917ac98cd5a7e9506d180f3e.info Lines: 88.6 % 88 78 10 78
Current Date: 2023-10-19 02:04:12 Functions: 72.7 % 33 24 9 24
Baseline: c8637f37369098875162f194f92736355783b050.info
Baseline Date: 2023-10-18 20:25:20

           TLA  Line data    Source code
       1                 : //!
       2                 : //! Common utilities for dealing with PostgreSQL non-relation files.
       3                 : //!
       4                 : use crate::pg_constants;
       5                 : use crate::transaction_id_precedes;
       6                 : use bytes::BytesMut;
       7                 : use log::*;
       8                 : 
       9                 : use super::bindings::MultiXactId;
      10                 : 
      11 CBC    23043729 : pub fn transaction_id_set_status(xid: u32, status: u8, page: &mut BytesMut) {
      12        23043729 :     trace!(
      13 UBC           0 :         "handle_apply_request for RM_XACT_ID-{} (1-commit, 2-abort, 3-sub_commit)",
      14                 :         status
      15                 :     );
      16                 : 
      17 CBC    23043729 :     let byteno: usize =
      18        23043729 :         ((xid % pg_constants::CLOG_XACTS_PER_PAGE) / pg_constants::CLOG_XACTS_PER_BYTE) as usize;
      19        23043729 : 
      20        23043729 :     let bshift: u8 =
      21        23043729 :         ((xid % pg_constants::CLOG_XACTS_PER_BYTE) * pg_constants::CLOG_BITS_PER_XACT as u32) as u8;
      22        23043729 : 
      23        23043729 :     page[byteno] =
      24        23043729 :         (page[byteno] & !(pg_constants::CLOG_XACT_BITMASK << bshift)) | (status << bshift);
      25        23043729 : }
      26                 : 
      27 UBC           0 : pub fn transaction_id_get_status(xid: u32, page: &[u8]) -> u8 {
      28               0 :     let byteno: usize =
      29               0 :         ((xid % pg_constants::CLOG_XACTS_PER_PAGE) / pg_constants::CLOG_XACTS_PER_BYTE) as usize;
      30               0 : 
      31               0 :     let bshift: u8 =
      32               0 :         ((xid % pg_constants::CLOG_XACTS_PER_BYTE) * pg_constants::CLOG_BITS_PER_XACT as u32) as u8;
      33               0 : 
      34               0 :     (page[byteno] >> bshift) & pg_constants::CLOG_XACT_BITMASK
      35               0 : }
      36                 : 
      37                 : // See CLOGPagePrecedes in clog.c
      38 CBC          21 : pub const fn clogpage_precedes(page1: u32, page2: u32) -> bool {
      39              21 :     let mut xid1 = page1 * pg_constants::CLOG_XACTS_PER_PAGE;
      40              21 :     xid1 += pg_constants::FIRST_NORMAL_TRANSACTION_ID + 1;
      41              21 :     let mut xid2 = page2 * pg_constants::CLOG_XACTS_PER_PAGE;
      42              21 :     xid2 += pg_constants::FIRST_NORMAL_TRANSACTION_ID + 1;
      43              21 : 
      44              21 :     transaction_id_precedes(xid1, xid2)
      45              19 :         && transaction_id_precedes(xid1, xid2 + pg_constants::CLOG_XACTS_PER_PAGE - 1)
      46              21 : }
      47                 : 
      48                 : // See SlruMayDeleteSegment() in slru.c
      49              10 : pub fn slru_may_delete_clogsegment(segpage: u32, cutoff_page: u32) -> bool {
      50              10 :     let seg_last_page = segpage + pg_constants::SLRU_PAGES_PER_SEGMENT - 1;
      51              10 : 
      52              10 :     assert_eq!(segpage % pg_constants::SLRU_PAGES_PER_SEGMENT, 0);
      53                 : 
      54              10 :     clogpage_precedes(segpage, cutoff_page) && clogpage_precedes(seg_last_page, cutoff_page)
      55              10 : }
      56                 : 
      57                 : // Multixact utils
      58                 : 
      59         1890106 : pub fn mx_offset_to_flags_offset(xid: MultiXactId) -> usize {
      60         1890106 :     ((xid / pg_constants::MULTIXACT_MEMBERS_PER_MEMBERGROUP as u32)
      61         1890106 :         % pg_constants::MULTIXACT_MEMBERGROUPS_PER_PAGE as u32
      62         1890106 :         * pg_constants::MULTIXACT_MEMBERGROUP_SIZE as u32) as usize
      63         1890106 : }
      64                 : 
      65          945053 : pub fn mx_offset_to_flags_bitshift(xid: MultiXactId) -> u16 {
      66          945053 :     (xid as u16) % pg_constants::MULTIXACT_MEMBERS_PER_MEMBERGROUP
      67          945053 :         * pg_constants::MXACT_MEMBER_BITS_PER_XACT
      68          945053 : }
      69                 : 
      70                 : /* Location (byte offset within page) of TransactionId of given member */
      71          945053 : pub fn mx_offset_to_member_offset(xid: MultiXactId) -> usize {
      72          945053 :     mx_offset_to_flags_offset(xid)
      73          945053 :         + (pg_constants::MULTIXACT_FLAGBYTES_PER_GROUP
      74          945053 :             + (xid as u16 % pg_constants::MULTIXACT_MEMBERS_PER_MEMBERGROUP) * 4) as usize
      75          945053 : }
      76                 : 
      77              30 : fn mx_offset_to_member_page(xid: u32) -> u32 {
      78              30 :     xid / pg_constants::MULTIXACT_MEMBERS_PER_PAGE as u32
      79              30 : }
      80                 : 
      81              15 : pub fn mx_offset_to_member_segment(xid: u32) -> i32 {
      82              15 :     (mx_offset_to_member_page(xid) / pg_constants::SLRU_PAGES_PER_SEGMENT) as i32
      83              15 : }
      84                 : 
      85                 : #[cfg(test)]
      86                 : mod tests {
      87                 :     use super::*;
      88                 : 
      89               3 :     #[test]
      90               3 :     fn test_multixid_calc() {
      91               3 :         // Check that the mx_offset_* functions produce the same values as the
      92               3 :         // corresponding PostgreSQL C macros (MXOffsetTo*). These test values
      93               3 :         // were generated by calling the PostgreSQL macros with a little C
      94               3 :         // program.
      95               3 :         assert_eq!(mx_offset_to_member_segment(0), 0);
      96               3 :         assert_eq!(mx_offset_to_member_page(0), 0);
      97               3 :         assert_eq!(mx_offset_to_flags_offset(0), 0);
      98               3 :         assert_eq!(mx_offset_to_flags_bitshift(0), 0);
      99               3 :         assert_eq!(mx_offset_to_member_offset(0), 4);
     100               3 :         assert_eq!(mx_offset_to_member_segment(1), 0);
     101               3 :         assert_eq!(mx_offset_to_member_page(1), 0);
     102               3 :         assert_eq!(mx_offset_to_flags_offset(1), 0);
     103               3 :         assert_eq!(mx_offset_to_flags_bitshift(1), 8);
     104               3 :         assert_eq!(mx_offset_to_member_offset(1), 8);
     105               3 :         assert_eq!(mx_offset_to_member_segment(123456789), 2358);
     106               3 :         assert_eq!(mx_offset_to_member_page(123456789), 75462);
     107               3 :         assert_eq!(mx_offset_to_flags_offset(123456789), 4780);
     108               3 :         assert_eq!(mx_offset_to_flags_bitshift(123456789), 8);
     109               3 :         assert_eq!(mx_offset_to_member_offset(123456789), 4788);
     110               3 :         assert_eq!(mx_offset_to_member_segment(u32::MAX - 1), 82040);
     111               3 :         assert_eq!(mx_offset_to_member_page(u32::MAX - 1), 2625285);
     112               3 :         assert_eq!(mx_offset_to_flags_offset(u32::MAX - 1), 5160);
     113               3 :         assert_eq!(mx_offset_to_flags_bitshift(u32::MAX - 1), 16);
     114               3 :         assert_eq!(mx_offset_to_member_offset(u32::MAX - 1), 5172);
     115               3 :         assert_eq!(mx_offset_to_member_segment(u32::MAX), 82040);
     116               3 :         assert_eq!(mx_offset_to_member_page(u32::MAX), 2625285);
     117               3 :         assert_eq!(mx_offset_to_flags_offset(u32::MAX), 5160);
     118               3 :         assert_eq!(mx_offset_to_flags_bitshift(u32::MAX), 24);
     119               3 :         assert_eq!(mx_offset_to_member_offset(u32::MAX), 5176);
     120               3 :     }
     121                 : }
        

Generated by: LCOV version 2.1-beta