PostgreSQL Source Code  git master
combocid.c File Reference
#include "postgres.h"
#include "miscadmin.h"
#include "access/htup_details.h"
#include "access/xact.h"
#include "storage/shmem.h"
#include "utils/combocid.h"
#include "utils/hsearch.h"
#include "utils/memutils.h"
Include dependency graph for combocid.c:

Go to the source code of this file.

Data Structures

struct  ComboCidKeyData
 
struct  ComboCidEntryData
 

Macros

#define CCID_HASH_SIZE   100
 
#define CCID_ARRAY_SIZE   100
 

Typedefs

typedef ComboCidKeyDataComboCidKey
 
typedef ComboCidEntryDataComboCidEntry
 

Functions

static CommandId GetComboCommandId (CommandId cmin, CommandId cmax)
 
static CommandId GetRealCmin (CommandId combocid)
 
static CommandId GetRealCmax (CommandId combocid)
 
CommandId HeapTupleHeaderGetCmin (HeapTupleHeader tup)
 
CommandId HeapTupleHeaderGetCmax (HeapTupleHeader tup)
 
void HeapTupleHeaderAdjustCmax (HeapTupleHeader tup, CommandId *cmax, bool *iscombo)
 
void AtEOXact_ComboCid (void)
 
Size EstimateComboCIDStateSpace (void)
 
void SerializeComboCIDState (Size maxsize, char *start_address)
 
void RestoreComboCIDState (char *comboCIDstate)
 

Variables

static HTABcomboHash = NULL
 
static ComboCidKey comboCids = NULL
 
static int usedComboCids = 0
 
static int sizeComboCids = 0
 

Macro Definition Documentation

◆ CCID_ARRAY_SIZE

#define CCID_ARRAY_SIZE   100

Definition at line 86 of file combocid.c.

Referenced by GetComboCommandId().

◆ CCID_HASH_SIZE

#define CCID_HASH_SIZE   100

Definition at line 74 of file combocid.c.

Referenced by GetComboCommandId().

Typedef Documentation

◆ ComboCidEntry

Definition at line 71 of file combocid.c.

◆ ComboCidKey

Definition at line 63 of file combocid.c.

Function Documentation

◆ AtEOXact_ComboCid()

void AtEOXact_ComboCid ( void  )

Definition at line 183 of file combocid.c.

References sizeComboCids, and usedComboCids.

Referenced by AbortTransaction(), CommitTransaction(), and PrepareTransaction().

184 {
185  /*
186  * Don't bother to pfree. These are allocated in TopTransactionContext, so
187  * they're going to go away at the end of transaction anyway.
188  */
189  comboHash = NULL;
190 
191  comboCids = NULL;
192  usedComboCids = 0;
193  sizeComboCids = 0;
194 }
static int usedComboCids
Definition: combocid.c:82
static ComboCidKey comboCids
Definition: combocid.c:81
static HTAB * comboHash
Definition: combocid.c:54
static int sizeComboCids
Definition: combocid.c:83

◆ EstimateComboCIDStateSpace()

Size EstimateComboCIDStateSpace ( void  )

Definition at line 299 of file combocid.c.

References add_size(), mul_size(), and usedComboCids.

Referenced by InitializeParallelDSM().

300 {
301  Size size;
302 
303  /* Add space required for saving usedComboCids */
304  size = sizeof(int);
305 
306  /* Add space required for saving the combocids key */
307  size = add_size(size, mul_size(sizeof(ComboCidKeyData), usedComboCids));
308 
309  return size;
310 }
static int usedComboCids
Definition: combocid.c:82
Size mul_size(Size s1, Size s2)
Definition: shmem.c:492
Size add_size(Size s1, Size s2)
Definition: shmem.c:475
size_t Size
Definition: c.h:414

◆ GetComboCommandId()

static CommandId GetComboCommandId ( CommandId  cmin,
CommandId  cmax 
)
static

Definition at line 205 of file combocid.c.

References CCID_ARRAY_SIZE, CCID_HASH_SIZE, ComboCidKeyData::cmax, ComboCidKeyData::cmin, ComboCidEntryData::combocid, HASHCTL::entrysize, HASH_BLOBS, HASH_CONTEXT, hash_create(), HASH_ELEM, HASH_ENTER, hash_search(), HASHCTL::hcxt, HASHCTL::keysize, MemoryContextAlloc(), repalloc(), sizeComboCids, TopTransactionContext, and usedComboCids.

Referenced by HeapTupleHeaderAdjustCmax(), and RestoreComboCIDState().

206 {
207  CommandId combocid;
208  ComboCidKeyData key;
209  ComboCidEntry entry;
210  bool found;
211 
212  /*
213  * Create the hash table and array the first time we need to use combo
214  * cids in the transaction.
215  */
216  if (comboHash == NULL)
217  {
218  HASHCTL hash_ctl;
219 
220  /* Make array first; existence of hash table asserts array exists */
223  sizeof(ComboCidKeyData) * CCID_ARRAY_SIZE);
225  usedComboCids = 0;
226 
227  memset(&hash_ctl, 0, sizeof(hash_ctl));
228  hash_ctl.keysize = sizeof(ComboCidKeyData);
229  hash_ctl.entrysize = sizeof(ComboCidEntryData);
230  hash_ctl.hcxt = TopTransactionContext;
231 
232  comboHash = hash_create("Combo CIDs",
234  &hash_ctl,
236  }
237 
238  /*
239  * Grow the array if there's not at least one free slot. We must do this
240  * before possibly entering a new hashtable entry, else failure to
241  * repalloc would leave a corrupt hashtable entry behind.
242  */
244  {
245  int newsize = sizeComboCids * 2;
246 
248  repalloc(comboCids, sizeof(ComboCidKeyData) * newsize);
249  sizeComboCids = newsize;
250  }
251 
252  /* Lookup or create a hash entry with the desired cmin/cmax */
253 
254  /* We assume there is no struct padding in ComboCidKeyData! */
255  key.cmin = cmin;
256  key.cmax = cmax;
258  (void *) &key,
259  HASH_ENTER,
260  &found);
261 
262  if (found)
263  {
264  /* Reuse an existing combo cid */
265  return entry->combocid;
266  }
267 
268  /* We have to create a new combo cid; we already made room in the array */
269  combocid = usedComboCids;
270 
271  comboCids[combocid].cmin = cmin;
272  comboCids[combocid].cmax = cmax;
273  usedComboCids++;
274 
275  entry->combocid = combocid;
276 
277  return combocid;
278 }
uint32 CommandId
Definition: c.h:469
MemoryContext TopTransactionContext
Definition: mcxt.c:48
#define HASH_CONTEXT
Definition: hsearch.h:93
#define HASH_ELEM
Definition: hsearch.h:87
MemoryContext hcxt
Definition: hsearch.h:78
#define CCID_ARRAY_SIZE
Definition: combocid.c:86
Size entrysize
Definition: hsearch.h:73
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition: dynahash.c:904
static int usedComboCids
Definition: combocid.c:82
static ComboCidKey comboCids
Definition: combocid.c:81
static HTAB * comboHash
Definition: combocid.c:54
#define HASH_BLOBS
Definition: hsearch.h:88
CommandId cmin
Definition: combocid.c:59
HTAB * hash_create(const char *tabname, long nelem, HASHCTL *info, int flags)
Definition: dynahash.c:316
Size keysize
Definition: hsearch.h:72
static int sizeComboCids
Definition: combocid.c:83
CommandId cmax
Definition: combocid.c:60
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:949
#define CCID_HASH_SIZE
Definition: combocid.c:74
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:693
CommandId combocid
Definition: combocid.c:68
ComboCidEntryData * ComboCidEntry
Definition: combocid.c:71

◆ GetRealCmax()

static CommandId GetRealCmax ( CommandId  combocid)
static

Definition at line 288 of file combocid.c.

References Assert, ComboCidKeyData::cmax, and usedComboCids.

Referenced by HeapTupleHeaderGetCmax().

289 {
290  Assert(combocid < usedComboCids);
291  return comboCids[combocid].cmax;
292 }
static int usedComboCids
Definition: combocid.c:82
static ComboCidKey comboCids
Definition: combocid.c:81
CommandId cmax
Definition: combocid.c:60
#define Assert(condition)
Definition: c.h:680

◆ GetRealCmin()

static CommandId GetRealCmin ( CommandId  combocid)
static

Definition at line 281 of file combocid.c.

References Assert, ComboCidKeyData::cmin, and usedComboCids.

Referenced by HeapTupleHeaderGetCmin().

282 {
283  Assert(combocid < usedComboCids);
284  return comboCids[combocid].cmin;
285 }
static int usedComboCids
Definition: combocid.c:82
static ComboCidKey comboCids
Definition: combocid.c:81
CommandId cmin
Definition: combocid.c:59
#define Assert(condition)
Definition: c.h:680

◆ HeapTupleHeaderAdjustCmax()

void HeapTupleHeaderAdjustCmax ( HeapTupleHeader  tup,
CommandId cmax,
bool iscombo 
)

Definition at line 154 of file combocid.c.

References GetComboCommandId(), HeapTupleHeaderGetCmin(), HeapTupleHeaderGetRawXmin, HeapTupleHeaderXminCommitted, and TransactionIdIsCurrentTransactionId().

Referenced by heap_delete(), and heap_update().

157 {
158  /*
159  * If we're marking a tuple deleted that was inserted by (any
160  * subtransaction of) our transaction, we need to use a combo command id.
161  * Test for HeapTupleHeaderXminCommitted() first, because it's cheaper
162  * than a TransactionIdIsCurrentTransactionId call.
163  */
164  if (!HeapTupleHeaderXminCommitted(tup) &&
166  {
167  CommandId cmin = HeapTupleHeaderGetCmin(tup);
168 
169  *cmax = GetComboCommandId(cmin, *cmax);
170  *iscombo = true;
171  }
172  else
173  {
174  *iscombo = false;
175  }
176 }
uint32 CommandId
Definition: c.h:469
bool TransactionIdIsCurrentTransactionId(TransactionId xid)
Definition: xact.c:766
CommandId HeapTupleHeaderGetCmin(HeapTupleHeader tup)
Definition: combocid.c:105
#define HeapTupleHeaderXminCommitted(tup)
Definition: htup_details.h:323
static CommandId GetComboCommandId(CommandId cmin, CommandId cmax)
Definition: combocid.c:205
#define HeapTupleHeaderGetRawXmin(tup)
Definition: htup_details.h:307

◆ HeapTupleHeaderGetCmax()

CommandId HeapTupleHeaderGetCmax ( HeapTupleHeader  tup)

Definition at line 119 of file combocid.c.

References Assert, CritSectionCount, GetRealCmax(), HEAP_COMBOCID, HEAP_MOVED, HeapTupleHeaderGetRawCommandId, HeapTupleHeaderGetUpdateXid, HeapTupleHeaderData::t_infomask, and TransactionIdIsCurrentTransactionId().

Referenced by heap_delete(), heap_lock_tuple(), heap_update(), HeapTupleSatisfiesMVCC(), HeapTupleSatisfiesUpdate(), and log_heap_new_cid().

120 {
122 
123  Assert(!(tup->t_infomask & HEAP_MOVED));
124 
125  /*
126  * Because GetUpdateXid() performs memory allocations if xmax is a
127  * multixact we can't Assert() if we're inside a critical section. This
128  * weakens the check, but not using GetCmax() inside one would complicate
129  * things too much.
130  */
131  Assert(CritSectionCount > 0 ||
133 
134  if (tup->t_infomask & HEAP_COMBOCID)
135  return GetRealCmax(cid);
136  else
137  return cid;
138 }
#define HeapTupleHeaderGetUpdateXid(tup)
Definition: htup_details.h:364
uint32 CommandId
Definition: c.h:469
bool TransactionIdIsCurrentTransactionId(TransactionId xid)
Definition: xact.c:766
volatile uint32 CritSectionCount
Definition: globals.c:37
static CommandId GetRealCmax(CommandId combocid)
Definition: combocid.c:288
#define HEAP_MOVED
Definition: htup_details.h:207
#define HEAP_COMBOCID
Definition: htup_details.h:185
#define Assert(condition)
Definition: c.h:680
#define HeapTupleHeaderGetRawCommandId(tup)
Definition: htup_details.h:390

◆ HeapTupleHeaderGetCmin()

CommandId HeapTupleHeaderGetCmin ( HeapTupleHeader  tup)

Definition at line 105 of file combocid.c.

References Assert, GetRealCmin(), HEAP_COMBOCID, HEAP_MOVED, HeapTupleHeaderGetRawCommandId, HeapTupleHeaderGetXmin, HeapTupleHeaderData::t_infomask, and TransactionIdIsCurrentTransactionId().

Referenced by EvalPlanQualFetch(), HeapTupleHeaderAdjustCmax(), HeapTupleSatisfiesMVCC(), HeapTupleSatisfiesUpdate(), and log_heap_new_cid().

106 {
108 
109  Assert(!(tup->t_infomask & HEAP_MOVED));
111 
112  if (tup->t_infomask & HEAP_COMBOCID)
113  return GetRealCmin(cid);
114  else
115  return cid;
116 }
uint32 CommandId
Definition: c.h:469
bool TransactionIdIsCurrentTransactionId(TransactionId xid)
Definition: xact.c:766
static CommandId GetRealCmin(CommandId combocid)
Definition: combocid.c:281
#define HEAP_MOVED
Definition: htup_details.h:207
#define HEAP_COMBOCID
Definition: htup_details.h:185
#define Assert(condition)
Definition: c.h:680
#define HeapTupleHeaderGetXmin(tup)
Definition: htup_details.h:312
#define HeapTupleHeaderGetRawCommandId(tup)
Definition: htup_details.h:390

◆ RestoreComboCIDState()

void RestoreComboCIDState ( char *  comboCIDstate)

Definition at line 344 of file combocid.c.

References Assert, elog, ERROR, GetComboCommandId(), and i.

Referenced by ParallelWorkerMain().

345 {
346  int num_elements;
347  ComboCidKeyData *keydata;
348  int i;
349  CommandId cid;
350 
351  Assert(!comboCids && !comboHash);
352 
353  /* First, we retrieve the number of ComboCIDs that were serialized. */
354  num_elements = *(int *) comboCIDstate;
355  keydata = (ComboCidKeyData *) (comboCIDstate + sizeof(int));
356 
357  /* Use GetComboCommandId to restore each ComboCID. */
358  for (i = 0; i < num_elements; i++)
359  {
360  cid = GetComboCommandId(keydata[i].cmin, keydata[i].cmax);
361 
362  /* Verify that we got the expected answer. */
363  if (cid != i)
364  elog(ERROR, "unexpected command ID while restoring combo CIDs");
365  }
366 }
uint32 CommandId
Definition: c.h:469
static ComboCidKey comboCids
Definition: combocid.c:81
#define ERROR
Definition: elog.h:43
static CommandId GetComboCommandId(CommandId cmin, CommandId cmax)
Definition: combocid.c:205
static HTAB * comboHash
Definition: combocid.c:54
#define Assert(condition)
Definition: c.h:680
int i
#define elog
Definition: elog.h:219

◆ SerializeComboCIDState()

void SerializeComboCIDState ( Size  maxsize,
char *  start_address 
)

Definition at line 318 of file combocid.c.

References elog, ERROR, and usedComboCids.

Referenced by InitializeParallelDSM().

319 {
320  char *endptr;
321 
322  /* First, we store the number of currently-existing ComboCIDs. */
323  *(int *) start_address = usedComboCids;
324 
325  /* If maxsize is too small, throw an error. */
326  endptr = start_address + sizeof(int) +
327  (sizeof(ComboCidKeyData) * usedComboCids);
328  if (endptr < start_address || endptr > start_address + maxsize)
329  elog(ERROR, "not enough space to serialize ComboCID state");
330 
331  /* Now, copy the actual cmin/cmax pairs. */
332  if (usedComboCids > 0)
333  memcpy(start_address + sizeof(int), comboCids,
334  (sizeof(ComboCidKeyData) * usedComboCids));
335 }
static int usedComboCids
Definition: combocid.c:82
static ComboCidKey comboCids
Definition: combocid.c:81
#define ERROR
Definition: elog.h:43
#define elog
Definition: elog.h:219

Variable Documentation

◆ comboCids

ComboCidKey comboCids = NULL
static

Definition at line 81 of file combocid.c.

◆ comboHash

HTAB* comboHash = NULL
static

Definition at line 54 of file combocid.c.

◆ sizeComboCids

int sizeComboCids = 0
static

Definition at line 83 of file combocid.c.

Referenced by AtEOXact_ComboCid(), and GetComboCommandId().

◆ usedComboCids

int usedComboCids = 0
static