[ovs-dev] [RFC HSA 1/4] ovs_list: Extend list functions.
Ben Pfaff
blp at nicira.com
Tue Mar 31 04:19:58 UTC 2015
On Mon, Mar 30, 2015 at 03:46:26PM -0700, Alex Wang wrote:
> This commit adds function that allows the appending of one list
> content to the other. Also, it adds functions which allows list
> to be sorted.
>
> Signed-off-by: Alex Wang <alexw at nicira.com>
I always like new basic algorithms!
> +/* Appends 'src''s content to the end of 'dst'. After 'list_join', 'src'
> + * becomes an empty list. */
> +static inline void
> +list_join(struct ovs_list *dst, struct ovs_list *src)
> +{
> + if (list_is_empty(src)) {
> + return;
> + }
> +
> + list_splice(dst, list_front(src), src);
> +}
I think that list_join() can be simplified to just:
list_splice(dst, src->next, src);
because if 'src' is empty then src->next == next and list_splice()
will become a no-op because of its test for first == last.
> +/* Swaps the two adjacent list elements. 'ahead' must be ahead of 'after'. */
> +static inline void
> +list_swap_adjacent(struct ovs_list *ahead, struct ovs_list *after)
> +{
> + ahead->next = after->next;
> + ahead->next->prev = ahead;
> + after->prev = ahead->prev;
> + ahead->prev->next = after;
> + ahead->prev = after;
> + after->next = ahead;
> +}
> +
> +/* Swaps the position of two list nodes, 'elem1' and 'elem2'. */
> +static inline void
> +list_swap(struct ovs_list *elem1, struct ovs_list *elem2)
> +{
> + if (elem1 == elem2) {
> + return;
> + } else if (elem1->prev == elem2) {
> + /* element2 is ahead of element1. */
> + list_swap_adjacent(elem2, elem1);
> + } else if (elem2->prev == elem1) {
> + /* element1 is ahead of element2. */
> + list_swap_adjacent(elem1, elem2);
> + } else {
> + const struct ovs_list tmp = *elem1;
> +
> + list_replace(elem1, elem2);
> + list_replace(elem2, &tmp);
> + }
> +}
I think that list_swap() can be simplified to the following, although I
have not tested it:
/* Exchanges the positions of A and B, which may be in the same list
* or different lists. */
void
ovs_list_swap(struct ovs_list *a, struct ovs_list *b)
{
if (a != b)
{
if (a->next != b)
{
struct ovs_list *a_next = list_remove(a);
struct ovs_list *b_next = list_remove(b);
list_insert(b_next, a);
list_insert(a_next, b);
}
else
{
list_remove(b);
list_insert(a, b);
}
}
}
> /* Adjusts pointers around 'list' to compensate for 'list' having been moved
> * around in memory (e.g. as a consequence of realloc()), with original
> * location 'orig'.
> @@ -233,6 +281,25 @@ list_back(const struct ovs_list *list_)
> return list->prev;
> }
>
> +/* Returns the element at position 'n', assumes the first element is
> + * at index 0. The 'list_' must contain at least 'n' elements. */
> +static inline struct ovs_list *
> +list_at_position(const struct ovs_list *list_, size_t n)
> +{
> + struct ovs_list *list = CONST_CAST(struct ovs_list *, list_);
> + struct ovs_list *ret;
> + size_t cnt = 0;
> +
> + for (ret = list->next; ret != list; ret = ret->next) {
> + if (cnt++ == n) {
> + return ret;
> + }
> + }
I'd probably just write the following two statements as OVS_NOT_REACHED():
> + ovs_assert(false);
> +
> + return NULL;
> +}
Thanks,
Ben.
More information about the dev
mailing list