diff options
| author | Tucker Evans <tucker@tuckerevans.com> | 2020-06-11 14:42:06 -0400 | 
|---|---|---|
| committer | Tucker Evans <tucker@tuckerevans.com> | 2020-06-11 15:00:14 -0400 | 
| commit | 349c75c16a3713ee6f3ffd701f1c88ce31ecd8de (patch) | |
| tree | d6aaeba8d124b4e9d760cc65ed2c94467035f831 | |
| parent | 277e14127bbe1a5080a2a88b6ee3ef94859bc3a5 (diff) | |
Add reserve function for double ended queue.
| -rw-r--r-- | collections/double_ended_queue.adoc | 19 | ||||
| -rw-r--r-- | collections/double_ended_queue.c | 36 | ||||
| -rw-r--r-- | collections/double_ended_queue.h | 6 | 
3 files changed, 54 insertions, 7 deletions
| diff --git a/collections/double_ended_queue.adoc b/collections/double_ended_queue.adoc index 70cbbaf..9ecf9cb 100644 --- a/collections/double_ended_queue.adoc +++ b/collections/double_ended_queue.adoc @@ -1,7 +1,7 @@  Double Ended Queue  ==================  Tucker Evans -v0.2, 2020-06-10 +v0.3, 2020-06-10  A double ended queue implemented in a circular buffer. @@ -440,6 +440,23 @@ deq_truncate(queue, 1);  assert(deq_size == 1);  ---- ++void deq_reserve(deq *self, int additional)+ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Reserves space for +additional+ items. May reserve more memory to avoid too +many reallocations. + +Examples +^^^^^^^^ +[source,c] +---- +#include "double_ended_queue.h" + +deq *queue = deq_with_capacity(16); + +deq_reserve(queue, 20); +assert(deq_capacity(queue) >= 20); +---- +  +void deq_remove(deq *self, int index)+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  Element at position +index+ of +self+ is removed from queue and the remaining 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; +} diff --git a/collections/double_ended_queue.h b/collections/double_ended_queue.h index c45b11b..6448c8a 100644 --- a/collections/double_ended_queue.h +++ b/collections/double_ended_queue.h @@ -36,12 +36,8 @@ void deq_swap(deq*, int, int);  /*Note: Does not currently reduce memory footprint*/  void deq_truncate(deq*, int); +void deq_reserve(deq*, int);  void deq_remove(deq*, int);  void deq_print(deq*, char* (void*)); - - -/*TODO - * resevee - */  #endif | 
