diff -r 4e6e812c1d97 -r 069c152f6272 src/server/ucx/dlist.c --- a/src/server/ucx/dlist.c Thu Jun 20 14:07:46 2013 +0200 +++ b/src/server/ucx/dlist.c Fri Jun 21 12:10:44 2013 +0200 @@ -1,3 +1,31 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013 Olaf Wintermann. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + #include "dlist.h" UcxDlist *ucx_dlist_clone(UcxDlist *l, copy_func fnc, void *data) { @@ -13,7 +41,8 @@ return ret; } -int ucx_dlist_equals(UcxDlist *l1, UcxDlist *l2, cmp_func fnc, void* data) { +int ucx_dlist_equals(const UcxDlist *l1, const UcxDlist *l2, + cmp_func fnc, void* data) { if (l1 == l2) return 1; while (l1 != NULL && l2 != NULL) { @@ -77,32 +106,41 @@ } } -UcxDlist *ucx_dlist_last(UcxDlist *l) { +UcxDlist *ucx_dlist_last(const UcxDlist *l) { if (l == NULL) return NULL; - UcxDlist *e = l; + const UcxDlist *e = l; while (e->next != NULL) { e = e->next; } - return e; + return (UcxDlist*)e; } -UcxDlist *ucx_dlist_get(UcxDlist *l, int index) { +UcxDlist *ucx_dlist_get(const UcxDlist *l, int index) { if (l == NULL) return NULL; - UcxDlist *e = l; + const UcxDlist *e = l; while (e->next != NULL && index > 0) { e = e->next; index--; } - return index == 0 ? e : NULL; + return (UcxDlist*)(index == 0 ? e : NULL); } -size_t ucx_dlist_size(UcxDlist *l) { +int ucx_dlist_contains(UcxDlist *l, void *elem, cmp_func fnc, void *cmpdata) { + UCX_FOREACH(UcxDlist*, l, e) { + if (!fnc(elem, e->data, cmpdata)) { + return 1; + } + } + return 0; +} + +size_t ucx_dlist_size(const UcxDlist *l) { if (l == NULL) return 0; - UcxDlist *e = l; + const UcxDlist *e = l; size_t s = 1; while (e->next != NULL) { e = e->next; @@ -113,14 +151,15 @@ } UcxDlist *ucx_dlist_sort_merge(int length, - UcxDlist* ls, UcxDlist* rs, UcxDlist* le, UcxDlist* re, + UcxDlist* restrict ls, UcxDlist* restrict le, UcxDlist* restrict re, cmp_func fnc, void* data) { - UcxDlist *sorted[length]; + + UcxDlist** sorted = (UcxDlist**) malloc(sizeof(UcxDlist*)*length); UcxDlist *rc, *lc; - lc = ls; rc = rs; + lc = ls; rc = le; int n = 0; - while (lc != le && rc != re) { + while (lc && lc != le && rc != re) { if (fnc(lc->data, rc->data, data) <= 0) { sorted[n] = lc; lc = lc->next; @@ -130,12 +169,12 @@ } n++; } - while (lc != le) { + while (lc && lc != le) { sorted[n] = lc; lc = lc->next; n++; } - while (rc != re) { + while (rc && rc != re) { sorted[n] = rc; rc = rc->next; n++; @@ -149,7 +188,9 @@ } sorted[length-1]->next = NULL; - return sorted[0]; + UcxDlist *ret = sorted[0]; + free(sorted); + return ret; } UcxDlist *ucx_dlist_sort(UcxDlist *l, cmp_func fnc, void *data) { @@ -160,7 +201,7 @@ UcxDlist *lc; int ln = 1; - UcxDlist *ls = l, *le; + UcxDlist *restrict ls = l, *restrict le, *restrict re; lc = ls; while (lc->next != NULL && fnc(lc->next->data, lc->data, data) > 0) { lc = lc->next; @@ -168,13 +209,12 @@ } le = lc->next; - UcxDlist *rs = le, *re; - if (rs == NULL) { + if (le == NULL) { return l; // this list is already sorted :) } else { UcxDlist *rc; int rn = 1; - rc = rs; + rc = le; while (rc->next != NULL && fnc(rc->next->data, rc->data, data) > 0) { rc = rc->next; rn++; @@ -190,27 +230,26 @@ // {ls,...,le->prev} and {rs,...,re->prev} are sorted - merge them UcxDlist *sorted = ucx_dlist_sort_merge(ln+rn, - ls, rs, le, re, + ls, le, re, fnc, data); // merge sorted list with (also sorted) remainder l = ucx_dlist_sort_merge(ln+rn+remainder_length, - sorted, remainder, NULL, NULL, - fnc, data); + sorted, remainder, NULL, fnc, data); return l; } } /* dlist specific functions */ -UcxDlist *ucx_dlist_first(UcxDlist *l) { +UcxDlist *ucx_dlist_first(const UcxDlist *l) { if (l == NULL) return NULL; - UcxDlist *e = l; + const UcxDlist *e = l; while (e->prev != NULL) { e = e->prev; } - return e; + return (UcxDlist *)e; } UcxDlist *ucx_dlist_remove(UcxDlist *l, UcxDlist *e) {