Thanks for the review, really good points, adopt both,

On Tue, Jun 2, 2015 at 12:57 PM, Andy Zhou <az...@nicira.com> wrote:

> On Mon, Jun 1, 2015 at 11:24 AM, Alex Wang <al...@nicira.com> 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 <al...@nicira.com>
> > ---
> > RFC->RFC V2:
> > - Adopt Ben's suggestions.
> >
> > ---
> >  lib/list.h        |   48 ++++++++++++++++++++++++
> >  tests/library.at  |    2 +-
> >  tests/test-list.c |  106
> +++++++++++++++++++++++++++++++++++++++++++++++++++++
> >  3 files changed, 155 insertions(+), 1 deletion(-)
> >
> > diff --git a/lib/list.h b/lib/list.h
> > index 7ba1e35..229f1c3 100644
> > --- a/lib/list.h
> > +++ b/lib/list.h
> > @@ -30,10 +30,12 @@ static inline void list_poison(struct ovs_list *);
> >  static inline void list_insert(struct ovs_list *, struct ovs_list *);
> >  static inline void list_splice(struct ovs_list *before, struct ovs_list
> *first,
> >                                 struct ovs_list *last);
> > +static inline void list_join(struct ovs_list *dst, struct ovs_list
> *src);
> >  static inline void list_push_front(struct ovs_list *, struct ovs_list
> *);
> >  static inline void list_push_back(struct ovs_list *, struct ovs_list *);
> >  static inline void list_replace(struct ovs_list *, const struct
> ovs_list *);
> >  static inline void list_moved(struct ovs_list *, const struct ovs_list
> *orig);
> > +static inline void list_swap(struct ovs_list *, struct ovs_list *);
> >  static inline void list_move(struct ovs_list *dst, struct ovs_list
> *src);
> >
> >  /* List removal. */
> > @@ -44,6 +46,8 @@ static inline struct ovs_list *list_pop_back(struct
> ovs_list *);
> >  /* List elements. */
> >  static inline struct ovs_list *list_front(const struct ovs_list *);
> >  static inline struct ovs_list *list_back(const struct ovs_list *);
> > +static inline struct ovs_list *list_at_position(const struct ovs_list *,
> > +                                                size_t n);
> >
> >  /* List properties. */
> >  static inline size_t list_size(const struct ovs_list *);
> > @@ -104,6 +108,14 @@ list_insert(struct ovs_list *before, struct
> ovs_list *elem)
> >      before->prev = elem;
> >  }
> >
> > +/* 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)
> > +{
> > +    list_splice(dst, src->next, src);
> > +}
> > +
> >  /* Removes elements 'first' though 'last' (exclusive) from their
> current list,
> >     then inserts them just before 'before'. */
> >  static inline void
> > @@ -152,6 +164,25 @@ list_replace(struct ovs_list *element, const struct
> ovs_list *position)
> >      element->prev->next = element;
> >  }
> >
> > +/* Exchanges the positions of A and B, which may be in the same list
> > + * or different lists. */
> May need to check for list_empty() for a and b, or make it clear in
> the comment that they
> are not expected.
> > +static inline void
> > +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'.
> > @@ -236,6 +267,23 @@ 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) {
> How about change to if (!n--)?  We don't need to maintain the 'cnt'
> variable.
> > +            return ret;
> > +        }
> > +    }
> > +    OVS_NOT_REACHED();
> > +}
> > +
> >  /* Returns the number of elements in 'list'.
> >     Runs in O(n) in the number of elements. */
> >  static inline size_t
> > diff --git a/tests/library.at b/tests/library.at
> > index 9bd6d81..cb1f858 100644
> > --- a/tests/library.at
> > +++ b/tests/library.at
> > @@ -38,7 +38,7 @@ AT_CHECK([ovstest test-atomic])
> >  AT_CLEANUP
> >
> >  AT_SETUP([test linked lists])
> > -AT_CHECK([ovstest test-list], [0], [...
> > +AT_CHECK([ovstest test-list], [0], [.......
> >  ])
> >  AT_CLEANUP
> >
> > diff --git a/tests/test-list.c b/tests/test-list.c
> > index 9b6b0bd..5c16990 100644
> > --- a/tests/test-list.c
> > +++ b/tests/test-list.c
> > @@ -20,6 +20,7 @@
> >  #include <config.h>
> >  #undef NDEBUG
> >  #include "list.h"
> > +#include "sort.h"
> >  #include <assert.h>
> >  #include <string.h>
> >  #include "ovstest.h"
> > @@ -185,6 +186,107 @@ test_list_for_each_pop(void)
> >  }
> >
> >  static void
> > +test_list_swap_elem(void)
> > +{
> > +    enum { MAX_ELEMS = 100 };
> > +    struct element elements[MAX_ELEMS];
> > +    int values[MAX_ELEMS];
> > +    size_t n = MAX_ELEMS;
> > +    struct ovs_list list;
> > +
> > +    make_list(&list, elements, values, n);
> > +    elements[1].value = 50;
> > +    elements[50].value = 1;
> > +    list_swap(&elements[1].node, &elements[50].node);
> > +    elements[9].value = 10;
> > +    elements[10].value = 9;
> > +    list_swap(&elements[9].node, &elements[10].node);
> > +    elements[19].value = 20;
> > +    elements[20].value = 19;
> > +    list_swap(&elements[20].node, &elements[19].node);
> > +    list_swap(&elements[29].node, &elements[29].node);
> > +    check_list(&list, values, n);
> > +}
> > +
> > +static void
> > +test_list_at_position(void)
> > +{
> > +    enum { MAX_ELEMS = 10 };
> > +    struct element elements[MAX_ELEMS];
> > +    int values[MAX_ELEMS];
> > +    size_t n = MAX_ELEMS;
> > +    struct ovs_list list;
> > +
> > +    make_list(&list, elements, values, n);
> > +    for (n = 0; n < MAX_ELEMS; n++) {
> > +        struct ovs_list *node = list_at_position(&list, n);
> > +
> > +        ovs_assert(node == &elements[n].node);
> > +    }
> > +}
> > +
> > +static int
> > +test_list_compare(size_t a, size_t b, void *aux)
> > +{
> > +    struct ovs_list *list = aux;
> > +    struct element *elem1, *elem2;
> > +
> > +    elem1 = CONTAINER_OF(list_at_position(list, a), struct element,
> node);
> > +    elem2 = CONTAINER_OF(list_at_position(list, b), struct element,
> node);
> > +
> > +    return elem1->value - elem2->value;
> > +}
> > +
> > +static void
> > +test_list_swap(size_t a, size_t b, void *aux)
> > +{
> > +    struct ovs_list *list = aux;
> > +
> > +    list_swap(list_at_position(list, a), list_at_position(list, b));
> > +}
> > +
> > +static void
> > +test_list_sort(void)
> > +{
> > +    enum { MAX_ELEMS = 10 };
> > +    struct element elements[MAX_ELEMS];
> > +    int values[MAX_ELEMS];
> > +    size_t n = MAX_ELEMS;
> > +    struct ovs_list list;
> > +
> > +    make_list(&list, elements, values, n);
> > +    for (n = 0; n < MAX_ELEMS; n++) {
> > +        elements[n].value = MAX_ELEMS - 1 - n;
> > +    }
> > +    /* Sorts the list in ascending order of priority. */
> > +    sort(n, test_list_compare, test_list_swap, &list);
> > +    check_list(&list, values, n);
> > +}
> > +
> > +static void
> > +test_list_join(void)
> > +{
> > +    enum { MAX_ELEMS = 10 };
> > +    struct element elements_1[MAX_ELEMS];
> > +    struct element elements_2[MAX_ELEMS];
> > +    int values[2*MAX_ELEMS];
> > +    size_t n = MAX_ELEMS;
> > +    struct ovs_list list_dst, list_src;
> > +
> > +    make_list(&list_dst, elements_1, values, n);
> > +    make_list(&list_src, elements_2, values, n);
> > +    /* Makes 'elements_2' contains values {MAX_ELEMS..2*MAX_ELEMS-1}. */
> > +    for (n = MAX_ELEMS; n < 2*MAX_ELEMS; n++) {
> > +        elements_2[n-MAX_ELEMS].value += MAX_ELEMS;
> > +        values[n] = n;
> > +    }
> > +
> > +    list_join(&list_dst, &list_src);
> > +    assert(list_is_empty(&list_src));
> > +    check_list(&list_dst, values, 2*MAX_ELEMS);
> > +}
> > +
> > +static void
> >  run_test(void (*function)(void))
> >  {
> >      function();
> > @@ -197,6 +299,10 @@ test_list_main(int argc OVS_UNUSED, char *argv[]
> OVS_UNUSED)
> >      run_test(test_list_construction);
> >      run_test(test_list_for_each_safe);
> >      run_test(test_list_for_each_pop);
> > +    run_test(test_list_swap_elem);
> > +    run_test(test_list_at_position);
> > +    run_test(test_list_sort);
> > +    run_test(test_list_join);
> >      printf("\n");
> >  }
> >
> > --
> > 1.7.9.5
> >
> > _______________________________________________
> > dev mailing list
> > dev@openvswitch.org
> > http://openvswitch.org/mailman/listinfo/dev
>
_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to