long commitTimestamp = tsv;
/*
* There were members on at least one of the lists so we need to try to
* find the corresponding TransactionStatus identified by tsv.
*/
TransactionStatus status = getStatus(tsv);
/*
* The result can be null in the event the TransactionStatus was freed.
* It could only have been freed if its transaction committed at a tc
* that is now primordial. Therefore if status is null we can return tsv
* as the imputed tc value.
*/
if (status != null) {
/*
* Found the TransactionStatus identified by tsv, but by the time we
* we read its tc, that TransactionStatus may already be committed
* to a new transaction with a different ts. Therefore we briefly to
* lock it to get an accurate reading.
*
* If the TransactionStatus was concurrently freed and reallocated
* to a different transaction, then it must have committed before
* the floor timestamp.
*/
long tc = status.getTc();
while (status.getTs() == tsv) {
if (tc >= ts) {
return UNCOMMITTED;
}
if (tc >= 0) {
return tc;
}
if (tc == ABORTED) {
return tc;
}
/*
* Waiting for status to resolve. To do this, lock, unlock and
* then retry.
*/
if (status.wwLock(SHORT_TIMEOUT)) {
tc = status.getTc();
status.wwUnlock();
}
}
}
return commitTimestamp;
}