/* * Given a tuple we are about to delete, determine the correct value to store * into its t_cid field. * * If we don't need a combo CID, *cmax is unchanged and *iscombo is set to * FALSE. If we do need one, *cmax is replaced by a combo CID and *iscombo * is set to TRUE. * * The reason this is separate from the actual HeapTupleHeaderSetCmax() * operation is that this could fail due to out-of-memory conditions. Hence * we need to do this before entering the critical section that actually * changes the tuple in shared buffers. */ void HeapTupleHeaderAdjustCmax(HeapTupleHeader tup, CommandId *cmax, bool *iscombo) { /* * If we're marking a tuple deleted that was inserted by (any * subtransaction of) our transaction, we need to use a combo command id. * Test for HeapTupleHeaderXminCommitted() first, because it's cheaper than a * TransactionIdIsCurrentTransactionId call. */ if (!HeapTupleHeaderXminCommitted(tup) && TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmin(tup))) { CommandId cmin = HeapTupleHeaderGetCmin(tup); *cmax = GetComboCommandId(cmin, *cmax); *iscombo = true; } else { *iscombo = false; } }
/* * Read the ComboCID state at the specified address and initialize this * backend with the same ComboCIDs. This is only valid in a backend that * currently has no ComboCIDs (and only makes sense if the transaction state * is serialized and restored as well). */ void RestoreComboCIDState(char *comboCIDstate) { int num_elements; ComboCidKeyData *keydata; int i; CommandId cid; Assert(!comboCids && !comboHash); /* First, we retrieve the number of ComboCIDs that were serialized. */ num_elements = *(int *) comboCIDstate; keydata = (ComboCidKeyData *) (comboCIDstate + sizeof(int)); /* Use GetComboCommandId to restore each ComboCID. */ for (i = 0; i < num_elements; i++) { cid = GetComboCommandId(keydata[i].cmin, keydata[i].cmax); /* Verify that we got the expected answer. */ if (cid != i) elog(ERROR, "unexpected command ID while restoring combo CIDs"); } }