From c38089c8246d25f64557de6cf2542b48f91ace4c Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Sun, 23 Feb 2020 13:34:38 -0500 Subject: Add swap to double ended queue --- collections/double_ended_queue.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'collections/double_ended_queue.c') diff --git a/collections/double_ended_queue.c b/collections/double_ended_queue.c index ee93196..6a3a810 100644 --- a/collections/double_ended_queue.c +++ b/collections/double_ended_queue.c @@ -159,3 +159,25 @@ deq *root; copy->beg = copy->base; copy->end = copy->base + deq_size(root); } + +void deq_swap(root, i, j) +deq *root; +int i, j; +{ + int len; + void *tmp; + + if (!root) { + return; + } + + len = deq_size(root); + + if (i >= len || j >= len) { + return; + } + + tmp = root->end[i]; + root->end[j] = root->end[i]; + root->end[i] = tmp; +} -- cgit v1.1 From 995f7838c0d47b3f4974e8bf501daf1d1f5e247f Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Sun, 23 Feb 2020 14:09:26 -0500 Subject: Add truncate function for double ended queue --- collections/double_ended_queue.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'collections/double_ended_queue.c') diff --git a/collections/double_ended_queue.c b/collections/double_ended_queue.c index 6a3a810..1f18330 100644 --- a/collections/double_ended_queue.c +++ b/collections/double_ended_queue.c @@ -181,3 +181,14 @@ int i, j; root->end[j] = root->end[i]; root->end[i] = tmp; } + +void deq_truncate(root, size) +deq *root; +int size; +{ + if ((!root) || size > deq_size(root)) { + return; + } + + root->end = root->beg + size; +} -- cgit v1.1 From 25395399f6a2822042a445fd6c812566d36dc3f9 Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Sun, 23 Feb 2020 14:21:16 -0500 Subject: Add front/back access functions for double ended queue --- collections/double_ended_queue.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'collections/double_ended_queue.c') diff --git a/collections/double_ended_queue.c b/collections/double_ended_queue.c index 1f18330..ac9c131 100644 --- a/collections/double_ended_queue.c +++ b/collections/double_ended_queue.c @@ -192,3 +192,23 @@ int size; root->end = root->beg + size; } + +void* deq_front(root) +deq *root; +{ + if (!root) { + return; + } + + return *root->beg; +} + +void* deq_back(root) +deq *root; +{ + if (!root) { + return; + } + + return *root->end; +} -- cgit v1.1 From 7b4a46a736f47222937ba875c162591d50b08d72 Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Mon, 25 May 2020 00:01:22 -0400 Subject: Fix typo in struct name. --- collections/double_ended_queue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'collections/double_ended_queue.c') diff --git a/collections/double_ended_queue.c b/collections/double_ended_queue.c index ac9c131..dac22b6 100644 --- a/collections/double_ended_queue.c +++ b/collections/double_ended_queue.c @@ -7,7 +7,7 @@ #define START_SIZE 64; -struct double_ended_queeu { +struct double_ended_queue { void **base, **end, **beg; int i, limit; }; -- cgit v1.1 From 8860413709853bf1daede5e2c95d502791952b7b Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Mon, 25 May 2020 00:45:51 -0400 Subject: Add push front for double ended queue. --- collections/double_ended_queue.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'collections/double_ended_queue.c') diff --git a/collections/double_ended_queue.c b/collections/double_ended_queue.c index dac22b6..967a716 100644 --- a/collections/double_ended_queue.c +++ b/collections/double_ended_queue.c @@ -88,6 +88,20 @@ void *item; *(root->end++) = item; } +void deq_push_front(root, item) +deq *root; +void *item; +{ + if (!root) { + return; + } + if (root->end == root->base + root->limit) { + deq_resize(root); + } + + *(root->end++) = item; +} + void* deq_pop_front(root) deq *root; { -- cgit v1.1 From 56f138f1de82d4bf7e21282f115fbcb63a6fe4d4 Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Mon, 25 May 2020 00:47:06 -0400 Subject: Fix index function for double ended queue. Double ended queue's did not account for pushing in-front of the base i.e. a truly circular buffer, this is the start to fixing that across all functions. --- collections/double_ended_queue.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'collections/double_ended_queue.c') diff --git a/collections/double_ended_queue.c b/collections/double_ended_queue.c index 967a716..88d4641 100644 --- a/collections/double_ended_queue.c +++ b/collections/double_ended_queue.c @@ -117,11 +117,18 @@ void* deq_index(root, index) deq *root; int index; { - if (!root || root->beg + index >= root->end) { + void *tmp; + + if (!root) { + return NULL; + } + + tmp = root->base + (root->beg + index - root->base) % root->limit); + if (tmp > root->end) { return NULL; } - return root->beg[index]; + return *tmp; } void* deq_pop_back(root) -- cgit v1.1 From 6eb63be564e5d99e9ead3c10e98ab684363428f2 Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Mon, 25 May 2020 01:02:43 -0400 Subject: Fix double ended queue size. --- collections/double_ended_queue.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'collections/double_ended_queue.c') diff --git a/collections/double_ended_queue.c b/collections/double_ended_queue.c index 88d4641..a49b018 100644 --- a/collections/double_ended_queue.c +++ b/collections/double_ended_queue.c @@ -9,7 +9,7 @@ struct double_ended_queue { void **base, **end, **beg; - int i, limit; + int limit; }; deq* deq_new() @@ -47,7 +47,12 @@ deq *root; if (!root) { return -1; } - return (root->end - root->beg); + + if (root->beg <= root->end) { + return (root->end - root->beg); + } + + return (root->base + root->limit - root->beg) + (root->end - root->base); } void deq_resize(root) -- cgit v1.1 From 68b53a55f308d02be02130ef32038b6d707a6b55 Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Mon, 25 May 2020 01:22:01 -0400 Subject: Fix double ended queue push back. --- collections/double_ended_queue.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'collections/double_ended_queue.c') diff --git a/collections/double_ended_queue.c b/collections/double_ended_queue.c index a49b018..81bee47 100644 --- a/collections/double_ended_queue.c +++ b/collections/double_ended_queue.c @@ -7,6 +7,10 @@ #define START_SIZE 64; +/*TODO add returned error codes for current void functions + * (resize, push, etc.) + */ + struct double_ended_queue { void **base, **end, **beg; int limit; @@ -86,11 +90,14 @@ void *item; if (!root) { return; } - if (root->end == root->base + root->limit) { + + tmp = (root->base + (root->end - root->base) % root->limit); + if (tmp == root->beg) { deq_resize(root); + tmp = (root->base + (root->end - root->base) % root->limit); } - *(root->end++) = item; + *(root->end = tmp) = item; } void deq_push_front(root, item) -- cgit v1.1 From c3f2eed02152d5902fa26a625d11207e64301849 Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Tue, 26 May 2020 01:19:31 -0400 Subject: Fix push front for double ended queue. Was only a copy of push back. --- collections/double_ended_queue.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'collections/double_ended_queue.c') diff --git a/collections/double_ended_queue.c b/collections/double_ended_queue.c index 81bee47..8a6a91e 100644 --- a/collections/double_ended_queue.c +++ b/collections/double_ended_queue.c @@ -104,14 +104,19 @@ void deq_push_front(root, item) deq *root; void *item; { + void *tmp; + if (!root) { return; } - if (root->end == root->base + root->limit) { + + tmp = (root->base + ((root->beg - 1) - root->base) % root->limit); + if (tmp == root->beg) { deq_resize(root); + tmp = (root->base + ((root->beg - 1) - root->base) % root->limit); } - *(root->end++) = item; + *(root->beg = tmp) = item; } void* deq_pop_front(root) -- cgit v1.1 From ee17ff1921ea790125d0c4b804f3c78a1f4c0a34 Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Wed, 27 May 2020 03:32:07 -0400 Subject: Fix double ended queue pop front w/ wrap around. --- collections/double_ended_queue.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'collections/double_ended_queue.c') diff --git a/collections/double_ended_queue.c b/collections/double_ended_queue.c index 8a6a91e..285983b 100644 --- a/collections/double_ended_queue.c +++ b/collections/double_ended_queue.c @@ -127,7 +127,10 @@ deq *root; return NULL; } - return tmp = *(root->beg++); + tmp = *(root->beg++); + root->beg = (root->base + (root->beg - root->base) % root->limit); + + return tmp; } void* deq_index(root, index) -- cgit v1.1 From 0b8aa4ce92c042eabb3ebed94674aa6dc099a23c Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Wed, 27 May 2020 03:34:37 -0400 Subject: Fix move index function for double ended queue. --- collections/double_ended_queue.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'collections/double_ended_queue.c') diff --git a/collections/double_ended_queue.c b/collections/double_ended_queue.c index 285983b..25167e3 100644 --- a/collections/double_ended_queue.c +++ b/collections/double_ended_queue.c @@ -83,6 +83,24 @@ deq *root; } } +void* deq_index(root, index) +deq *root; +int index; +{ + void *tmp; + + if (!root) { + return NULL; + } + + tmp = root->base + (root->beg + index - root->base) % root->limit); + if (tmp > root->end) { + return NULL; + } + + return *tmp; +} + void deq_push_back(root, item) deq *root; void *item; @@ -133,24 +151,6 @@ deq *root; return tmp; } -void* deq_index(root, index) -deq *root; -int index; -{ - void *tmp; - - if (!root) { - return NULL; - } - - tmp = root->base + (root->beg + index - root->base) % root->limit); - if (tmp > root->end) { - return NULL; - } - - return *tmp; -} - void* deq_pop_back(root) deq *root; { -- cgit v1.1 From df2e0f59747d55ffd6fd47468d098aab1e9abfbe Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Wed, 27 May 2020 03:39:03 -0400 Subject: Fix double ended queue pop back w/ wrap around. --- collections/double_ended_queue.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'collections/double_ended_queue.c') diff --git a/collections/double_ended_queue.c b/collections/double_ended_queue.c index 25167e3..31ede5f 100644 --- a/collections/double_ended_queue.c +++ b/collections/double_ended_queue.c @@ -159,7 +159,10 @@ deq *root; return NULL; } - return tmp = *(--root->end); + tmp = *(root->end--); + root->end = (root->base + (root->end - root->base) % root->limit); + + return tmp; } void deq_free(root) -- cgit v1.1 From a89e4d56a242073982ca3620a00c6e04bf5e82d8 Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Wed, 27 May 2020 04:05:57 -0400 Subject: Fix trivial compiler errors. --- collections/double_ended_queue.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'collections/double_ended_queue.c') diff --git a/collections/double_ended_queue.c b/collections/double_ended_queue.c index 31ede5f..fab92c7 100644 --- a/collections/double_ended_queue.c +++ b/collections/double_ended_queue.c @@ -87,13 +87,13 @@ void* deq_index(root, index) deq *root; int index; { - void *tmp; + void **tmp; if (!root) { return NULL; } - tmp = root->base + (root->beg + index - root->base) % root->limit); + tmp = root->base + ((root->beg + index - root->base) % root->limit); if (tmp > root->end) { return NULL; } @@ -105,6 +105,8 @@ void deq_push_back(root, item) deq *root; void *item; { + void **tmp; + if (!root) { return; } @@ -122,7 +124,7 @@ void deq_push_front(root, item) deq *root; void *item; { - void *tmp; + void **tmp; if (!root) { return; @@ -241,7 +243,7 @@ void* deq_front(root) deq *root; { if (!root) { - return; + return NULL; } return *root->beg; @@ -251,7 +253,7 @@ void* deq_back(root) deq *root; { if (!root) { - return; + return NULL; } return *root->end; -- cgit v1.1 From 533d7755f866257c78299561b2634a3ea54f9a87 Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Wed, 27 May 2020 04:26:00 -0400 Subject: Add print function for double ended queue. Moves original print to debug_print. --- collections/double_ended_queue.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'collections/double_ended_queue.c') diff --git a/collections/double_ended_queue.c b/collections/double_ended_queue.c index fab92c7..29c8873 100644 --- a/collections/double_ended_queue.c +++ b/collections/double_ended_queue.c @@ -178,7 +178,22 @@ deq *root; free(root); } -void deq_print(root) +void deq_print(root, to_string) +deq *root; +char* to_string(void*); +{ + int i, size;; + + size = deq_size(root); + + printf("["); + for (i = 0; i < size; i++) { + printf("%s,", to_string(deq_index(root, i))); + } + printf("\b]\n"); +} + +void deq_debug_print(root) deq *root; { void **tmp; -- cgit v1.1 From 735a88c02286a01c2a4edb8f7f6ccf0a93de24b0 Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Wed, 27 May 2020 04:39:59 -0400 Subject: Add brief description of double ended queue struct. --- collections/double_ended_queue.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'collections/double_ended_queue.c') diff --git a/collections/double_ended_queue.c b/collections/double_ended_queue.c index 29c8873..25f3181 100644 --- a/collections/double_ended_queue.c +++ b/collections/double_ended_queue.c @@ -11,6 +11,17 @@ * (resize, push, etc.) */ +/*TODO + * Fix empty vs totally full ambiquity + */ + +/* Double ended queue as a circular buffer + * base is pointer to buffer. + * beg is where the first element is stored. + * end is where the last element is stored. + * limit is the maximum number of elements. + */ + struct double_ended_queue { void **base, **end, **beg; int limit; -- cgit v1.1 From dbb5ba792719088f99b58a954a53b1cdab213f0c Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Wed, 27 May 2020 04:41:40 -0400 Subject: Fix resize implementation (double ended queue). Needed to take into account circular buffer i.e. handle a split buffer (base<->end & beg<->limit) along with regular (beg<->end). --- collections/double_ended_queue.c | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) (limited to 'collections/double_ended_queue.c') diff --git a/collections/double_ended_queue.c b/collections/double_ended_queue.c index 25f3181..b555e3a 100644 --- a/collections/double_ended_queue.c +++ b/collections/double_ended_queue.c @@ -73,25 +73,32 @@ deq *root; void deq_resize(root) deq *root; { - if (root->beg != root->base) { - memmove(root->base, root->beg, root->end - root->beg); - root->end = root->base + deq_size(root); - root->beg = root->base; - } else { - root->base = malloc(root->limit * 2 * sizeof(void*)); - assert(root->base); + void **tmp; + int size; + tmp = malloc(root->limit * 2 * sizeof(void*)); + assert(root->base); - root->base = memcpy(root->base, root->beg, root->limit * sizeof(void*)); - assert(root->base); + if (root->beg > root->end) { + /*copy beg<->limit*/ + size = (root->base + (root->limit*sizeof(void*)) - root->beg); + tmp = memcpy(tmp, root->beg, size * sizeof(void*); + assert(tmp); + /*copy base<->end*/ + tmp = memcpy(tmp + size, root->beg, + (root->end - root->base)* sizeof(void*)); + assert(tmp); + } else { + size = deq_size(root); + tmp = memcpy(tmp, root->beg, size*sizeof(void*)); + } - root->end = root->base + deq_size(root); - root->limit = root->limit * 2; + root->limit *= 2; - free(root->beg); - root->beg = root->base; - } + free(root->base); + root->base = root->beg = tmp; + root->end = root->base + size; } void* deq_index(root, index) -- cgit v1.1 From 4e4704b0251bb2b03d0fa573437b77b15567441c Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Fri, 29 May 2020 17:15:53 -0400 Subject: Fix change beg, end to indices. These are now indices of the buffer rather than pointers into buffer, as this is simpler to maintain and extend. end is also changed to point to next location for storage rather than the last element. --- collections/double_ended_queue.c | 154 ++++++++++++++++++++------------------- 1 file changed, 78 insertions(+), 76 deletions(-) (limited to 'collections/double_ended_queue.c') diff --git a/collections/double_ended_queue.c b/collections/double_ended_queue.c index b555e3a..956e362 100644 --- a/collections/double_ended_queue.c +++ b/collections/double_ended_queue.c @@ -17,14 +17,14 @@ /* Double ended queue as a circular buffer * base is pointer to buffer. - * beg is where the first element is stored. - * end is where the last element is stored. - * limit is the maximum number of elements. + * beg: postiton of the first element is stored. + * end: position for the next element to be stored. + * limit: the maximum number of elements. */ struct double_ended_queue { - void **base, **end, **beg; - int limit; + void **base; + int beg, end, limit; }; deq* deq_new() @@ -35,7 +35,8 @@ deq* deq_new() assert(root); root->limit = START_SIZE; - root->base = root->end = root->beg = malloc(root->limit * sizeof(void*)); + root->beg = root->end = 0; + root->base = malloc(root->limit * sizeof(void*)); assert(root->base); return root; @@ -50,7 +51,8 @@ int n; assert(root); root->limit = n; - root->base = root->end = root->beg = malloc(root->limit * sizeof(void*)); + root->beg = root->end = 0; + root->base = malloc(root->limit * sizeof(void*)); assert(root->base); return root; @@ -59,15 +61,13 @@ int n; int deq_size(root) deq *root; { - if (!root) { + if (!root) return -1; - } - if (root->beg <= root->end) { + if (root->beg <= root->end) return (root->end - root->beg); - } - return (root->base + root->limit - root->beg) + (root->end - root->base); + return (root->limit - root->beg) + (root->end); } void deq_resize(root) @@ -79,26 +79,25 @@ deq *root; tmp = malloc(root->limit * 2 * sizeof(void*)); assert(root->base); - if (root->beg > root->end) { + if (root->beg <= root->end) { + tmp = memcpy(tmp, root->base + root->beg, + deq_size(root) * sizeof(void*)); + } else { /*copy beg<->limit*/ - size = (root->base + (root->limit*sizeof(void*)) - root->beg); - tmp = memcpy(tmp, root->beg, size * sizeof(void*); + size = root->limit - root->beg; + tmp = memcpy(tmp, root->base + root->beg, size * sizeof(void*)); assert(tmp); /*copy base<->end*/ - tmp = memcpy(tmp + size, root->beg, - (root->end - root->base)* sizeof(void*)); + tmp = memcpy(tmp + size, root->base, + root->end * sizeof(void*)); assert(tmp); - } else { - size = deq_size(root); - tmp = memcpy(tmp, root->beg, size*sizeof(void*)); } root->limit *= 2; free(root->base); - root->base = root->beg = tmp; - root->end = root->base + size; + root->base = tmp; } void* deq_index(root, index) @@ -107,16 +106,15 @@ int index; { void **tmp; - if (!root) { + if (!root || index > root->limit + || (index >= root->end && index < root->beg)) return NULL; - } - tmp = root->base + ((root->beg + index - root->base) % root->limit); - if (tmp > root->end) { + index = (root->beg + index) % root->limit; + if (index >= root->end) return NULL; - } - return *tmp; + return root->base[index]; } void deq_push_back(root, item) @@ -125,17 +123,17 @@ void *item; { void **tmp; - if (!root) { + if (!root) return; - } - tmp = (root->base + (root->end - root->base) % root->limit); - if (tmp == root->beg) { + if (root->end >= root->limit) deq_resize(root); - tmp = (root->base + (root->end - root->base) % root->limit); - } - *(root->end = tmp) = item; + root->base[root->end++] = item; + root->end %= root->limit; + + if (root->end == root->beg) + root->end = root->limit; } void deq_push_front(root, item) @@ -144,29 +142,32 @@ void *item; { void **tmp; - if (!root) { + if (!root) return; - } - tmp = (root->base + ((root->beg - 1) - root->base) % root->limit); - if (tmp == root->beg) { + if (root->end >= root->limit) deq_resize(root); - tmp = (root->base + ((root->beg - 1) - root->base) % root->limit); - } - *(root->beg = tmp) = item; + --root->beg; + root->beg %= root->limit; + + root->base[root->beg] = item; + + if (root->end == root->beg) + root->end = root->limit; } void* deq_pop_front(root) deq *root; { void* tmp; - if (!root || root->beg == root->end) { + if (!root || root->beg == root->end) return NULL; - } - tmp = *(root->beg++); - root->beg = (root->base + (root->beg - root->base) % root->limit); + tmp = root->base[root->beg]; + + ++root->beg; + root->beg %= root->limit; return tmp; } @@ -174,15 +175,13 @@ deq *root; void* deq_pop_back(root) deq *root; { - void* tmp; - if (!root || root->end == root->beg) { + if (!root || root->end == root->beg) return NULL; - } - tmp = *(root->end--); - root->end = (root->base + (root->end - root->base) % root->limit); + --root->end; + root->end %= root->limit; - return tmp; + return root->base[root->end]; } void deq_free(root) @@ -190,8 +189,6 @@ deq *root; { free(root->base); root->base = NULL; - root->end = NULL; - root->beg = NULL; free(root); } @@ -216,9 +213,9 @@ deq *root; { void **tmp; - fprintf(stderr, "VEC[b: %p, p: %p, n:%p]:\n\t ", + fprintf(stderr, "VEC[b: %p, beg: %d, end:%d]:\n\t ", root->base, root->beg, root->end); - for (tmp = root->beg; tmp < root->end; tmp++){ + for (tmp = root->base; tmp < root->base + root->limit; tmp++){ fprintf(stderr, "[%p]", *tmp); } fprintf(stderr, "\n"); @@ -230,13 +227,16 @@ deq *root; deq *copy; copy = deq_with_capacity(root->limit); + assert(copy->base); - copy->base = memcpy(copy->base, root->beg, - deq_size(root) * sizeof(void*)); + copy->base = memcpy(copy->base, root->base, + root->limit * sizeof(void*)); assert(copy->base); - copy->beg = copy->base; - copy->end = copy->base + deq_size(root); + copy->beg = root->beg; + copy->end = root->end; + + return copy; } void deq_swap(root, i, j) @@ -246,48 +246,50 @@ int i, j; int len; void *tmp; - if (!root) { + if (!root) return; - } len = deq_size(root); - if (i >= len || j >= len) { + if (i >= len || j >= len) return; - } - tmp = root->end[i]; - root->end[j] = root->end[i]; - root->end[i] = tmp; + i += root->beg; + i %= root->limit; + + j += root->beg; + j %= root->limit; + + tmp = root->base[i]; + root->base[i] = root->base[j]; + root->base[j] = tmp; } +/*Note: Does not currently reduce memory footprint*/ void deq_truncate(root, size) deq *root; int size; { - if ((!root) || size > deq_size(root)) { + if (!root || size > deq_size(root)) return; - } - root->end = root->beg + size; + root->end = (root->beg + size) % root->limit; } void* deq_front(root) deq *root; { - if (!root) { + if (!root) return NULL; - } - return *root->beg; + return root->base[root->beg]; } void* deq_back(root) deq *root; { - if (!root) { + if (!root) return NULL; - } - return *root->end; + return root->base[(root->end - 1) % root->limit]; } -- cgit v1.1 From 10cd9eadf3f14d4b25ef85ea563938a784fcf20c Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Sat, 30 May 2020 20:11:45 -0400 Subject: Add deq_clear function for double ended queue. Frees all elements in double ended queue, does not free the queue struct itself (deq_free is used for this). --- collections/double_ended_queue.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'collections/double_ended_queue.c') diff --git a/collections/double_ended_queue.c b/collections/double_ended_queue.c index 956e362..7938307 100644 --- a/collections/double_ended_queue.c +++ b/collections/double_ended_queue.c @@ -184,6 +184,9 @@ deq *root; return root->base[root->end]; } +/* Note: Elements are not freed + * deq_clear should be called before if they are no longer needed. + */ void deq_free(root) deq *root; { @@ -193,6 +196,17 @@ deq *root; free(root); } +void deq_clear(root) +deq *root; +{ + int i, size; + + size = deq_size(root); + for (i = 0; i < size; i++) { + free(deq_index(root, i)); + } +} + void deq_print(root, to_string) deq *root; char* to_string(void*); -- cgit v1.1 From b93a7b87b55a42ca864325ae91328a5627885471 Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Sat, 30 May 2020 20:35:05 -0400 Subject: Add remove index function for double ended queue. --- collections/double_ended_queue.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'collections/double_ended_queue.c') diff --git a/collections/double_ended_queue.c b/collections/double_ended_queue.c index 7938307..0348cfa 100644 --- a/collections/double_ended_queue.c +++ b/collections/double_ended_queue.c @@ -184,6 +184,32 @@ deq *root; return root->base[root->end]; } +void deq_remove(root, index) +deq *root; +int index; +{ + if (!root || index > root->limit + || (index >= root->end && index < root->beg)) + return; + + index = (root->beg + index) % root->limit; + if (index >= root->end) + return NULL; + + root->base[index] = NULL; + + if (root->beg < root->end || index >= root->beg) { + root->beg = memmove(root->base + root->beg + 1, + root->base + root->beg, + (index - root->beg) * sizeof(void*)); + ++root->beg; + } else { + memmove(root->base + index, root->base + index + 1, + (--root->end - index) * sizeof(void*)); + } + +} + /* Note: Elements are not freed * deq_clear should be called before if they are no longer needed. */ -- cgit v1.1 From 7e3a4d7bd009df8975f5ef374f979da7405fd501 Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Mon, 8 Jun 2020 22:14:02 -0400 Subject: Fix trivial compiler errors. --- collections/double_ended_queue.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'collections/double_ended_queue.c') diff --git a/collections/double_ended_queue.c b/collections/double_ended_queue.c index 0348cfa..a8daf92 100644 --- a/collections/double_ended_queue.c +++ b/collections/double_ended_queue.c @@ -194,12 +194,12 @@ int index; index = (root->beg + index) % root->limit; if (index >= root->end) - return NULL; + return; root->base[index] = NULL; if (root->beg < root->end || index >= root->beg) { - root->beg = memmove(root->base + root->beg + 1, + memmove(root->base + root->beg + 1, root->base + root->beg, (index - root->beg) * sizeof(void*)); ++root->beg; -- cgit v1.1 From f4ce6540cfaf754ab4f0a6d4b8ed6b38c0cbe956 Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Mon, 8 Jun 2020 22:25:24 -0400 Subject: Add double ended queue swap remove front/back functions. --- collections/double_ended_queue.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'collections/double_ended_queue.c') diff --git a/collections/double_ended_queue.c b/collections/double_ended_queue.c index a8daf92..169693d 100644 --- a/collections/double_ended_queue.c +++ b/collections/double_ended_queue.c @@ -184,6 +184,22 @@ deq *root; return root->base[root->end]; } +void* deq_swap_rm_front(root, index) +deq *root; +int index; +{ + deq_swap(root, 0, index); + return deq_pop_front(root); +} + +void* deq_swap_rm_back(root, index) +deq *root; +int index; +{ + deq_swap(root,deq_size(root) - 1,index); + return deq_pop_back(root); +} + void deq_remove(root, index) deq *root; int index; -- cgit v1.1 From 92b0bac22ab3f3feeb48feb013753961581c7615 Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Mon, 8 Jun 2020 22:59:05 -0400 Subject: Fix bounds checking for deq remove. Bounds checking is now down after index is converted to a position in base array. Removed TODO comment was handled in previous commit (SHA: 4e4704b0251bb2b03d0fa573437b77b15567441c). --- collections/double_ended_queue.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) (limited to 'collections/double_ended_queue.c') diff --git a/collections/double_ended_queue.c b/collections/double_ended_queue.c index 169693d..e06ba36 100644 --- a/collections/double_ended_queue.c +++ b/collections/double_ended_queue.c @@ -11,10 +11,6 @@ * (resize, push, etc.) */ -/*TODO - * Fix empty vs totally full ambiquity - */ - /* Double ended queue as a circular buffer * base is pointer to buffer. * beg: postiton of the first element is stored. @@ -204,12 +200,14 @@ void deq_remove(root, index) deq *root; int index; { - if (!root || index > root->limit - || (index >= root->end && index < root->beg)) + if (!root || index > root->limit) return; index = (root->beg + index) % root->limit; - if (index >= root->end) + + /*Bounds check*/ + if ((root->beg <= root->end && index < root->beg || index >= root->end) + || (index >= root->end && index < root->beg)) return; root->base[index] = NULL; @@ -223,7 +221,6 @@ int index; memmove(root->base + index, root->base + index + 1, (--root->end - index) * sizeof(void*)); } - } /* Note: Elements are not freed -- cgit v1.1 From fb65c9cc91fe5bcf75e1519bd73d31242fbccb9d Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Wed, 10 Jun 2020 12:34:11 -0400 Subject: Add bounds checking macro for double ended queue. --- collections/double_ended_queue.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'collections/double_ended_queue.c') diff --git a/collections/double_ended_queue.c b/collections/double_ended_queue.c index e06ba36..f8f59e4 100644 --- a/collections/double_ended_queue.c +++ b/collections/double_ended_queue.c @@ -5,10 +5,15 @@ #include +/*Checks bounds for index (y) in queue*/ +#define DEQ_IN_BOUNDS(x, y) (y < deq_size(x)) \ + #define START_SIZE 64; /*TODO add returned error codes for current void functions * (resize, push, etc.) + * + * Should all functions return a status code and take in a dest argument? */ /* Double ended queue as a circular buffer @@ -184,6 +189,9 @@ void* deq_swap_rm_front(root, index) deq *root; int index; { + if (!root || !DEQ_IN_BOUNDS(root,index)) + return NULL; + deq_swap(root, 0, index); return deq_pop_front(root); } @@ -192,6 +200,9 @@ void* deq_swap_rm_back(root, index) deq *root; int index; { + if (!root || !DEQ_IN_BOUNDS(root,index)) + return NULL; + deq_swap(root,deq_size(root) - 1,index); return deq_pop_back(root); } @@ -200,16 +211,11 @@ void deq_remove(root, index) deq *root; int index; { - if (!root || index > root->limit) + if (!root || !DEQ_IN_BOUNDS(root,index)); return; index = (root->beg + index) % root->limit; - /*Bounds check*/ - if ((root->beg <= root->end && index < root->beg || index >= root->end) - || (index >= root->end && index < root->beg)) - return; - root->base[index] = NULL; if (root->beg < root->end || index >= root->beg) { -- cgit v1.1 From ce6d7f43e7ad77b3eec043ff731d17ab21e89e87 Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Wed, 10 Jun 2020 12:51:52 -0400 Subject: Fix double ended queue index to use bounds check. --- collections/double_ended_queue.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'collections/double_ended_queue.c') diff --git a/collections/double_ended_queue.c b/collections/double_ended_queue.c index f8f59e4..e737d28 100644 --- a/collections/double_ended_queue.c +++ b/collections/double_ended_queue.c @@ -107,15 +107,10 @@ int index; { void **tmp; - if (!root || index > root->limit - || (index >= root->end && index < root->beg)) - return NULL; - - index = (root->beg + index) % root->limit; - if (index >= root->end) + if (!root || !DEQ_IN_BOUNDS(root,index)) return NULL; - return root->base[index]; + return root->base[(root->beg + index) % root->limit]; } void deq_push_back(root, item) -- cgit v1.1 From b38bcd56356973a50797630f8366d6701dd7c988 Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Wed, 10 Jun 2020 12:55:33 -0400 Subject: Add set index function for double ended queue. --- collections/double_ended_queue.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'collections/double_ended_queue.c') diff --git a/collections/double_ended_queue.c b/collections/double_ended_queue.c index e737d28..232fb44 100644 --- a/collections/double_ended_queue.c +++ b/collections/double_ended_queue.c @@ -101,6 +101,16 @@ deq *root; root->base = tmp; } +void deq_set(root, index, item) +deq *root; +int index; +void *item; +{ + if (!root || !DEQ_IN_BOUNDS(root, index)) + return; + root->base[(root->beg + index) % root->limit] = item; +} + void* deq_index(root, index) deq *root; int index; -- cgit v1.1 From 6dce1b32a4e19c875131cdbb441cca0ca23f73f5 Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Wed, 10 Jun 2020 18:09:48 -0400 Subject: Add capacity function to double ended queue. --- collections/double_ended_queue.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'collections/double_ended_queue.c') diff --git a/collections/double_ended_queue.c b/collections/double_ended_queue.c index 232fb44..7857c3a 100644 --- a/collections/double_ended_queue.c +++ b/collections/double_ended_queue.c @@ -71,6 +71,16 @@ deq *root; return (root->limit - root->beg) + (root->end); } +int deq_capacity(root) +deq *root; +{ + if (!root) { + return -1; + } else { + return root->limit; + } +} + void deq_resize(root) deq *root; { -- cgit v1.1 From 0f7085dedd2f60f2ccc0b1f49558f5be89de97b2 Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Wed, 10 Jun 2020 23:23:52 -0400 Subject: Fix change order of functions in double ended queue. Groups functions that return items together. --- collections/double_ended_queue.c | 88 ++++++++++++++++++++-------------------- 1 file changed, 44 insertions(+), 44 deletions(-) (limited to 'collections/double_ended_queue.c') diff --git a/collections/double_ended_queue.c b/collections/double_ended_queue.c index 7857c3a..bf329ca 100644 --- a/collections/double_ended_queue.c +++ b/collections/double_ended_queue.c @@ -111,16 +111,6 @@ deq *root; root->base = tmp; } -void deq_set(root, index, item) -deq *root; -int index; -void *item; -{ - if (!root || !DEQ_IN_BOUNDS(root, index)) - return; - root->base[(root->beg + index) % root->limit] = item; -} - void* deq_index(root, index) deq *root; int index; @@ -133,7 +123,7 @@ int index; return root->base[(root->beg + index) % root->limit]; } -void deq_push_back(root, item) +void deq_push_front(root, item) deq *root; void *item; { @@ -145,14 +135,16 @@ void *item; if (root->end >= root->limit) deq_resize(root); - root->base[root->end++] = item; - root->end %= root->limit; + --root->beg; + root->beg %= root->limit; + + root->base[root->beg] = item; if (root->end == root->beg) root->end = root->limit; } -void deq_push_front(root, item) +void deq_push_back(root, item) deq *root; void *item; { @@ -164,15 +156,23 @@ void *item; if (root->end >= root->limit) deq_resize(root); - --root->beg; - root->beg %= root->limit; - - root->base[root->beg] = item; + root->base[root->end++] = item; + root->end %= root->limit; if (root->end == root->beg) root->end = root->limit; } +void deq_set(root, index, item) +deq *root; +int index; +void *item; +{ + if (!root || !DEQ_IN_BOUNDS(root, index)) + return; + root->base[(root->beg + index) % root->limit] = item; +} + void* deq_pop_front(root) deq *root; { @@ -222,6 +222,32 @@ int index; return deq_pop_back(root); } +void deq_swap(root, i, j) +deq *root; +int i, j; +{ + int len; + void *tmp; + + if (!root) + return; + + len = deq_size(root); + + if (i >= len || j >= len) + return; + + i += root->beg; + i %= root->limit; + + j += root->beg; + j %= root->limit; + + tmp = root->base[i]; + root->base[i] = root->base[j]; + root->base[j] = tmp; +} + void deq_remove(root, index) deq *root; int index; @@ -313,32 +339,6 @@ deq *root; return copy; } -void deq_swap(root, i, j) -deq *root; -int i, j; -{ - int len; - void *tmp; - - if (!root) - return; - - len = deq_size(root); - - if (i >= len || j >= len) - return; - - i += root->beg; - i %= root->limit; - - j += root->beg; - j %= root->limit; - - tmp = root->base[i]; - root->base[i] = root->base[j]; - root->base[j] = tmp; -} - /*Note: Does not currently reduce memory footprint*/ void deq_truncate(root, size) deq *root; -- cgit v1.1 From 277e14127bbe1a5080a2a88b6ee3ef94859bc3a5 Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Wed, 10 Jun 2020 23:37:15 -0400 Subject: Add insert function to double ended queue. --- collections/double_ended_queue.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'collections/double_ended_queue.c') diff --git a/collections/double_ended_queue.c b/collections/double_ended_queue.c index bf329ca..4de6a27 100644 --- a/collections/double_ended_queue.c +++ b/collections/double_ended_queue.c @@ -173,6 +173,44 @@ void *item; root->base[(root->beg + index) % root->limit] = item; } +void deq_insert(root, index, item) +deq *root; +int index; +void *item; +{ + if (!root) + return; + + if (index > deq_size(root)) + return; + + if (root->end >= root->limit) + deq_resize(root); + + index = (root->beg + index) % root->limit; + + if (root->beg < root->end) { + memmove(root->base + index + 1, root->base + index, + (root->end - index) * sizeof(void*)); + ++root->end; + root->end = root->end % root->limit; + } else if (index < root->end) { + memmove(root->base + index + 1, + root->base + index, + (root->end - index) * sizeof(void*)); + ++root->end; + } else { + memmove(root->base + root->beg - 1, root->base + root->beg, + (index - root->beg) * sizeof(void*)); + --root->beg; + } + + if (root->end == root->beg) + root->end = root->limit; + + root->base[index] = item; +} + void* deq_pop_front(root) deq *root; { -- cgit v1.1 From 349c75c16a3713ee6f3ffd701f1c88ce31ecd8de Mon Sep 17 00:00:00 2001 From: Tucker Evans Date: Thu, 11 Jun 2020 14:42:06 -0400 Subject: Add reserve function for double ended queue. --- collections/double_ended_queue.c | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) (limited to 'collections/double_ended_queue.c') diff --git a/collections/double_ended_queue.c b/collections/double_ended_queue.c index 4de6a27..015b90b 100644 --- a/collections/double_ended_queue.c +++ b/collections/double_ended_queue.c @@ -88,7 +88,7 @@ deq *root; int size; tmp = malloc(root->limit * 2 * sizeof(void*)); - assert(root->base); + assert(tmp); if (root->beg <= root->end) { tmp = memcpy(tmp, root->base + root->beg, @@ -405,3 +405,37 @@ deq *root; return root->base[(root->end - 1) % root->limit]; } + +void deq_reserve(root, size) +deq *root; +int size; +{ + void **tmp; + int i, cur_size; + + cur_size = deq_size(root); + for (i = root->limit; i - cur_size < size; i*=2); + + tmp = malloc(i * sizeof(void*)); + assert(tmp); + + if (root->beg <= root->end) { + tmp = memcpy(tmp, root->base + root->beg, + deq_size(root) * sizeof(void*)); + } else { + /*copy beg<->limit*/ + size = root->limit - root->beg; + tmp = memcpy(tmp, root->base + root->beg, size * sizeof(void*)); + assert(tmp); + + /*copy base<->end*/ + tmp = memcpy(tmp + size, root->base, + root->end * sizeof(void*)); + assert(tmp); + } + + root->limit *= 2; + + free(root->base); + root->base = tmp; +} -- cgit v1.1