Mercurial > almixer_isolated
view CircularQueue.c @ 23:ee96f91ba887
Bump version since I've changed the public API a bit.
author | Eric Wing <ewing . public |-at-| gmail . com> |
---|---|
date | Fri, 24 Dec 2010 03:26:58 -0800 |
parents | 279d0427ef26 |
children |
line wrap: on
line source
/* 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) { // printf("pushBack: %d\n", value); unsigned int temp_index; if(NULL == queue) { return 0; } if(queue->currentSize >= queue->maxSize) { printf("failed to pushBack: %d\n", value); 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; // printf("PopFront: %d, %d\n", queue->headIndex,queue->internalQueue[queue->headIndex] ); 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"); } unsigned int CircularQueueUnsignedInt_ValueAtIndex(CircularQueueUnsignedInt* queue, unsigned int the_index) { unsigned int i; if(NULL == queue) { return 0; } if(the_index >= queue->currentSize) { return 0; } i = (queue->headIndex + the_index) % queue->currentSize; // fprintf(stderr, "%d\n", queue->internalQueue[i]); return queue->internalQueue[i]; } /* * 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; } 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, "%x ", (unsigned int)queue->internalQueue[i]); } fprintf(stderr, "\n"); } void* CircularQueueVoid_ValueAtIndex(CircularQueueVoid* queue, unsigned int the_index) { unsigned int i; if(NULL == queue) { return NULL; } if(the_index >= queue->currentSize) { return NULL; } i = (queue->headIndex + the_index) % queue->currentSize; // fprintf(stderr, "%d\n", queue->internalQueue[i]); return queue->internalQueue[i]; }