a simple c queue

Committer:
danilob
Date:
Sat Feb 14 23:25:22 2015 +0000
Revision:
0:8b473c4a0afc
it has been improved

Who changed what in which revision?

UserRevisionLine numberNew contents of line
danilob 0:8b473c4a0afc 1 /*
danilob 0:8b473c4a0afc 2 * queue.c
danilob 0:8b473c4a0afc 3 *
danilob 0:8b473c4a0afc 4 * Created on: Jan 15, 2015
danilob 0:8b473c4a0afc 5 * Author: danilob
danilob 0:8b473c4a0afc 6 */
danilob 0:8b473c4a0afc 7
danilob 0:8b473c4a0afc 8
danilob 0:8b473c4a0afc 9 #include <stdio.h>
danilob 0:8b473c4a0afc 10 #include <stdlib.h>
danilob 0:8b473c4a0afc 11 #include "queue.h"
danilob 0:8b473c4a0afc 12
danilob 0:8b473c4a0afc 13 //auxiliar function to handle the reset of Index in neede for the queue
danilob 0:8b473c4a0afc 14 queue_index_t incrementIndex(queue_index_t index, queue_size_t size) //functionw ill increment queue index
danilob 0:8b473c4a0afc 15 {
danilob 0:8b473c4a0afc 16 if(index == size-1)
danilob 0:8b473c4a0afc 17 index = 0;
danilob 0:8b473c4a0afc 18 else
danilob 0:8b473c4a0afc 19 index++;
danilob 0:8b473c4a0afc 20 return index;
danilob 0:8b473c4a0afc 21 }
danilob 0:8b473c4a0afc 22
danilob 0:8b473c4a0afc 23 // Standard queue implementation that leaves one spot empty so easier to check for full/empty.
danilob 0:8b473c4a0afc 24 void queue_init(queue_t* q, queue_size_t size) {
danilob 0:8b473c4a0afc 25 q->indexIn = 0;
danilob 0:8b473c4a0afc 26 q->indexOut = 0;
danilob 0:8b473c4a0afc 27 q->elementCount = 0;
danilob 0:8b473c4a0afc 28 q->size = size+1; // Add one additional location for the empty location.
danilob 0:8b473c4a0afc 29 q->data = (queue_data_t *) malloc(q->size * sizeof(queue_data_t));
danilob 0:8b473c4a0afc 30 }
danilob 0:8b473c4a0afc 31
danilob 0:8b473c4a0afc 32 queue_size_t queue_size(queue_t* q);
danilob 0:8b473c4a0afc 33
danilob 0:8b473c4a0afc 34 // Returns true if the queue is full.
danilob 0:8b473c4a0afc 35 bool queueFull(queue_t* q)
danilob 0:8b473c4a0afc 36 {
danilob 0:8b473c4a0afc 37 if(q->elementCount == q->size-1)
danilob 0:8b473c4a0afc 38 return 1;
danilob 0:8b473c4a0afc 39 return 0;
danilob 0:8b473c4a0afc 40 }
danilob 0:8b473c4a0afc 41
danilob 0:8b473c4a0afc 42 // Returns true if the queue is empty.
danilob 0:8b473c4a0afc 43 bool queue_empty(queue_t* q)
danilob 0:8b473c4a0afc 44 {
danilob 0:8b473c4a0afc 45 if(q->elementCount == (queue_size_t)0)
danilob 0:8b473c4a0afc 46 return 1;
danilob 0:8b473c4a0afc 47 return 0;
danilob 0:8b473c4a0afc 48 }
danilob 0:8b473c4a0afc 49
danilob 0:8b473c4a0afc 50 // Pushes a new element into the queue. Reports an error if the queue is full.
danilob 0:8b473c4a0afc 51 void queue_push(queue_t* q, queue_data_t value)
danilob 0:8b473c4a0afc 52 {
danilob 0:8b473c4a0afc 53 if(queueFull(q))
danilob 0:8b473c4a0afc 54 printf("Cannot insert, full queue!\n\r"); // This prints on the console.
danilob 0:8b473c4a0afc 55 else
danilob 0:8b473c4a0afc 56 {
danilob 0:8b473c4a0afc 57 q->data[q->indexIn] = value;
danilob 0:8b473c4a0afc 58 q->elementCount++;
danilob 0:8b473c4a0afc 59 q->indexIn = incrementIndex(q->indexIn, q->size);
danilob 0:8b473c4a0afc 60 }
danilob 0:8b473c4a0afc 61
danilob 0:8b473c4a0afc 62 }
danilob 0:8b473c4a0afc 63
danilob 0:8b473c4a0afc 64 // Removes the oldest element in the queue.
danilob 0:8b473c4a0afc 65 queue_data_t queue_pop(queue_t* q)
danilob 0:8b473c4a0afc 66 {
danilob 0:8b473c4a0afc 67 queue_data_t rdata;
danilob 0:8b473c4a0afc 68 if(queue_empty(q))
danilob 0:8b473c4a0afc 69 printf("Queue is empty\n\r"); // This prints on the console.
danilob 0:8b473c4a0afc 70 else
danilob 0:8b473c4a0afc 71 {
danilob 0:8b473c4a0afc 72 rdata = q->data[q->indexOut];
danilob 0:8b473c4a0afc 73 q->elementCount--;
danilob 0:8b473c4a0afc 74 q->indexOut = incrementIndex(q->indexOut, q->size);
danilob 0:8b473c4a0afc 75 return rdata;
danilob 0:8b473c4a0afc 76 }
danilob 0:8b473c4a0afc 77 return 0;
danilob 0:8b473c4a0afc 78 }
danilob 0:8b473c4a0afc 79
danilob 0:8b473c4a0afc 80 // Pushes a new element into the queue, making room by removing the oldest element.
danilob 0:8b473c4a0afc 81 void queue_overwritePush(queue_t* q, queue_data_t value)
danilob 0:8b473c4a0afc 82 {
danilob 0:8b473c4a0afc 83 if(queueFull(q))
danilob 0:8b473c4a0afc 84 {
danilob 0:8b473c4a0afc 85 printf("warning Queue is being overwritten\n\r"); // This prints on the console.
danilob 0:8b473c4a0afc 86 q->data[q->indexIn] = value;
danilob 0:8b473c4a0afc 87 q->indexIn = incrementIndex(q->indexIn, q->size);
danilob 0:8b473c4a0afc 88 q->indexOut = incrementIndex(q->indexOut, q->size);
danilob 0:8b473c4a0afc 89 }
danilob 0:8b473c4a0afc 90 else
danilob 0:8b473c4a0afc 91 queue_push(q,value);
danilob 0:8b473c4a0afc 92 }
danilob 0:8b473c4a0afc 93
danilob 0:8b473c4a0afc 94 // Provides random-access read capability to the queue.
danilob 0:8b473c4a0afc 95 // Low-valued indexes access older queue elements while higher-value indexes access newer elements
danilob 0:8b473c4a0afc 96 // (according to the order that they were added).
danilob 0:8b473c4a0afc 97 queue_data_t queue_readElementAt(queue_t* q, queue_index_t index)
danilob 0:8b473c4a0afc 98 {
danilob 0:8b473c4a0afc 99 if(queue_empty(q))
danilob 0:8b473c4a0afc 100 printf("Queue is empty\n\r"); // This prints on the console.
danilob 0:8b473c4a0afc 101 else
danilob 0:8b473c4a0afc 102 {
danilob 0:8b473c4a0afc 103 if(index < q->elementCount)
danilob 0:8b473c4a0afc 104 {
danilob 0:8b473c4a0afc 105 if((index + q->indexOut) < q->size-1)
danilob 0:8b473c4a0afc 106 return q->data[index+ q->indexOut];
danilob 0:8b473c4a0afc 107 else
danilob 0:8b473c4a0afc 108 return q->data[q->size - (index+ q->indexOut) -1];
danilob 0:8b473c4a0afc 109 }
danilob 0:8b473c4a0afc 110 else
danilob 0:8b473c4a0afc 111 printf("index out of bounds\n\r");
danilob 0:8b473c4a0afc 112 }
danilob 0:8b473c4a0afc 113 return 0;
danilob 0:8b473c4a0afc 114 }
danilob 0:8b473c4a0afc 115
danilob 0:8b473c4a0afc 116 // Returns a count of the elements currently contained in the queue.
danilob 0:8b473c4a0afc 117 queue_size_t queue_elementCount(queue_t* q)
danilob 0:8b473c4a0afc 118 {
danilob 0:8b473c4a0afc 119 return q->elementCount;
danilob 0:8b473c4a0afc 120 }
danilob 0:8b473c4a0afc 121
danilob 0:8b473c4a0afc 122 // Prints the current contents of the queue. Handy for debugging.
danilob 0:8b473c4a0afc 123 void queue_print(queue_t* q)
danilob 0:8b473c4a0afc 124 {
danilob 0:8b473c4a0afc 125 queue_index_t indexOutTmp;
danilob 0:8b473c4a0afc 126 if(queue_empty(q))
danilob 0:8b473c4a0afc 127 printf("Queue is empty.\n\r");
danilob 0:8b473c4a0afc 128 else
danilob 0:8b473c4a0afc 129 {
danilob 0:8b473c4a0afc 130 for (indexOutTmp = q->indexOut; indexOutTmp != q->indexIn; indexOutTmp = incrementIndex(indexOutTmp, q->size))
danilob 0:8b473c4a0afc 131 printf("%lf\n\r", q->data[indexOutTmp]);
danilob 0:8b473c4a0afc 132 }
danilob 0:8b473c4a0afc 133 }
danilob 0:8b473c4a0afc 134
danilob 0:8b473c4a0afc 135 // Performs a comprehensive test of all queue functions.
danilob 0:8b473c4a0afc 136 int queue_runTest()
danilob 0:8b473c4a0afc 137 {
danilob 0:8b473c4a0afc 138 queue_t q;
danilob 0:8b473c4a0afc 139 queue_init(&q, 3);
danilob 0:8b473c4a0afc 140 queue_pop(&q);
danilob 0:8b473c4a0afc 141
danilob 0:8b473c4a0afc 142 queue_push(&q, 1);
danilob 0:8b473c4a0afc 143 printf("Element count : %lf \n\r",queue_elementCount(&q));
danilob 0:8b473c4a0afc 144 queue_push(&q, 2);
danilob 0:8b473c4a0afc 145 printf("Element count : %lf\n\r",queue_elementCount(&q));
danilob 0:8b473c4a0afc 146 queue_push(&q, 3);
danilob 0:8b473c4a0afc 147 printf("Element count : %lf\n\r",queue_elementCount(&q));
danilob 0:8b473c4a0afc 148 queue_push(&q, 6);
danilob 0:8b473c4a0afc 149
danilob 0:8b473c4a0afc 150 printf("printing contents of queue.\n\r");
danilob 0:8b473c4a0afc 151 queue_print(&q);
danilob 0:8b473c4a0afc 152 printf("done printing contents of queue.\n\r");
danilob 0:8b473c4a0afc 153
danilob 0:8b473c4a0afc 154 printf("%lf\n\r", queue_pop(&q));
danilob 0:8b473c4a0afc 155 queue_push(&q, 4);
danilob 0:8b473c4a0afc 156 printf("%lf\n\r", queue_pop(&q));
danilob 0:8b473c4a0afc 157 queue_push(&q, 5);
danilob 0:8b473c4a0afc 158 printf("%lf\n\r", queue_pop(&q));
danilob 0:8b473c4a0afc 159
danilob 0:8b473c4a0afc 160 printf("printing contents of queue.\n\r");
danilob 0:8b473c4a0afc 161 queue_print(&q);
danilob 0:8b473c4a0afc 162 printf("done printing contents of queue.\n\r");
danilob 0:8b473c4a0afc 163
danilob 0:8b473c4a0afc 164 printf("%lf\n\r", queue_pop(&q));
danilob 0:8b473c4a0afc 165 printf("%lf\n\r", queue_pop(&q));
danilob 0:8b473c4a0afc 166 printf("%lf\n\r", queue_pop(&q));
danilob 0:8b473c4a0afc 167
danilob 0:8b473c4a0afc 168 queue_overwritePush(&q,7);
danilob 0:8b473c4a0afc 169 queue_overwritePush(&q,8);
danilob 0:8b473c4a0afc 170 queue_overwritePush(&q,9);
danilob 0:8b473c4a0afc 171 queue_overwritePush(&q,10);
danilob 0:8b473c4a0afc 172 queue_overwritePush(&q,11);
danilob 0:8b473c4a0afc 173
danilob 0:8b473c4a0afc 174 printf("printing contents of queue.\n\r");
danilob 0:8b473c4a0afc 175 queue_print(&q);
danilob 0:8b473c4a0afc 176 printf("done printing contents of queue.\n\r");
danilob 0:8b473c4a0afc 177
danilob 0:8b473c4a0afc 178 printf("%lf\n\r", queue_pop(&q));
danilob 0:8b473c4a0afc 179 printf("%lf\n\r",queue_readElementAt(&q, 3));
danilob 0:8b473c4a0afc 180 printf("%lf\n\r",queue_readElementAt(&q, 2));
danilob 0:8b473c4a0afc 181 printf("%lf\n\r",queue_readElementAt(&q, 1));
danilob 0:8b473c4a0afc 182 printf("%lf\n\r",queue_readElementAt(&q, 0));
danilob 0:8b473c4a0afc 183
danilob 0:8b473c4a0afc 184 printf("%lf\n\r", queue_pop(&q));
danilob 0:8b473c4a0afc 185
danilob 0:8b473c4a0afc 186 printf("%lf\n\r",queue_readElementAt(&q, 3));
danilob 0:8b473c4a0afc 187 printf("%lf\n\r",queue_readElementAt(&q, 2));
danilob 0:8b473c4a0afc 188 printf("%lf\n\r",queue_readElementAt(&q, 1));
danilob 0:8b473c4a0afc 189 printf("%lf\n\r",queue_readElementAt(&q, 0));
danilob 0:8b473c4a0afc 190
danilob 0:8b473c4a0afc 191 printf("done testing queue working!.\n\r");
danilob 0:8b473c4a0afc 192 return 1;
danilob 0:8b473c4a0afc 193 }
danilob 0:8b473c4a0afc 194 // Just free the malloc'd storage.
danilob 0:8b473c4a0afc 195 void gueue_garbageCollect(queue_t* q)
danilob 0:8b473c4a0afc 196 {
danilob 0:8b473c4a0afc 197 free(q->data);
danilob 0:8b473c4a0afc 198 }