diff options
Diffstat (limited to 'collections')
| -rw-r--r-- | collections/double_ended_queue.c | 154 | 
1 files changed, 78 insertions, 76 deletions
| 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];  } | 
