- for (; update != NULL; update = update->prev) {
- uint64_t writer_version = update->version;
- if (writer_version <= txn->rv)
- return TXN_VALIDATED;
-
- // If the version is tagged, it means it is a pointer to a transaction in progress.
- if (IS_TAGGED(writer_version)) {
-
- // Skip aborted transactions.
- if (EXPECT_FALSE(writer_version == TAG_VALUE(0)))
- continue;
-
- // Skip our own updates.
- txn_t *writer = (txn_t *)STRIP_TAG(writer_version);
- if (writer == txn)
- continue;
-
- writer_version = writer->wv;
- if (writer_version <= txn->rv && writer_version != UNDETERMINED_VERSION)
- return TXN_VALIDATED;
-
- txn_state_e writer_state = writer->state;
- if (EXPECT_FALSE(writer_state == TXN_ABORTED))
+ for (; update != NULL; update = update->next) {
+
+ // If the update's version is not tagged it means the update is committed.
+ //
+ // We can stop at the first committed record we find that is at least as old as our read version. All
+ // the other committed records following it will be older. And all the uncommitted records following it
+ // will eventually conflict with it and abort.
+ if (!IS_TAGGED(update->version))
+ return (update->version <= txn->rv) ? TXN_VALIDATED : TXN_ABORTED;
+
+ // If the update's version is tagged then either the update was aborted or the the version number is
+ // actually a pointer to a running transaction's txn_t.
+
+ // Skip aborted transactions.
+ if (EXPECT_FALSE(update->version == ABORTED_VERSION))
+ continue;
+
+ // The update's transaction is still in progress. Access its txn_t.
+ txn_t *writer = (txn_t *)STRIP_TAG(update->version);
+ if (writer == txn)
+ continue; // Skip our own updates.
+ txn_state_e writer_state = writer->state;
+
+ // Any running transaction will only be able to aquire a wv greater than ours. A transaction changes its
+ // state to validating before aquiring a wv. We can ignore an unvalidated transaction if its version is
+ // greater than ours. See next comment below for why.
+ if (writer_state == TXN_RUNNING)
+ continue;
+
+ // If <writer> has a later version than us we can safely ignore its updates. It will not commit until
+ // we have completed validation (in order to remain non-blocking it will help us validate if necessary).
+ // This protocol ensures a deterministic resolution to every conflict and avoids infinite ping-ponging
+ // between validating two conflicting transactions.
+ if (writer_state == TXN_VALIDATING) {
+ if (writer->wv > txn->wv)