- update_rec_t *next = update->next;
- if (next != NULL) {
- uint64_t min_active_version = (uint64_t)sl_min_key(active_);
- if (next->version < min_active_version) {
- next = SYNC_SWAP(&update->next, NULL);
- while (next != NULL) {
+ update_t *last = update;
+ update_t *next = update->next;
+ uint64_t min_active = 0;
+ if (IS_TAGGED(next, TAG2)) {
+ next = (update_t *)STRIP_TAG(next, TAG2);
+ min_active = (uint64_t)sl_min_key(active_);
+ if (next->version < min_active) {
+
+ // Skip over aborted versions to verify the chain of updates is old enough for collection
+ update_t *temp = next;
+ while (temp->version == ABORTED_VERSION) {
+ assert(!IS_TAGGED(temp->version, TAG1));
+ update_t *temp = next->next;
+ if (!IS_TAGGED(temp, TAG2))
+ break;
+ temp = (update_t *)STRIP_TAG(temp, TAG2);
+ if (temp->version >= min_active)
+ return value;
+ temp = temp->next;
+ }
+
+ // collect <next> and all the update records following it
+ do {
+ next = SYNC_SWAP(&update->next, NULL);
+
+ // if we find ourself in a race just back off and let the other thread take care of it
+ if (next == NULL)
+ return value;
+