-uint64_t tm_get (txn_t *txn, void *key) {
-
- // Iterate through update records associated with <key> to find the latest committed version.
- // We can use the first matching version. Older updates always come later in the list.
- update_rec_t *update = (update_rec_t *) map_get(txn->map, key);
- for (; update != NULL; update = update->prev) {
- uint64_t writer_version = update->version;
- if (writer_version < txn->rv)
- return update->value;
-
- // If the version is tagged, it means that it is not a version number, but a pointer to an
- // in progress transaction.
- if (IS_TAGGED(update->version)) {
- txn_t *writer = (txn_t *)STRIP_TAG(writer_version);
-
- if (writer == txn)
- return update->type == UPDATE_TYPE_DELETE ? DOES_NOT_EXIST : update->value;
-
- // Skip updates from aborted transactions.
- txn_state_e writer_state = writer->state;
- if (EXPECT_FALSE(writer_state == TXN_ABORTED))
+map_val_t txn_map_get (txn_t *txn, map_key_t key) {
+ if (txn->state != TXN_RUNNING)
+ return ERROR_TXN_NOT_RUNNING;
+
+ // Iterate through the update records to find the latest committed version prior to our read version.
+ map_val_t newest_val = map_get(txn->map, key);
+ map_val_t val = newest_val;
+ update_t *update = NULL;
+ for ( ; ; val = update->next) {
+
+ if (!IS_TAGGED(val, TAG2))
+ return val;
+
+ update = (update_t *)STRIP_TAG(val, TAG2);
+ assert(update != NULL);
+
+ // If the update's version is not tagged it means the update is committed.
+ if (!IS_TAGGED(update->version, TAG1)) {
+ if (update->version <= txn->rv)
+ break; // success
+ continue;
+ }
+
+ // 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 updates from 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, TAG1);
+ if (writer == txn) // found our own update
+ break; // success
+
+ txn_state_e writer_state = writer->state;
+ if (writer_state == TXN_RUNNING)
+ continue;
+
+ if (writer_state == TXN_VALIDATING) {
+ if (writer->wv > txn->rv)