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.

◆ CCID_HASH_SIZE

#define CCID_HASH_SIZE   100

Definition at line 73 of file combocid.c.

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.

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 ComboCidKey comboCids
Definition: combocid.c:80
static HTAB * comboHash
Definition: combocid.c:53
static int usedComboCids
Definition: combocid.c:81
static int sizeComboCids
Definition: combocid.c:82

References comboCids, comboHash, sizeComboCids, and usedComboCids.

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

◆ EstimateComboCIDStateSpace()

Size EstimateComboCIDStateSpace ( void  )

Definition at line 297 of file combocid.c.

298 {
299  Size size;
300 
301  /* Add space required for saving usedComboCids */
302  size = sizeof(int);
303 
304  /* Add space required for saving ComboCidKeyData */
306 
307  return size;
308 }
size_t Size
Definition: c.h:605
Size add_size(Size s1, Size s2)
Definition: shmem.c:493
Size mul_size(Size s1, Size s2)
Definition: shmem.c:510
static pg_noinline void Size size
Definition: slab.c:607

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

Referenced by InitializeParallelDSM().

◆ GetComboCommandId()

static CommandId GetComboCommandId ( CommandId  cmin,
CommandId  cmax 
)
static

Definition at line 204 of file combocid.c.

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  &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:666
#define CCID_HASH_SIZE
Definition: combocid.c:73
#define CCID_ARRAY_SIZE
Definition: combocid.c:85
ComboCidEntryData * ComboCidEntry
Definition: combocid.c:70
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition: dynahash.c:955
HTAB * hash_create(const char *tabname, long nelem, const HASHCTL *info, int flags)
Definition: dynahash.c:352
@ HASH_ENTER
Definition: hsearch.h:114
#define HASH_CONTEXT
Definition: hsearch.h:102
#define HASH_ELEM
Definition: hsearch.h:95
#define HASH_BLOBS
Definition: hsearch.h:97
MemoryContext TopTransactionContext
Definition: mcxt.c:154
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1540
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:1180
CommandId combocid
Definition: combocid.c:67
CommandId cmax
Definition: combocid.c:59
CommandId cmin
Definition: combocid.c:58
Size keysize
Definition: hsearch.h:75
Size entrysize
Definition: hsearch.h:76
MemoryContext hcxt
Definition: hsearch.h:86

References CCID_ARRAY_SIZE, CCID_HASH_SIZE, ComboCidKeyData::cmax, ComboCidKeyData::cmin, ComboCidEntryData::combocid, comboCids, comboHash, 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().

◆ GetRealCmax()

static CommandId GetRealCmax ( CommandId  combocid)
static

Definition at line 286 of file combocid.c.

287 {
288  Assert(combocid < usedComboCids);
289  return comboCids[combocid].cmax;
290 }
#define Assert(condition)
Definition: c.h:858

References Assert, ComboCidKeyData::cmax, comboCids, and usedComboCids.

Referenced by HeapTupleHeaderGetCmax().

◆ GetRealCmin()

static CommandId GetRealCmin ( CommandId  combocid)
static

Definition at line 279 of file combocid.c.

280 {
281  Assert(combocid < usedComboCids);
282  return comboCids[combocid].cmin;
283 }

References Assert, ComboCidKeyData::cmin, comboCids, and usedComboCids.

Referenced by HeapTupleHeaderGetCmin().

◆ HeapTupleHeaderAdjustCmax()

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

Definition at line 153 of file combocid.c.

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 }
CommandId HeapTupleHeaderGetCmin(HeapTupleHeader tup)
Definition: combocid.c:104
static CommandId GetComboCommandId(CommandId cmin, CommandId cmax)
Definition: combocid.c:204
#define HeapTupleHeaderGetRawXmin(tup)
Definition: htup_details.h:304
#define HeapTupleHeaderXminCommitted(tup)
Definition: htup_details.h:320
bool TransactionIdIsCurrentTransactionId(TransactionId xid)
Definition: xact.c:938

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

Referenced by heap_delete(), and heap_update().

◆ HeapTupleHeaderGetCmax()

CommandId HeapTupleHeaderGetCmax ( HeapTupleHeader  tup)

Definition at line 118 of file combocid.c.

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 }
static CommandId GetRealCmax(CommandId combocid)
Definition: combocid.c:286
volatile uint32 CritSectionCount
Definition: globals.c:43
#define HEAP_MOVED
Definition: htup_details.h:213
#define HEAP_COMBOCID
Definition: htup_details.h:195
#define HeapTupleHeaderGetUpdateXid(tup)
Definition: htup_details.h:361
#define HeapTupleHeaderGetRawCommandId(tup)
Definition: htup_details.h:387

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().

◆ HeapTupleHeaderGetCmin()

CommandId HeapTupleHeaderGetCmin ( HeapTupleHeader  tup)

Definition at line 104 of file combocid.c.

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 }
static CommandId GetRealCmin(CommandId combocid)
Definition: combocid.c:279
#define HeapTupleHeaderGetXmin(tup)
Definition: htup_details.h:309

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().

◆ RestoreComboCIDState()

void RestoreComboCIDState ( char *  comboCIDstate)

Definition at line 342 of file combocid.c.

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 }
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:224
int i
Definition: isn.c:73

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

Referenced by ParallelWorkerMain().

◆ SerializeComboCIDState()

void SerializeComboCIDState ( Size  maxsize,
char *  start_address 
)

Definition at line 316 of file combocid.c.

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 }

References comboCids, elog, ERROR, and usedComboCids.

Referenced by InitializeParallelDSM().

Variable Documentation

◆ comboCids

◆ comboHash

HTAB* comboHash = NULL
static

Definition at line 53 of file combocid.c.

Referenced by AtEOXact_ComboCid(), GetComboCommandId(), and RestoreComboCIDState().

◆ sizeComboCids

int sizeComboCids = 0
static

Definition at line 82 of file combocid.c.

Referenced by AtEOXact_ComboCid(), and GetComboCommandId().

◆ usedComboCids

int usedComboCids = 0
static