universe@4: #include "dlist.h" universe@4: universe@18: UcxDlist *ucx_dlist_clone(UcxDlist *l, copy_func fnc, void *data) { universe@18: UcxDlist *ret = NULL; universe@18: while (l != NULL) { universe@18: if (fnc != NULL) { universe@18: ret = ucx_dlist_append(ret, fnc(l->data, data)); universe@18: } else { universe@18: ret = ucx_dlist_append(ret, l->data); universe@18: } universe@18: l = l->next; universe@18: } universe@18: return ret; universe@18: } universe@18: universe@18: int ucx_dlist_equals(UcxDlist *l1, UcxDlist *l2, cmp_func fnc, void* data) { universe@18: if (l1 == l2) return 1; universe@18: universe@18: while (l1 != NULL && l2 != NULL) { universe@18: if (fnc == NULL) { universe@18: if (l1->data != l2->data) return 0; universe@18: } else { universe@18: if (fnc(l1->data, l2->data, data) != 0) return 0; universe@18: } universe@18: l1 = l1->next; universe@18: l2 = l2->next; universe@18: } universe@18: universe@18: return (l1 == NULL && l2 == NULL); universe@18: } universe@18: universe@8: void ucx_dlist_free(UcxDlist *l) { universe@8: UcxDlist *e = l, *f; universe@8: while (e != NULL) { universe@8: f = e; universe@8: e = e->next; universe@8: free(f); universe@8: } universe@8: } universe@8: universe@7: UcxDlist *ucx_dlist_append(UcxDlist *l, void *data) { universe@8: UcxDlist *nl = (UcxDlist*) malloc(sizeof(UcxDlist)); universe@8: if (nl == NULL) return NULL; universe@7: universe@8: nl->data = data; universe@8: nl->next = NULL; universe@8: if (l == NULL) { universe@22: nl->prev = NULL; universe@8: return nl; universe@8: } else { universe@8: UcxDlist *t = ucx_dlist_last(l); universe@8: t->next = nl; universe@8: nl->prev = t; universe@8: return l; universe@8: } universe@7: } universe@7: universe@7: UcxDlist *ucx_dlist_prepend(UcxDlist *l, void *data) { universe@8: UcxDlist *nl = ucx_dlist_append(NULL, data); universe@8: if (nl == NULL) return NULL; universe@7: universe@8: if (l != NULL) { universe@8: nl->next = l; universe@8: l->prev = nl; universe@8: } universe@8: return nl; universe@7: } universe@7: universe@7: UcxDlist *ucx_dlist_concat(UcxDlist *l1, UcxDlist *l2) { universe@8: if (l1 == NULL) { universe@8: return l2; universe@8: } else { universe@8: UcxDlist *last = ucx_dlist_last(l1); universe@8: last->next = l2; universe@8: l2->prev = last; universe@8: return l1; universe@8: } universe@7: } universe@7: universe@7: UcxDlist *ucx_dlist_last(UcxDlist *l) { universe@7: if (l == NULL) return NULL; universe@7: universe@7: UcxDlist *e = l; universe@7: while (e->next != NULL) { universe@7: e = e->next; universe@7: } universe@7: return e; universe@7: } universe@7: universe@7: UcxDlist *ucx_dlist_get(UcxDlist *l, int index) { universe@8: if (l == NULL) return NULL; universe@8: universe@8: UcxDlist *e = l; universe@8: while (e->next != NULL && index > 0) { universe@8: e = e->next; universe@8: index--; universe@8: } universe@7: universe@8: return index == 0 ? e : NULL; universe@7: } universe@7: universe@7: size_t ucx_dlist_size(UcxDlist *l) { universe@7: if (l == NULL) return 0; universe@7: universe@7: UcxDlist *e = l; universe@7: size_t s = 1; universe@7: while (e->next != NULL) { universe@7: e = e->next; universe@7: s++; universe@7: } universe@7: universe@7: return s; universe@7: } universe@7: universe@35: int ucx_dlist_qsort_devide(UcxDlist** list, int l, int r, cmp_func f, void* d) { universe@35: int i = l; universe@35: int j = r - 1; universe@35: void *p = list[r]->data; universe@35: UcxDlist *b; universe@35: universe@35: do { universe@35: while (i < r && f(list[i]->data, p, d) <= 0) i++; universe@35: while (j > l && f(list[j]->data, p, d) >= 0) j--; universe@35: if (i < j) { universe@35: b = list[i]; universe@35: list[i] = list[j]; universe@35: list[j] = b; universe@35: } universe@35: } while (i < j); universe@35: universe@35: if (f(list[i]->data, p, d) > 0) { universe@35: b = list[r]; universe@35: list[r] = list[i]; universe@35: list[i] = b; universe@35: } universe@35: universe@35: return i; universe@35: } universe@35: universe@35: void ucx_dlist_qsort_sort(UcxDlist** list, int l, int r, cmp_func f, void* d) { universe@35: if (l < r) { universe@35: int m = ucx_dlist_qsort_devide(list, l, r, f, d); universe@35: ucx_dlist_qsort_sort(list, l, m-1, f, d); universe@35: ucx_dlist_qsort_sort(list, m+1, r, f, d); universe@35: } universe@35: } universe@35: universe@35: UcxDlist *ucx_dlist_qsort(UcxDlist *l, cmp_func fnc, void *data) { universe@35: if (l == NULL) { universe@35: return NULL; universe@35: } universe@35: size_t n = ucx_dlist_size(l); universe@35: if (n == 1) { universe@35: return l; universe@35: } universe@35: universe@35: UcxDlist *entries[n]; universe@35: entries[0] = l; universe@35: for (int i = 1 ; i < n ; i++) { universe@35: entries[i] = entries[i-1]->next; universe@35: } universe@35: universe@35: ucx_dlist_qsort_sort(entries, 0, n-1, fnc, data); universe@35: universe@35: entries[0]->prev = NULL; universe@35: for (int i = 0 ; i < n-1 ; i++) { universe@35: entries[i]->next = entries[i+1]; universe@35: entries[i+1]->prev = entries[i]; universe@35: } universe@35: entries[n-1]->next = NULL; universe@35: universe@35: return entries[0]; universe@35: } universe@35: universe@7: /* dlist specific functions */ universe@7: UcxDlist *ucx_dlist_first(UcxDlist *l) { universe@8: if (l == NULL) return NULL; universe@7: universe@8: UcxDlist *e = l; universe@8: while (e->prev != NULL) { universe@8: e = e->prev; universe@8: } universe@8: return e; olaf@13: } universe@22: universe@22: UcxDlist *ucx_dlist_remove(UcxDlist *l, UcxDlist *e) { universe@22: if (e->prev == NULL) { olaf@31: if(e->next != NULL) { olaf@31: e->next->prev = NULL; olaf@31: l = e->next; olaf@31: } else { olaf@31: l = NULL; olaf@31: } olaf@31: universe@22: } else { universe@22: e->prev->next = e->next; universe@22: e->next->prev = e->prev; universe@22: } universe@22: free(e); universe@22: return l; universe@22: }