PostgreSQL Source Code  git master
itemptr.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * itemptr.c
4  * POSTGRES disk item pointer code.
5  *
6  * Portions Copyright (c) 1996-2021, 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  * ItemPointerEquals
22  * Returns true if both item pointers point to the same item,
23  * otherwise returns false.
24  *
25  * Note:
26  * Asserts that the disk item pointers are both valid!
27  */
28 bool
30 {
31  /*
32  * We really want ItemPointerData to be exactly 6 bytes. This is rather a
33  * random place to check, but there is no better place.
34  */
35  StaticAssertStmt(sizeof(ItemPointerData) == 3 * sizeof(uint16),
36  "ItemPointerData struct is improperly padded");
37 
38  if (ItemPointerGetBlockNumber(pointer1) ==
39  ItemPointerGetBlockNumber(pointer2) &&
40  ItemPointerGetOffsetNumber(pointer1) ==
42  return true;
43  else
44  return false;
45 }
46 
47 /*
48  * ItemPointerCompare
49  * Generic btree-style comparison for item pointers.
50  */
51 int32
53 {
54  /*
55  * Use ItemPointerGet{Offset,Block}NumberNoCheck to avoid asserting
56  * ip_posid != 0, which may not be true for a user-supplied TID.
57  */
60 
61  if (b1 < b2)
62  return -1;
63  else if (b1 > b2)
64  return 1;
65  else if (ItemPointerGetOffsetNumberNoCheck(arg1) <
67  return -1;
68  else if (ItemPointerGetOffsetNumberNoCheck(arg1) >
70  return 1;
71  else
72  return 0;
73 }
74 
75 /*
76  * ItemPointerInc
77  * Increment 'pointer' by 1 only paying attention to the ItemPointer's
78  * type's range limits and not MaxOffsetNumber and FirstOffsetNumber.
79  * This may result in 'pointer' becoming !OffsetNumberIsValid.
80  *
81  * If the pointer is already the maximum possible values permitted by the
82  * range of the ItemPointer's types, then do nothing.
83  */
84 void
86 {
89 
90  if (off == PG_UINT16_MAX)
91  {
92  if (blk != InvalidBlockNumber)
93  {
94  off = 0;
95  blk++;
96  }
97  }
98  else
99  off++;
100 
101  ItemPointerSet(pointer, blk, off);
102 }
103 
104 /*
105  * ItemPointerDec
106  * Decrement 'pointer' by 1 only paying attention to the ItemPointer's
107  * type's range limits and not MaxOffsetNumber and FirstOffsetNumber.
108  * This may result in 'pointer' becoming !OffsetNumberIsValid.
109  *
110  * If the pointer is already the minimum possible values permitted by the
111  * range of the ItemPointer's types, then do nothing. This does rely on
112  * FirstOffsetNumber being 1 rather than 0.
113  */
114 void
116 {
119 
120  if (off == 0)
121  {
122  if (blk != 0)
123  {
124  off = PG_UINT16_MAX;
125  blk--;
126  }
127  }
128  else
129  off--;
130 
131  ItemPointerSet(pointer, blk, off);
132 }
int32 ItemPointerCompare(ItemPointer arg1, ItemPointer arg2)
Definition: itemptr.c:52
#define ItemPointerGetOffsetNumberNoCheck(pointer)
Definition: itemptr.h:108
uint32 BlockNumber
Definition: block.h:31
signed int int32
Definition: c.h:429
uint16 OffsetNumber
Definition: off.h:24
#define StaticAssertStmt(condition, errmessage)
Definition: c.h:918
unsigned short uint16
Definition: c.h:440
#define PG_UINT16_MAX
Definition: c.h:522
void ItemPointerDec(ItemPointer pointer)
Definition: itemptr.c:115
void ItemPointerInc(ItemPointer pointer)
Definition: itemptr.c:85
#define InvalidBlockNumber
Definition: block.h:33
#define ItemPointerGetOffsetNumber(pointer)
Definition: itemptr.h:117
bool ItemPointerEquals(ItemPointer pointer1, ItemPointer pointer2)
Definition: itemptr.c:29
#define ItemPointerGetBlockNumberNoCheck(pointer)
Definition: itemptr.h:89
#define ItemPointerGetBlockNumber(pointer)
Definition: itemptr.h:98
#define ItemPointerSet(pointer, blockNumber, offNum)
Definition: itemptr.h:127