Mercurial > almixer_isolated
diff CircularQueue.c @ 0:01e39f9f58d5
Bitkeeper era.
author | Eric Wing <ewing . public |-at-| gmail . com> |
---|---|
date | Wed, 27 Oct 2010 16:50:19 -0700 |
parents | |
children | a8a8fe374984 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CircularQueue.c Wed Oct 27 16:50:19 2010 -0700 @@ -0,0 +1,512 @@ +/* + CircularQueue + Copyright (C) 2002 Eric Wing + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "CircularQueue.h" +#include <stddef.h> /* for NULL */ +#include <stdlib.h> /* for malloc/free */ +#include <stdio.h> /* for debugging */ + +CircularQueueUnsignedInt* CircularQueueUnsignedInt_CreateQueue(unsigned int max_size) +{ + CircularQueueUnsignedInt* ret_ptr; + if(max_size < 1) + { + return NULL; + } + ret_ptr = (CircularQueueUnsignedInt*)malloc(sizeof(CircularQueueUnsignedInt)); + if(NULL == ret_ptr) + { + /* Out of memory */ + return NULL; + } + ret_ptr->internalQueue = (unsigned int*)malloc(sizeof(unsigned int) * max_size); + if(NULL == ret_ptr->internalQueue) + { + /* Out of memory */ + free(ret_ptr); + return NULL; + } + ret_ptr->maxSize = max_size; + ret_ptr->currentSize = 0; + ret_ptr->headIndex = 0; + ret_ptr->tailIndex = 0; + + return ret_ptr; +} + +void CircularQueueUnsignedInt_FreeQueue(CircularQueueUnsignedInt* queue) +{ + if(NULL == queue) + { + return; + } + + free(queue->internalQueue); + free(queue); +} + +/** + * Returns 1 if successful, 0 if failure. + */ +unsigned int CircularQueueUnsignedInt_PushBack(CircularQueueUnsignedInt* queue, unsigned int value) +{ + unsigned int temp_index; + if(NULL == queue) + { + return 0; + } + if(queue->currentSize >= queue->maxSize) + { + return 0; + } + temp_index = queue->tailIndex + 1; + if(temp_index >= queue->maxSize) + { + /* need to wrap tail index around */ + temp_index = 0; + } + /* So with my implementation, the tail index actually points + * to the slot right after the last value. + * So we will enter the value in the current tail, and then increment + * the tail. + * Note that in a full queue, the head and tail will be the same (I think). + */ + queue->internalQueue[queue->tailIndex] = value; + queue->tailIndex = temp_index; + queue->currentSize++; + + return 1; +} + +/** + * Returns 1 if successful, 0 if failure. + */ +unsigned int CircularQueueUnsignedInt_PushFront(CircularQueueUnsignedInt* queue, unsigned int value) +{ + unsigned int temp_index; + if(NULL == queue) + { + return 0; + } + if(queue->currentSize >= queue->maxSize) + { + return 0; + } + + /* This check is needed to prevent the unsigned int from overflowing. */ + if(0 == queue->headIndex) + { + /* Need to wrap head index around */ + temp_index = queue->maxSize - 1; + } + else + { + temp_index = queue->headIndex - 1; + } + /* So unlike the tail, the head index actually points to the element + * at the head, and not an element before (or after) the head. + */ + queue->internalQueue[temp_index] = value; + queue->headIndex = temp_index; + queue->currentSize++; + return 1; +} + +unsigned int CircularQueueUnsignedInt_PopFront(CircularQueueUnsignedInt* queue) +{ + unsigned int temp_index; + if(NULL == queue) + { + return 0; + } + if(queue->currentSize == 0) + { + return 0; + } + temp_index = queue->headIndex + 1; + if(temp_index >= queue->maxSize) + { + /* need to wrap tail index around */ + temp_index = 0; + } + queue->headIndex = temp_index; + queue->currentSize--; + return 1; +} + + +unsigned int CircularQueueUnsignedInt_PopBack(CircularQueueUnsignedInt* queue) +{ + unsigned int temp_index; + if(NULL == queue) + { + return 0; + } + if(queue->currentSize == 0) + { + return 0; + } + + /* This check is needed to prevent the unsigned int from overflowing. */ + if(0 == queue->tailIndex) + { + temp_index = queue->maxSize - 1; + } + else + { + temp_index = queue->tailIndex - 1; + } + + queue->tailIndex = temp_index; + queue->currentSize--; + return 1; +} + +unsigned int CircularQueueUnsignedInt_Front(CircularQueueUnsignedInt* queue) +{ + if(NULL == queue) + { + return 0; + } + if(0 == queue->currentSize) + { + return 0; + } + return queue->internalQueue[queue->headIndex]; +} + + +unsigned int CircularQueueUnsignedInt_Back(CircularQueueUnsignedInt* queue) +{ + unsigned int temp_index; + if(NULL == queue) + { + return 0; + } + if(0 == queue->currentSize) + { + return 0; + } + if(0 == queue->tailIndex) + { + /* need to wrap tail index around */ + temp_index = queue->maxSize-1; + } + else + { + temp_index = queue->tailIndex-1; + } + + return queue->internalQueue[temp_index]; +} + +unsigned int CircularQueueUnsignedInt_Size(CircularQueueUnsignedInt* queue) +{ + if(NULL == queue) + { + return 0; + } + return queue->currentSize; +} + +unsigned int CircularQueueUnsignedInt_MaxSize(CircularQueueUnsignedInt* queue) +{ + if(NULL == queue) + { + return 0; + } + return queue->maxSize; +} + +void CircularQueueUnsignedInt_Clear(CircularQueueUnsignedInt* queue) +{ + if(NULL == queue) + { + return; + } + + queue->currentSize = 0; + queue->headIndex = 0; + queue->tailIndex = 0; +} + +void CircularQueueUnsignedInt_Print(CircularQueueUnsignedInt* queue) +{ + unsigned int i; + unsigned int count; + if(NULL == queue) + { + return; + } + fprintf(stderr, "Queue: "); + for(count=0, i=queue->headIndex; count<queue->currentSize; count++, i++) + { + if(i >= queue->maxSize) + { + i=0; + } + fprintf(stderr, "%d ", queue->internalQueue[i]); + } + fprintf(stderr, "\n"); +} + +/* + * Implementation for void* version starts here. + */ + +CircularQueueVoid* CircularQueueVoid_CreateQueue(unsigned int max_size) +{ + CircularQueueVoid* ret_ptr; + if(max_size < 1) + { + return NULL; + } + ret_ptr = (CircularQueueVoid*)malloc(sizeof(CircularQueueVoid)); + if(NULL == ret_ptr) + { + /* Out of memory */ + return NULL; + } + ret_ptr->internalQueue = (void**)malloc(sizeof(void*) * max_size); + if(NULL == ret_ptr->internalQueue) + { + /* Out of memory */ + free(ret_ptr); + return NULL; + } + ret_ptr->maxSize = max_size; + ret_ptr->currentSize = 0; + ret_ptr->headIndex = 0; + ret_ptr->tailIndex = 0; + + return ret_ptr; +} + +void CircularQueueVoid_FreeQueue(CircularQueueVoid* queue) +{ + if(NULL == queue) + { + return; + } + + free(queue->internalQueue); + free(queue); +} + +/** + * Returns 1 if successful, 0 if failure. + */ +unsigned int CircularQueueVoid_PushBack(CircularQueueVoid* queue, void* value) +{ + unsigned int temp_index; + if(NULL == queue) + { + return 0; + } + if(queue->currentSize >= queue->maxSize) + { + return 0; + } + temp_index = queue->tailIndex + 1; + if(temp_index >= queue->maxSize) + { + /* need to wrap tail index around */ + temp_index = 0; + } + queue->internalQueue[queue->tailIndex] = value; + queue->tailIndex = temp_index; + queue->currentSize++; + + return 1; +} + +/** + * Returns 1 if successful, 0 if failure. + */ +unsigned int CircularQueueVoid_PushFront(CircularQueueVoid* queue, void* value) +{ + unsigned int temp_index; + if(NULL == queue) + { + return 0; + } + if(queue->currentSize >= queue->maxSize) + { + return 0; + } + + /* This check is needed to prevent the unsigned int from overflowing. */ + if(0 == queue->headIndex) + { + /* Need to wrap head index around */ + temp_index = queue->maxSize - 1; + } + else + { + temp_index = queue->headIndex - 1; + } + queue->internalQueue[temp_index] = value; + queue->headIndex = temp_index; + queue->currentSize++; + return 1; +} + +unsigned int CircularQueueVoid_PopFront(CircularQueueVoid* queue) +{ + unsigned int temp_index; + if(NULL == queue) + { + return 0; + } + if(queue->currentSize == 0) + { + return 0; + } + temp_index = queue->headIndex + 1; + if(temp_index >= queue->maxSize) + { + /* need to wrap tail index around */ + temp_index = 0; + } + queue->headIndex = temp_index; + queue->currentSize--; + return 1; +} + + +unsigned int CircularQueueVoid_PopBack(CircularQueueVoid* queue) +{ + unsigned int temp_index; + if(NULL == queue) + { + return 0; + } + if(queue->currentSize == 0) + { + return 0; + } + + /* This check is needed to prevent the unsigned int from overflowing. */ + if(0 == queue->tailIndex) + { + temp_index = queue->maxSize - 1; + } + else + { + temp_index = queue->tailIndex - 1; + } + + queue->tailIndex = temp_index; + queue->currentSize--; + return 1; +} + +void* CircularQueueVoid_Front(CircularQueueVoid* queue) +{ + if(NULL == queue) + { + return 0; + } + if(0 == queue->currentSize) + { + return 0; + } + return queue->internalQueue[queue->headIndex]; +} + + +void* CircularQueueVoid_Back(CircularQueueVoid* queue) +{ + unsigned int temp_index; + if(NULL == queue) + { + return 0; + } + if(0 == queue->currentSize) + { + return 0; + } + if(0 == queue->tailIndex) + { + /* need to wrap tail index around */ + temp_index = queue->maxSize-1; + } + else + { + temp_index = queue->tailIndex-1; + } + + return queue->internalQueue[temp_index]; +} + +unsigned int CircularQueueVoid_Size(CircularQueueVoid* queue) +{ + if(NULL == queue) + { + return 0; + } + return queue->currentSize; +} + +unsigned int CircularQueueVoid_MaxSize(CircularQueueVoid* queue) +{ + if(NULL == queue) + { + return 0; + } + return queue->maxSize; +} + +void CircularQueueVoid_Clear(CircularQueueVoid* queue) +{ + if(NULL == queue) + { + return; + } + + queue->currentSize = 0; + queue->headIndex = 0; + queue->tailIndex = 0; +} + +/* Not implemented for void* */ +/* +void CircularQueueVoid_Print(CircularQueueVoid* queue) +{ + unsigned int i; + unsigned int count; + if(NULL == queue) + { + return; + } + fprintf(stderr, "Queue: "); + for(count=0, i=queue->headIndex; count<queue->currentSize; count++, i++) + { + if(i >= queue->maxSize) + { + i=0; + } + fprintf(stderr, "%d ", queue->internalQueue[i]); + } + fprintf(stderr, "\n"); +} +*/ + + +