Replace stailq_splice with stailq_cut_tail
stailq_splice(head1, item, head2) moves elements from list 'head1' starting from 'item' to list 'head2'. To follow the protocol, it needs to know the element previous to 'item' in 'head1' so as to make it the new last element of 'head1'. To achieve that, it has to loop over 'head1', which is inefficient. Actually, wherever we use this function, we know in advance the element stailq_splice() has to look up, but we still pass the next one, making its life difficult and obscuring the code at the caller's side. For example, look at how stailq_splice() is used in txn.c: if (stmt == NULL) { rollback_stmts = txn->stmts; stailq_create(&txn->stmts); } else { stailq_create(&rollback_stmts); stmt = stailq_next_entry(stmt, next); stailq_splice(&txn->stmts, &stmt->next, &rollback_stmts); } while under the hood stailq_splice() has the loop to find 'stmt': stailq_splice(struct stailq *head1, struct stailq_entry *elem, struct stailq *head2) { if (elem) { *head2->last = elem; head2->last = head1->last; head1->last = &head1->first; while (*head1->last != elem) head1->last = &(*head1->last)->next; *head1->last = NULL; } } This is utterly preposterous. Let's replace stailq_splice() with a new method with the same signature, but with a slightly different semantics: move all elements from list 'head1' starting from the element *following* 'item' to list 'head2'; if 'item' is NULL, move all elements from 'head1' to 'head2'. This greatly simplifies the code for both parties, as the callee doesn't have to loop any more while the caller doesn't have to handle the case when 'item' is NULL. Also, let's change the name of this function, because stailq_splice() sounds kinda confusing: after all, this function tears a list in two first and only then splices the tail with another list. Let's remove the 'splice' part altogether (anyway, there's another function for splicing lists - stailq_concat()) and call it stailq_cut_tail().
Showing
- src/box/txn.c 1 addition, 8 deletionssrc/box/txn.c
- src/box/vy_log.c 7 additions, 12 deletionssrc/box/vy_log.c
- src/box/vy_tx.c 1 addition, 8 deletionssrc/box/vy_tx.c
- src/box/wal.cc 10 additions, 15 deletionssrc/box/wal.cc
- src/lib/salad/stailq.h 18 additions, 10 deletionssrc/lib/salad/stailq.h
- test/unit/stailq.c 41 additions, 3 deletionstest/unit/stailq.c
- test/unit/stailq.result 32 additions, 1 deletiontest/unit/stailq.result
Loading
Please register or sign in to comment