From a538c52bc4f12a9719915856d838f71631d7cac3 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Thu, 24 Feb 2011 22:27:04 -0800 Subject: [PATCH] quicklists can be used as a set of pointers (this will be useful). --- src/util/quicklist.c | 35 ++++++++++++++++++++++++++++++++--- src/util/quicklist.h | 5 ++++- src/util/quicklist_test.c | 29 +++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 4 deletions(-) diff --git a/src/util/quicklist.c b/src/util/quicklist.c index db06108c0..f5b0bc8bd 100644 --- a/src/util/quicklist.c +++ b/src/util/quicklist.c @@ -29,7 +29,7 @@ struct quicklist { }; -void * ql_get(quicklist * ql, int index) { +void * ql_get(const quicklist * ql, int index) { return (ql && indexnum_elements)?ql->elements[index]:ql_get(ql->next, index-ql->num_elements); } @@ -43,7 +43,7 @@ void ql_push(quicklist ** qlp, void * data) { qlp = &(*qlp)->next; } if (!*qlp) { - ql = malloc(sizeof(quicklist)); + ql = (quicklist *)malloc(sizeof(quicklist)); ql->num_elements = 0; ql->next = 0; *qlp = ql; @@ -94,7 +94,7 @@ int ql_insert(quicklist ** qlp, int index, void * data) { ql->elements[index]=data; ++ql->num_elements; } else { - quicklist * qn = malloc(sizeof(quicklist)); + quicklist * qn = (quicklist *)malloc(sizeof(quicklist)); qn->next = ql->next; ql->next = qn; qn->num_elements = QL_LIMIT; @@ -145,3 +145,32 @@ void ql_free(struct quicklist * ql) if (ql->next) ql_free(ql->next); free(ql); } + +int ql_set_insert(struct quicklist ** qlp, void * data) +{ + if (*qlp) { + quicklist * ql = *qlp; + if (ql->num_elements>0 && ql->elements[ql->num_elements-1] < data) { + if (ql->num_elements==QL_MAXSIZE || (ql->next && ql->next->elements[0]<=data)) { + return ql_set_insert(&ql->next, data); + } else { + ql->elements[ql->num_elements++] = data; + } + return 0; + } else { + int i; + /* TODO: OPT | binary search */ + for (i=0;i!=ql->num_elements;++i) { + if (data < ql->elements[i]) { + ql_insert(qlp, i, data); + return 0; + } + if (data == ql->elements[i]) { + return 1; + } + } + } + } + ql_push(qlp, data); + return 0; +} \ No newline at end of file diff --git a/src/util/quicklist.h b/src/util/quicklist.h index 89fc95cf7..cc7186a31 100644 --- a/src/util/quicklist.h +++ b/src/util/quicklist.h @@ -23,7 +23,7 @@ extern "C" { /* see http://en.wikipedia.org/wiki/Unrolled_linked_list */ typedef struct quicklist quicklist; -void * ql_get(struct quicklist * ql, int index); +void * ql_get(const struct quicklist * ql, int index); int ql_length(const struct quicklist * ql); void ql_push(struct quicklist ** qlp, void * data); int ql_delete(struct quicklist ** qlp, int index); @@ -31,6 +31,9 @@ int ql_insert(struct quicklist ** qlp, int index, void * data); void ql_foreach(struct quicklist * ql, void (*cb)(void *)); int ql_advance(struct quicklist ** iterator, int * index, int stride); void ql_free(struct quicklist * ql); + +/* you can use it as a set (sorted pointers)*/ +int ql_set_insert(struct quicklist ** qlp, void * data); #ifdef __cplusplus } #endif diff --git a/src/util/quicklist_test.c b/src/util/quicklist_test.c index 5125a9b37..bb82afa12 100644 --- a/src/util/quicklist_test.c +++ b/src/util/quicklist_test.c @@ -17,6 +17,33 @@ static void test_insert(CuTest * tc) { } } +static void test_insert_delete_gives_null(CuTest * tc) { + struct quicklist * ql = NULL; + ql_push(&ql, (void*)42); + ql_delete(&ql, 0); + CuAssertPtrEquals(tc, 0, ql); +} + +static void test_set_insert(CuTest * tc) { + struct quicklist * ql = NULL; + int a; + a = ql_set_insert(&ql, (void*)42); + CuAssertIntEquals(tc, 1, ql_length(ql)); + CuAssertIntEquals(tc, 0, a); + a = ql_set_insert(&ql, (void*)43); + CuAssertIntEquals(tc, 2, ql_length(ql)); + CuAssertIntEquals(tc, 0, a); + a = ql_set_insert(&ql, (void*)42); + CuAssertIntEquals(tc, 2, ql_length(ql)); + CuAssertIntEquals(tc, 1, a); + a = ql_set_insert(&ql, (void*)41); + CuAssertIntEquals(tc, 0, a); + CuAssertIntEquals(tc, 3, ql_length(ql)); + CuAssertIntEquals(tc, 41, (int)ql_get(ql, 0)); + CuAssertIntEquals(tc, 42, (int)ql_get(ql, 1)); + CuAssertIntEquals(tc, 43, (int)ql_get(ql, 2)); +} + static void test_advance(CuTest * tc) { struct quicklist * ql = NULL, *qli; int i, n = 31; @@ -84,8 +111,10 @@ CuSuite* get_quicklist_suite(void) SUITE_ADD_TEST(suite, test_advance); SUITE_ADD_TEST(suite, test_push); SUITE_ADD_TEST(suite, test_insert); + SUITE_ADD_TEST(suite, test_insert_delete_gives_null); SUITE_ADD_TEST(suite, test_insert_many); SUITE_ADD_TEST(suite, test_delete_rand); SUITE_ADD_TEST(suite, test_delete_edgecases); + SUITE_ADD_TEST(suite, test_set_insert); return suite; }