@@ -370,6 +370,49 @@ FullTransactionIdNewer(FullTransactionId a, FullTransactionId b)
370370 return b ;
371371}
372372
373+ /*
374+ * Compute FullTransactionId for the given TransactionId, assuming xid was
375+ * between [oldestXid, nextXid] at the time when TransamVariables->nextXid was
376+ * nextFullXid. When adding calls, evaluate what prevents xid from preceding
377+ * oldestXid if SetTransactionIdLimit() runs between the collection of xid and
378+ * the collection of nextFullXid.
379+ */
380+ static inline FullTransactionId
381+ FullTransactionIdFromAllowableAt (FullTransactionId nextFullXid ,
382+ TransactionId xid )
383+ {
384+ uint32 epoch ;
385+
386+ /* Special transaction ID. */
387+ if (!TransactionIdIsNormal (xid ))
388+ return FullTransactionIdFromEpochAndXid (0 , xid );
389+
390+ Assert (TransactionIdPrecedesOrEquals (xid ,
391+ XidFromFullTransactionId (nextFullXid )));
392+
393+ /*
394+ * The 64 bit result must be <= nextFullXid, since nextFullXid hadn't been
395+ * issued yet when xid was in the past. The xid must therefore be from
396+ * the epoch of nextFullXid or the epoch before. We know this because we
397+ * must remove (by freezing) an XID before assigning the XID half an epoch
398+ * ahead of it.
399+ *
400+ * The unlikely() branch hint is dubious. It's perfect for the first 2^32
401+ * XIDs of a cluster's life. Right at 2^32 XIDs, misprediction shoots to
402+ * 100%, then improves until perfection returns 2^31 XIDs later. Since
403+ * current callers pass relatively-recent XIDs, expect >90% prediction
404+ * accuracy overall. This favors average latency over tail latency.
405+ */
406+ epoch = EpochFromFullTransactionId (nextFullXid );
407+ if (unlikely (xid > XidFromFullTransactionId (nextFullXid )))
408+ {
409+ Assert (epoch != 0 );
410+ epoch -- ;
411+ }
412+
413+ return FullTransactionIdFromEpochAndXid (epoch , xid );
414+ }
415+
373416#endif /* FRONTEND */
374417
375418#endif /* TRANSAM_H */
0 commit comments