Age Owner Branch data TLA Line data Source code
1 : : /*-------------------------------------------------------------------------
2 : : *
3 : : * itemptr.c
4 : : * POSTGRES disk item pointer code.
5 : : *
6 : : * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
7 : : * Portions Copyright (c) 1994, Regents of the University of California
8 : : *
9 : : *
10 : : * IDENTIFICATION
11 : : * src/backend/storage/page/itemptr.c
12 : : *
13 : : *-------------------------------------------------------------------------
14 : : */
15 : : #include "postgres.h"
16 : :
17 : : #include "storage/itemptr.h"
18 : :
19 : :
20 : : /*
21 : : * We really want ItemPointerData to be exactly 6 bytes.
22 : : */
23 : : StaticAssertDecl(sizeof(ItemPointerData) == 3 * sizeof(uint16),
24 : : "ItemPointerData struct is improperly padded");
25 : :
26 : : /*
27 : : * ItemPointerEquals
28 : : * Returns true if both item pointers point to the same item,
29 : : * otherwise returns false.
30 : : *
31 : : * Note:
32 : : * Asserts that the disk item pointers are both valid!
33 : : */
34 : : bool
48 peter@eisentraut.org 35 :GNC 19457507 : ItemPointerEquals(const ItemPointerData *pointer1, const ItemPointerData *pointer2)
36 : : {
10328 bruce@momjian.us 37 [ + + ]:CBC 38915014 : if (ItemPointerGetBlockNumber(pointer1) ==
38 [ + + ]: 33547145 : ItemPointerGetBlockNumber(pointer2) &&
39 : 14089638 : ItemPointerGetOffsetNumber(pointer1) ==
40 : 14089638 : ItemPointerGetOffsetNumber(pointer2))
9969 41 : 12682673 : return true;
42 : : else
43 : 6774834 : return false;
44 : : }
45 : :
46 : : /*
47 : : * ItemPointerCompare
48 : : * Generic btree-style comparison for item pointers.
49 : : */
50 : : int32
48 peter@eisentraut.org 51 :GNC 21888928 : ItemPointerCompare(const ItemPointerData *arg1, const ItemPointerData *arg2)
52 : : {
53 : : /*
54 : : * Use ItemPointerGet{Offset,Block}NumberNoCheck to avoid asserting
55 : : * ip_posid != 0, which may not be true for a user-supplied TID.
56 : : */
3186 alvherre@alvh.no-ip. 57 :CBC 21888928 : BlockNumber b1 = ItemPointerGetBlockNumberNoCheck(arg1);
58 : 21888928 : BlockNumber b2 = ItemPointerGetBlockNumberNoCheck(arg2);
59 : :
7054 tgl@sss.pgh.pa.us 60 [ + + ]: 21888928 : if (b1 < b2)
61 : 286243 : return -1;
62 [ + + ]: 21602685 : else if (b1 > b2)
63 : 11354432 : return 1;
3186 alvherre@alvh.no-ip. 64 [ + + ]: 20496506 : else if (ItemPointerGetOffsetNumberNoCheck(arg1) <
65 : 10248253 : ItemPointerGetOffsetNumberNoCheck(arg2))
7054 tgl@sss.pgh.pa.us 66 : 568832 : return -1;
3186 alvherre@alvh.no-ip. 67 [ + + ]: 19358842 : else if (ItemPointerGetOffsetNumberNoCheck(arg1) >
68 : 9679421 : ItemPointerGetOffsetNumberNoCheck(arg2))
7054 tgl@sss.pgh.pa.us 69 : 8753327 : return 1;
70 : : else
71 : 926094 : return 0;
72 : : }
73 : :
74 : : /*
75 : : * ItemPointerInc
76 : : * Increment 'pointer' by 1 only paying attention to the ItemPointer's
77 : : * type's range limits and not MaxOffsetNumber and FirstOffsetNumber.
78 : : * This may result in 'pointer' becoming !OffsetNumberIsValid.
79 : : *
80 : : * If the pointer is already the maximum possible values permitted by the
81 : : * range of the ItemPointer's types, then do nothing.
82 : : */
83 : : void
1754 drowley@postgresql.o 84 : 53 : ItemPointerInc(ItemPointer pointer)
85 : : {
86 : 53 : BlockNumber blk = ItemPointerGetBlockNumberNoCheck(pointer);
87 : 53 : OffsetNumber off = ItemPointerGetOffsetNumberNoCheck(pointer);
88 : :
89 [ + + ]: 53 : if (off == PG_UINT16_MAX)
90 : : {
91 [ + + ]: 6 : if (blk != InvalidBlockNumber)
92 : : {
93 : 3 : off = 0;
94 : 3 : blk++;
95 : : }
96 : : }
97 : : else
98 : 47 : off++;
99 : :
100 : 53 : ItemPointerSet(pointer, blk, off);
101 : 53 : }
102 : :
103 : : /*
104 : : * ItemPointerDec
105 : : * Decrement 'pointer' by 1 only paying attention to the ItemPointer's
106 : : * type's range limits and not MaxOffsetNumber and FirstOffsetNumber.
107 : : * This may result in 'pointer' becoming !OffsetNumberIsValid.
108 : : *
109 : : * If the pointer is already the minimum possible values permitted by the
110 : : * range of the ItemPointer's types, then do nothing. This does rely on
111 : : * FirstOffsetNumber being 1 rather than 0.
112 : : */
113 : : void
114 : 75 : ItemPointerDec(ItemPointer pointer)
115 : : {
116 : 75 : BlockNumber blk = ItemPointerGetBlockNumberNoCheck(pointer);
117 : 75 : OffsetNumber off = ItemPointerGetOffsetNumberNoCheck(pointer);
118 : :
119 [ + + ]: 75 : if (off == 0)
120 : : {
121 [ + + ]: 45 : if (blk != 0)
122 : : {
123 : 36 : off = PG_UINT16_MAX;
124 : 36 : blk--;
125 : : }
126 : : }
127 : : else
1754 drowley@postgresql.o 128 :GBC 30 : off--;
129 : :
1754 drowley@postgresql.o 130 :CBC 75 : ItemPointerSet(pointer, blk, off);
131 : 75 : }
|