forked from github/server
quicklists can be used as a set of pointers (this will be useful).
This commit is contained in:
parent
372908a9af
commit
a538c52bc4
3 changed files with 65 additions and 4 deletions
|
@ -29,7 +29,7 @@ struct quicklist {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
void * ql_get(quicklist * ql, int index) {
|
void * ql_get(const quicklist * ql, int index) {
|
||||||
return (ql && index<ql->num_elements)?ql->elements[index]:ql_get(ql->next, index-ql->num_elements);
|
return (ql && index<ql->num_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;
|
qlp = &(*qlp)->next;
|
||||||
}
|
}
|
||||||
if (!*qlp) {
|
if (!*qlp) {
|
||||||
ql = malloc(sizeof(quicklist));
|
ql = (quicklist *)malloc(sizeof(quicklist));
|
||||||
ql->num_elements = 0;
|
ql->num_elements = 0;
|
||||||
ql->next = 0;
|
ql->next = 0;
|
||||||
*qlp = ql;
|
*qlp = ql;
|
||||||
|
@ -94,7 +94,7 @@ int ql_insert(quicklist ** qlp, int index, void * data) {
|
||||||
ql->elements[index]=data;
|
ql->elements[index]=data;
|
||||||
++ql->num_elements;
|
++ql->num_elements;
|
||||||
} else {
|
} else {
|
||||||
quicklist * qn = malloc(sizeof(quicklist));
|
quicklist * qn = (quicklist *)malloc(sizeof(quicklist));
|
||||||
qn->next = ql->next;
|
qn->next = ql->next;
|
||||||
ql->next = qn;
|
ql->next = qn;
|
||||||
qn->num_elements = QL_LIMIT;
|
qn->num_elements = QL_LIMIT;
|
||||||
|
@ -145,3 +145,32 @@ void ql_free(struct quicklist * ql)
|
||||||
if (ql->next) ql_free(ql->next);
|
if (ql->next) ql_free(ql->next);
|
||||||
free(ql);
|
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;
|
||||||
|
}
|
|
@ -23,7 +23,7 @@ extern "C" {
|
||||||
|
|
||||||
/* see http://en.wikipedia.org/wiki/Unrolled_linked_list */
|
/* see http://en.wikipedia.org/wiki/Unrolled_linked_list */
|
||||||
typedef struct quicklist quicklist;
|
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);
|
int ql_length(const struct quicklist * ql);
|
||||||
void ql_push(struct quicklist ** qlp, void * data);
|
void ql_push(struct quicklist ** qlp, void * data);
|
||||||
int ql_delete(struct quicklist ** qlp, int index);
|
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 *));
|
void ql_foreach(struct quicklist * ql, void (*cb)(void *));
|
||||||
int ql_advance(struct quicklist ** iterator, int * index, int stride);
|
int ql_advance(struct quicklist ** iterator, int * index, int stride);
|
||||||
void ql_free(struct quicklist * ql);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -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) {
|
static void test_advance(CuTest * tc) {
|
||||||
struct quicklist * ql = NULL, *qli;
|
struct quicklist * ql = NULL, *qli;
|
||||||
int i, n = 31;
|
int i, n = 31;
|
||||||
|
@ -84,8 +111,10 @@ CuSuite* get_quicklist_suite(void)
|
||||||
SUITE_ADD_TEST(suite, test_advance);
|
SUITE_ADD_TEST(suite, test_advance);
|
||||||
SUITE_ADD_TEST(suite, test_push);
|
SUITE_ADD_TEST(suite, test_push);
|
||||||
SUITE_ADD_TEST(suite, test_insert);
|
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_insert_many);
|
||||||
SUITE_ADD_TEST(suite, test_delete_rand);
|
SUITE_ADD_TEST(suite, test_delete_rand);
|
||||||
SUITE_ADD_TEST(suite, test_delete_edgecases);
|
SUITE_ADD_TEST(suite, test_delete_edgecases);
|
||||||
|
SUITE_ADD_TEST(suite, test_set_insert);
|
||||||
return suite;
|
return suite;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue