Optimize meld in qr module
The goal of `qr_meld()` is to change the following four fields `(a->prev, a->prev->next, b->prev, b->prev->next)` from the values `(a->prev, a, b->prev, b)` to `(b->prev, b, a->prev, a)`. This commit changes ``` a->prev->next = b; b->prev->next = a; temp = a->prev; a->prev = b->prev; b->prev = temp; ``` to ``` temp = a->prev; a->prev = b->prev; b->prev = temp; a->prev->next = a; b->prev->next = b; ``` The benefit is that we can use `b->prev->next` for `temp`, and so there's no need to pass in `a_type`. The restriction is that `b` cannot be a `qr_next()` macro, so users of `qr_meld()` must pay attention. (Before this change, neither `a` nor `b` could be a `qr_next()` macro.)
This commit is contained in:
parent
0d6d9e8586
commit
c9d56cddf2
@ -32,21 +32,23 @@ struct { \
|
||||
(a_qrelm)->a_field.qre_next = (a_qr); \
|
||||
} while (0)
|
||||
|
||||
#define qr_meld(a_qr_a, a_qr_b, a_type, a_field) do { \
|
||||
a_type *t; \
|
||||
(a_qr_a)->a_field.qre_prev->a_field.qre_next = (a_qr_b); \
|
||||
(a_qr_b)->a_field.qre_prev->a_field.qre_next = (a_qr_a); \
|
||||
t = (a_qr_a)->a_field.qre_prev; \
|
||||
/* a_qr_a can directly be a qr_next() macro, but a_qr_b cannot. */
|
||||
#define qr_meld(a_qr_a, a_qr_b, a_field) do { \
|
||||
(a_qr_b)->a_field.qre_prev->a_field.qre_next = \
|
||||
(a_qr_a)->a_field.qre_prev; \
|
||||
(a_qr_a)->a_field.qre_prev = (a_qr_b)->a_field.qre_prev; \
|
||||
(a_qr_b)->a_field.qre_prev = t; \
|
||||
(a_qr_b)->a_field.qre_prev = \
|
||||
(a_qr_b)->a_field.qre_prev->a_field.qre_next; \
|
||||
(a_qr_a)->a_field.qre_prev->a_field.qre_next = (a_qr_a); \
|
||||
(a_qr_b)->a_field.qre_prev->a_field.qre_next = (a_qr_b); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* qr_meld() and qr_split() are functionally equivalent, so there's no need to
|
||||
* have two copies of the code.
|
||||
*/
|
||||
#define qr_split(a_qr_a, a_qr_b, a_type, a_field) \
|
||||
qr_meld((a_qr_a), (a_qr_b), a_type, a_field)
|
||||
#define qr_split(a_qr_a, a_qr_b, a_field) \
|
||||
qr_meld((a_qr_a), (a_qr_b), a_field)
|
||||
|
||||
#define qr_remove(a_qr, a_field) do { \
|
||||
(a_qr)->a_field.qre_prev->a_field.qre_next \
|
||||
|
@ -212,22 +212,22 @@ TEST_BEGIN(test_qr_meld_split) {
|
||||
qr_after_insert(&entries[i - 1], &entries[i], link);
|
||||
}
|
||||
|
||||
qr_split(&entries[0], &entries[SPLIT_INDEX], ring_t, link);
|
||||
qr_split(&entries[0], &entries[SPLIT_INDEX], link);
|
||||
test_split_entries(entries);
|
||||
|
||||
qr_meld(&entries[0], &entries[SPLIT_INDEX], ring_t, link);
|
||||
qr_meld(&entries[0], &entries[SPLIT_INDEX], link);
|
||||
test_entries_ring(entries);
|
||||
|
||||
qr_meld(&entries[0], &entries[SPLIT_INDEX], ring_t, link);
|
||||
qr_meld(&entries[0], &entries[SPLIT_INDEX], link);
|
||||
test_split_entries(entries);
|
||||
|
||||
qr_split(&entries[0], &entries[SPLIT_INDEX], ring_t, link);
|
||||
qr_split(&entries[0], &entries[SPLIT_INDEX], link);
|
||||
test_entries_ring(entries);
|
||||
|
||||
qr_split(&entries[0], &entries[0], ring_t, link);
|
||||
qr_split(&entries[0], &entries[0], link);
|
||||
test_entries_ring(entries);
|
||||
|
||||
qr_meld(&entries[0], &entries[0], ring_t, link);
|
||||
qr_meld(&entries[0], &entries[0], link);
|
||||
test_entries_ring(entries);
|
||||
}
|
||||
TEST_END
|
||||
|
Loading…
Reference in New Issue
Block a user