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:562
Size add_size(Size s1, Size s2)
Definition: shmem.c:488
Size mul_size(Size s1, Size s2)
Definition: shmem.c:505
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 */
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,
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;
272
273 entry->combocid = combocid;
274
275 return combocid;
276}
uint32 CommandId
Definition: c.h:623
#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
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:1181
MemoryContext TopTransactionContext
Definition: mcxt.c:154
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1541
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:815

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 */
165 {
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:940

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 */
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:44
#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)

◆ 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
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:225
int i
Definition: isn.c:72

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