src/server/ucx/dlist.c

changeset 71
069c152f6272
parent 36
450d2d5f4735
--- 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) {

mercurial