Skip to content

Commit

Permalink
Queue: Complere the refined implementation, unit test, and demo program.
Browse files Browse the repository at this point in the history
  • Loading branch information
ZSShen committed Sep 24, 2016
1 parent 0efc0d0 commit 5b4712b
Show file tree
Hide file tree
Showing 4 changed files with 471 additions and 428 deletions.
144 changes: 82 additions & 62 deletions demo/demo_queue.c
Original file line number Diff line number Diff line change
@@ -1,74 +1,94 @@
#include "cds.h"


typedef struct Employ_ {
int8_t cYear;
int8_t cLevel;
int32_t iId;
} Employ;
typedef struct Tuple_ {
int first;
int second;
} Tuple;


void DestroyObject(Item item)
void CleanObject(void* element)
{
free((Employ*)item);
free(element);
}


void ManipulateNumerics()
{
/* We should initialize the container before any operations. */
Queue* queue = QueueInit();

/* Push numeric elements to the queue. */
QueuePush(queue, (void*)(intptr_t)1);
QueuePush(queue, (void*)(intptr_t)2);
QueuePush(queue, (void*)(intptr_t)3);
QueuePush(queue, (void*)(intptr_t)4);

/* Check the element order. */
void* element;
QueueFront(queue, &element);
assert((int)(intptr_t)element == 1);

QueueBack(queue, &element);
assert((int)(intptr_t)element == 4);

/* Pop elements from the queue*/
QueuePop(queue);
QueuePop(queue);

/* Check the number of stored elements. */
assert(QueueSize(queue) == 2);

QueueDeinit(queue);
}

void ManipulateObjects()
{
/* We should initialize the container before any operations. */
Queue* queue = QueueInit();
QueueSetClean(queue, CleanObject);

/* Push numeric elements to the queue. */
Tuple* tuple = (Tuple*)malloc(sizeof(Tuple));
tuple->first = 1;
tuple->second = -1;
QueuePush(queue, tuple);

tuple = (Tuple*)malloc(sizeof(Tuple));
tuple->first = 2;
tuple->second = -2;
QueuePush(queue, tuple);

tuple = (Tuple*)malloc(sizeof(Tuple));
tuple->first = 3;
tuple->second = -3;
QueuePush(queue, tuple);

tuple = (Tuple*)malloc(sizeof(Tuple));
tuple->first = 4;
tuple->second = -4;
QueuePush(queue, tuple);

/* Check the element order. */
void* element;
QueueFront(queue, &element);
assert(((Tuple*)element)->first == 1);
QueueBack(queue, &element);
assert(((Tuple*)element)->first == 4);

/* Pop elements from the queue*/
QueuePop(queue);
QueuePop(queue);

/* Check the number of stored elements. */
assert(QueueSize(queue) == 2);

QueueDeinit(queue);
}

int main()
{
Queue *pQueue;

/* You should initialize the DS before any operations. */
int32_t iRtnCode = QueueInit(&pQueue);
if (iRtnCode != SUCC)
return iRtnCode;

/* If you plan to delegate the resource clean task to the DS, please set the
custom clean method. */
pQueue->set_destroy(pQueue, DestroyObject);

/* Push items onto the queue. */
Employ *pEmploy = (Employ*)malloc(sizeof(Employ));
pEmploy->iId = 4;
pEmploy->cLevel = 4;
pEmploy->cYear = 4;
pQueue->push(pQueue, (Item)pEmploy);

pEmploy = (Employ*)malloc(sizeof(Employ));
pEmploy->iId = 3;
pEmploy->cLevel = 3;
pEmploy->cYear = 3;
pQueue->push(pQueue, (Item)pEmploy);

pEmploy = (Employ*)malloc(sizeof(Employ));
pEmploy->iId = 2;
pEmploy->cLevel = 2;
pEmploy->cYear = 2;
pQueue->push(pQueue, (Item)pEmploy);

pEmploy = (Employ*)malloc(sizeof(Employ));
pEmploy->iId = 1;
pEmploy->cLevel = 1;
pEmploy->cYear = 1;
pQueue->push(pQueue, (Item)pEmploy);

/* Check the queue order. */
Item item;
pQueue->front(pQueue, &item);
assert(((Employ*)item)->cLevel == 4);
pQueue->back(pQueue, &item);
assert(((Employ*)item)->cLevel == 1);

/* Pop items from the queue */
pQueue->pop(pQueue);
pQueue->pop(pQueue);

/* Check the number of stored items. */
int32_t iSize = pQueue->size(pQueue);
assert(iSize == 2);

/* You should deinitialize the DS after all the relevant tasks. */
QueueDeinit(&pQueue);

return SUCC;
ManipulateNumerics();
ManipulateObjects();
return 0;
}
149 changes: 75 additions & 74 deletions include/container/queue.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,27 @@
/**
* The MIT License (MIT)
* Copyright (C) 2016 ZongXian Shen <andy.zsshen@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/


/**
* @file queue.h The FIFO queue.
*/
Expand All @@ -14,34 +38,38 @@ extern "C" {
/** QueueData is the data type for the container private information. */
typedef struct _QueueData QueueData;

/** Element clean function called when an element is removed. */
typedef void (*QueueClean) (void*);


/** The implementation for queue. */
typedef struct _Queue {
/** The container private information */
QueueData *pData;
QueueData *data;

/** Insert an item to the tail of the queue.
/** Push an element to the tail of the queue.
@see QueuePush */
int32_t (*push) (struct _Queue*, Item);
bool (*push) (struct _Queue*, void*);

/** Retrieve item from the head of the queue.
/** Retrieve an element from the head of the queue.
@see QueueFront */
int32_t (*front) (struct _Queue*, Item*);
bool (*front) (struct _Queue*, void**);

/** Retrieve item from the tail of the queue.
/** Retrieve an element from the tail of the queue.
@see QueueBack */
int32_t (*back) (struct _Queue*, Item*);
bool (*back) (struct _Queue*, void**);

/** Delete an item from the head of the queue.
/** Remove an element from the head of the queue.
@see QueuePop */
int32_t (*pop) (struct _Queue*);
bool (*pop) (struct _Queue*);

/** Return the number of stored items.
/** Return the number of stored elements.
@see QueueSize */
int32_t (*size) (struct _Queue*);
unsigned (*size) (struct _Queue*);

/** Set the custom item resource clean method.
/** Set the custom element cleanup function.
@see QueueSetDestroy */
int32_t (*set_destroy) (struct _Queue*, void (*) (Item));
void (*set_clean) (struct _Queue*, QueueClean func);
} Queue;


Expand All @@ -51,107 +79,80 @@ typedef struct _Queue {
/**
* @brief The constructor for Queue.
*
* @param ppObj The double pointer to the to be constructed queue
*
* @retval SUCC
* @retval ERR_NOMEM Insufficient memory for queue construction
* @retval obj The successfully constructed queue
* @retval NULL Insufficient memory for queue construction
*/
int32_t QueueInit(Queue **ppObj);
Queue* QueueInit();

/**
* @brief The destructor for Queue.
*
* If the custom resource clean method is set, it also runs the clean method
* for all the items.
*
* @param ppObj The double pointer to the to be destructed queue
* @param obj The pointer to the to be destructed queue
*/
void QueueDeinit(Queue **ppObj);
void QueueDeinit(Queue* obj);

/**
* @brief Insert an item to the tail of the queue.
*
* This function inserts an item to the tail of the queue with the corresponding
* queue size extension.
* @brief Push an element to the tail of the queue.
*
* @param self The pointer to Queue structure
* @param item The designated item
* @param element The specified element
*
* @retval SUCC
* @retval ERR_NOINIT Uninitialized container
* @retval ERR_NOMEM Insufficient memory for queue extension
* @retval true The element is successfully pushed
* @retval false The element cannot be pushed due to insufficient memory
*/
int32_t QueuePush(Queue *self, Item item);
bool QueuePush(Queue* self, void* element);

/**
* @brief Delete item from top of the queue.
*
* This function deletes item from top of the queue. If the custom resource clean
* method is set, it also runs the clean method for the deleted item.
* @brief Retrieve an element from the head of the queue.
*
* @param self The pointer to Queue structure
* @param self The pointer to PriorityQueue structure
* @param p_element The pointer to the returned element
*
* @retval SUCC
* @retval ERR_NOINIT Uninitialized container
* @retval ERR_IDX Empty queue
* @retval true The head element is successfully retrieved
* @retval false The queue is empty
*/
int32_t QueuePop(Queue *self);
bool QueueFront(Queue* self, void** p_element);

/**
* @brief Retrieve item from the head of the queue.
* @brief Retrieve an element from the tail of the queue.
*
* This function retrieves item from the head of the queue. If the queue is not
* empty, the item is returned by the second parameter. Otherwise, the error
* code is returned and the second parameter is updated with NULL.
* @param self The pointer to PriorityQueue structure
* @param p_element The pointer to the returned element
*
* @param self The pointer to Queue structure
* @param pItem The pointer to the returned item
*
* @retval SUCC
* @retval ERR_NOINIT Uninitialized container
* @retval ERR_IDX Empty queue
* @retval ERR_GET Invalid parameter to store returned item
* @retval true The tail element is successfully retrieved
* @retval false The queue is empty
*/
int32_t QueueFront(Queue *self, Item *pItem);
bool QueueBack(Queue* self, void** p_element);

/**
* @brief Retrieve item from the tail of the queue.
* @brief Remove an element from the head of the queue.
*
* This function retrieves item from the tail of the queue. If the queue is not
* empty, the item is returned by the second parameter. Otherwise, the error
* code is returned and the second parameter is updated with NULL.
* This function removes an element from the head of the queue. Also, the cleanup
* function is invoked for the removed element.
*
* @param self The pointer to Queue structure
* @param pItem The pointer to the returned item
*
* @retval SUCC
* @retval ERR_NOINIT Uninitialized container
* @retval ERR_IDX Empty queue
* @retval ERR_GET Invalid parameter to store returned item
* @retval true The top element is successfully removed
* @retval false The queue is empty
*/
int32_t QueueBack(Queue *self, Item *pItem);

bool QueuePop(Queue* self);

/**
* @brief Return the number of stored items.
* @brief Return the number of stored elements.
*
* @param self The pointer to Queue structure
*
* @return The number of items
* @retval ERR_NOINIT Uninitialized container
* @retval size The number of stored elements
*/
int32_t QueueSize(Queue *self);
unsigned QueueSize(Queue* self);

/**
* @brief Set the custom item resource clean method.
* @brief Set the custom element cleanup function.
*
* @param self The pointer to Queue structure
* @param pFunc The function pointer to the custom method
*
* @retval SUCC
* @retval ERR_NOINIT Uninitialized container
* @param func The custom function
*/
int32_t QueueSetDestroy(Queue *self, void (*pFunc) (Item));
void QueueSetClean(Queue* self, QueueClean func);

#ifdef __cplusplus
}
Expand Down
Loading

0 comments on commit 5b4712b

Please sign in to comment.