PostgreSQL Source Code  git master
combocid.c File Reference
#include "postgres.h"
#include "access/htup_details.h"
#include "access/xact.h"
#include "miscadmin.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 85 of file combocid.c.

Referenced by GetComboCommandId().

◆ CCID_HASH_SIZE

#define CCID_HASH_SIZE   100

Definition at line 73 of file combocid.c.

Referenced by GetComboCommandId().

Typedef Documentation

◆ ComboCidEntry

Definition at line 70 of file combocid.c.

◆ ComboCidKey

Definition at line 62 of file combocid.c.

Function Documentation

◆ AtEOXact_ComboCid()

void AtEOXact_ComboCid ( void  )

Definition at line 182 of file combocid.c.

References sizeComboCids, and usedComboCids.

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

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

◆ EstimateComboCIDStateSpace()

Size EstimateComboCIDStateSpace ( void  )

Definition at line 297 of file combocid.c.

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

Referenced by InitializeParallelDSM().

298 {
299  Size size;
300 
301  /* Add space required for saving usedComboCids */
302  size = sizeof(int);
303 
304  /* Add space required for saving ComboCidKeyData */
305  size = add_size(size, mul_size(sizeof(ComboCidKeyData), usedComboCids));
306 
307  return size;
308 }
static int usedComboCids
Definition: combocid.c:81
Size mul_size(Size s1, Size s2)
Definition: shmem.c:519
Size add_size(Size s1, Size s2)
Definition: shmem.c:502
size_t Size
Definition: c.h:540

◆ GetComboCommandId()

static CommandId GetComboCommandId ( CommandId  cmin,
CommandId  cmax 
)
static

Definition at line 204 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, sort-test::key, HASHCTL::keysize, MemoryContextAlloc(), repalloc(), sizeComboCids, TopTransactionContext, and usedComboCids.

Referenced by HeapTupleHeaderAdjustCmax(), and RestoreComboCIDState().

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

◆ GetRealCmax()

static CommandId GetRealCmax ( CommandId  combocid)
static

Definition at line 286 of file combocid.c.

References Assert, ComboCidKeyData::cmax, and usedComboCids.

Referenced by HeapTupleHeaderGetCmax().

287 {
288  Assert(combocid < usedComboCids);
289  return comboCids[combocid].cmax;
290 }
static int usedComboCids
Definition: combocid.c:81
static ComboCidKey comboCids
Definition: combocid.c:80
CommandId cmax
Definition: combocid.c:59
#define Assert(condition)
Definition: c.h:804

◆ GetRealCmin()

static CommandId GetRealCmin ( CommandId  combocid)
static

Definition at line 279 of file combocid.c.

References Assert, ComboCidKeyData::cmin, and usedComboCids.

Referenced by HeapTupleHeaderGetCmin().

280 {
281  Assert(combocid < usedComboCids);
282  return comboCids[combocid].cmin;
283 }
static int usedComboCids
Definition: combocid.c:81
static ComboCidKey comboCids
Definition: combocid.c:80
CommandId cmin
Definition: combocid.c:58
#define Assert(condition)
Definition: c.h:804

◆ HeapTupleHeaderAdjustCmax()

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

Definition at line 153 of file combocid.c.

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

Referenced by heap_delete(), and heap_update().

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

◆ HeapTupleHeaderGetCmax()

CommandId HeapTupleHeaderGetCmax ( HeapTupleHeader  tup)

Definition at line 118 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().

119 {
121 
122  Assert(!(tup->t_infomask & HEAP_MOVED));
123 
124  /*
125  * Because GetUpdateXid() performs memory allocations if xmax is a
126  * multixact we can't Assert() if we're inside a critical section. This
127  * weakens the check, but not using GetCmax() inside one would complicate
128  * things too much.
129  */
130  Assert(CritSectionCount > 0 ||
132 
133  if (tup->t_infomask & HEAP_COMBOCID)
134  return GetRealCmax(cid);
135  else
136  return cid;
137 }
#define HeapTupleHeaderGetUpdateXid(tup)
Definition: htup_details.h:365
uint32 CommandId
Definition: c.h:601
bool TransactionIdIsCurrentTransactionId(TransactionId xid)
Definition: xact.c:869
volatile uint32 CritSectionCount
Definition: globals.c:41
static CommandId GetRealCmax(CommandId combocid)
Definition: combocid.c:286
#define HEAP_MOVED
Definition: htup_details.h:216
#define HEAP_COMBOCID
Definition: htup_details.h:194
#define Assert(condition)
Definition: c.h:804
#define HeapTupleHeaderGetRawCommandId(tup)
Definition: htup_details.h:391

◆ HeapTupleHeaderGetCmin()

CommandId HeapTupleHeaderGetCmin ( HeapTupleHeader  tup)

Definition at line 104 of file combocid.c.

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

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

105 {
107 
108  Assert(!(tup->t_infomask & HEAP_MOVED));
110 
111  if (tup->t_infomask & HEAP_COMBOCID)
112  return GetRealCmin(cid);
113  else
114  return cid;
115 }
uint32 CommandId
Definition: c.h:601
bool TransactionIdIsCurrentTransactionId(TransactionId xid)
Definition: xact.c:869
static CommandId GetRealCmin(CommandId combocid)
Definition: combocid.c:279
#define HEAP_MOVED
Definition: htup_details.h:216
#define HEAP_COMBOCID
Definition: htup_details.h:194
#define Assert(condition)
Definition: c.h:804
#define HeapTupleHeaderGetXmin(tup)
Definition: htup_details.h:313
#define HeapTupleHeaderGetRawCommandId(tup)
Definition: htup_details.h:391

◆ RestoreComboCIDState()

void RestoreComboCIDState ( char *  comboCIDstate)

Definition at line 342 of file combocid.c.

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

Referenced by ParallelWorkerMain().

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

◆ SerializeComboCIDState()

void SerializeComboCIDState ( Size  maxsize,
char *  start_address 
)

Definition at line 316 of file combocid.c.

References elog, ERROR, and usedComboCids.

Referenced by InitializeParallelDSM().

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

Variable Documentation

◆ comboCids

ComboCidKey comboCids = NULL
static

Definition at line 80 of file combocid.c.

◆ comboHash

HTAB* comboHash = NULL
static

Definition at line 53 of file combocid.c.

◆ sizeComboCids

int sizeComboCids = 0
static

Definition at line 82 of file combocid.c.

Referenced by AtEOXact_ComboCid(), and GetComboCommandId().

◆ usedComboCids

int usedComboCids = 0
static