This shows you the differences between two versions of the page.
Next revision | Previous revision | ||
haas:fall2015:data:projects:dlq0 [2015/04/29 18:48] – external edit 127.0.0.1 | haas:fall2015:data:projects:dlq0 [2015/11/16 14:10] (current) – [Queue library unit tests] wedge | ||
---|---|---|---|
Line 11: | Line 11: | ||
This section will document any updates applied to the project since original release: | This section will document any updates applied to the project since original release: | ||
- | * __revision | + | * __revision |
- | * lacking a leading ' | + | |
- | * also, a few erroneous mentions of " | + | |
- | * __revision 2__: typo in unit-purge (20150427) | + | |
- | * " | + | |
- | * __revision 3__: typo in unit-dequeue (20150429) | + | |
- | * unit-dequeue was dequeueing backwards (FIXED) | + | |
=====Objective===== | =====Objective===== | ||
Line 24: | Line 17: | ||
=====Background===== | =====Background===== | ||
- | A **queue** is considered one of the most important data structures, along with **stack** (last week's project) | + | A **queue** is considered one of the most important data structures, along with **stack** (last week's project), trees, and hash tables. And it is largely because of how often we find them playing out in nature or in our day-to-day lives. |
- | The word " | + | The word "**queue**" is [[https:// |
* (generically): | * (generically): | ||
Line 37: | Line 30: | ||
Therefore, a queue is a data structure that stores its data in a list (which consists of nodes), and we apply various rules/ | Therefore, a queue is a data structure that stores its data in a list (which consists of nodes), and we apply various rules/ | ||
- | The concept of restricting access is a very important one- which we did with our list as well (limiting our access to the list through the use of **append()**, | + | The concept of restricting access is a very important one- which we did with our list as well (limiting our access to the list through the use of **append()**, |
* __error reduction__: | * __error reduction__: | ||
Line 47: | Line 40: | ||
Although we've commonly viewed lists horizontally (from left to right), there is absolutely nothing requiring this positional orientation. | Although we've commonly viewed lists horizontally (from left to right), there is absolutely nothing requiring this positional orientation. | ||
- | Similarly, queues possess no mandatory orientation, | + | Similarly, queues possess no mandatory orientation, |
====the queue==== | ====the queue==== | ||
The queue data structure presents certain advantages that encourages its use in solving problems (why is the notion of forming lines important? What problems does that solve? How are resources more efficiently utilized by this act?), and we accomplish that by its compositional definition: | The queue data structure presents certain advantages that encourages its use in solving problems (why is the notion of forming lines important? What problems does that solve? How are resources more efficiently utilized by this act?), and we accomplish that by its compositional definition: | ||
- | * a queue has a **back** and a **front**, basically node pointers that constantly point to the back and front node in the queue (equivalent to the underlying list' | + | * a queue has a **back** and a **front**, basically node pointers that constantly point to the back and front node in the queue (equivalent to the underlying list' |
* to put an item on the queue, we **enqueue** it (place it at the back of the queue). So one of the functions we'll be implementing is **enqueue()**, | * to put an item on the queue, we **enqueue** it (place it at the back of the queue). So one of the functions we'll be implementing is **enqueue()**, | ||
- | * to get an item off of the queue, we **dequeue** it. In our **dequeue()** function, we grab the **front** node off the stack (this also translates into a set of list-level transactions that our **dequeue()** function will handle for us). | + | * to get an item off of the queue, we **dequeue** it. In our **dequeue()** function, we grab the **front** node off the queue (this also translates into a set of list-level transactions that our **dequeue()** function will handle for us). |
These qualities cause the queue to be described as a FIFO (or LILO) structure: | These qualities cause the queue to be described as a FIFO (or LILO) structure: | ||
Line 60: | Line 53: | ||
* **LILO**: **L**ast **I**n **L**ast **O**ut | * **LILO**: **L**ast **I**n **L**ast **O**ut | ||
- | And that describes what is conceptually going on-- if we can ONLY put our data on at one end (the back), and grab our data from the other (the front), the data most immediately available to us is that which we placed there first (hence the first one we pushed in would be the first one we get back when dequeueing | + | And that describes what is conceptually going on-- if we can ONLY put our data on at one end (the back), and grab our data from the other (the front), the data most immediately available to us is that which we placed there first (hence the first one we enqueued |
This concept is very important, and being aware of it can be of significant strategic importance when going about solving problems (and seeing its pattern proliferate in nature). | This concept is very important, and being aware of it can be of significant strategic importance when going about solving problems (and seeing its pattern proliferate in nature). | ||
- | With that said, the existence of **front**, **back**, along with the core **enqueue()** and **dequeue()** functions defines the minimal necessary | + | With that said, the existence of **front**, **back**, along with the core **enqueue()** and **dequeue()** functions defines the minimal necessary |
* **purge**: a way to quickly empty out a queue (evacuate its contents-- note this is partially similar in nature to what our **rmqueue()** function will do; only we won't take it the extra step of de-allocating and NULLifying the queue pointer). | * **purge**: a way to quickly empty out a queue (evacuate its contents-- note this is partially similar in nature to what our **rmqueue()** function will do; only we won't take it the extra step of de-allocating and NULLifying the queue pointer). | ||
Line 72: | Line 65: | ||
Their inclusion should ONLY be viewed as a means of convenience (in certain scenarios they may result in less code needing to be written), but NOT as something you should routinely make use of. | Their inclusion should ONLY be viewed as a means of convenience (in certain scenarios they may result in less code needing to be written), but NOT as something you should routinely make use of. | ||
+ | |||
====buffer size can matter==== | ====buffer size can matter==== | ||
Line 94: | Line 88: | ||
<code c> | <code c> | ||
- | // Status codes for the queue implementation | + | ////////////////////////////////////////////////////////////////////// |
// | // | ||
- | # | + | // Status codes for the doubly linked queue implementation |
- | # | + | // |
- | # | + | # |
- | # | + | # |
- | # | + | # |
- | # | + | # |
- | # | + | # |
- | # | + | # |
+ | # | ||
+ | # | ||
+ | # | ||
</ | </ | ||
- | |||
- | You may notice that they equate to the same numerical values as the stack; that is because, for the purposes of our stack and queue implementations, | ||
====In inc/ | ====In inc/ | ||
Line 114: | Line 109: | ||
#define _QUEUE_H | #define _QUEUE_H | ||
- | #include "data.h" | + | ////////////////////////////////////////////////////////////////////// |
- | #include " | + | // |
- | // (which relies on node) | + | // Queue relies on list (which relies on node) to work. |
+ | // | ||
+ | #include " | ||
+ | |||
+ | ////////////////////////////////////////////////////////////////////// | ||
+ | // | ||
+ | // Define the queue struct | ||
+ | // | ||
struct queue { | struct queue { | ||
- | | + | |
- | Node *front; // pointer to node at front of queue | + | Node *back; // pointer to back of queue |
- | | + | |
- | | + | |
}; | }; | ||
- | typedef struct queue Queue; | ||
- | code_t mkqueue(Queue **, uli ); // create new queue (of max size) | + | code_t |
- | code_t cpqueue(Queue | + | code_t |
- | code_t rmqueue(Queue ** ); // clear and de-allocate a queue | + | code_t |
- | code_t purge (Queue ** ); // clear and de-allocate | + | code_t |
- | code_t enqueue(Queue **, Node * ); // add new node to the back of queue | + | code_t |
- | code_t dequeue(Queue **, Node ** ); // take off node at front of queue | + | code_t |
#endif | #endif | ||
</ | </ | ||
- | For our queue implementation, | + | For our queue implementation, |
- | This is necessary so that we can free up the return value of **enqueue()** and **dequeue()** to be used for status (ie look out for buffer overruns and underruns). | + | This is necessary so that we can free up the return value of **enqueue()** and **dequeue()** to be used for status |
Also, while nothing is stopping you from doing so, the idea here is that things like **buffer** and the underlying list **qty** in queue transactions will **NOT** be accessed outside of the **enqueue()** and **dequeue()** functions. Just like my warnings about using **qty** in your list solutions (save for **display()** when showing position values in a backwards orientation)-- do not consider **buffer** as a variable for your general use. | Also, while nothing is stopping you from doing so, the idea here is that things like **buffer** and the underlying list **qty** in queue transactions will **NOT** be accessed outside of the **enqueue()** and **dequeue()** functions. Just like my warnings about using **qty** in your list solutions (save for **display()** when showing position values in a backwards orientation)-- do not consider **buffer** as a variable for your general use. | ||
Line 151: | Line 152: | ||
Again, your queue is to utilize the list for its underlying data storage operations. This is what the queue' | Again, your queue is to utilize the list for its underlying data storage operations. This is what the queue' | ||
- | |||
- | ====Reference Implementation==== | ||
- | As the layers and complexities rise, narrowing down the source of errors becomes increasingly important. | ||
- | |||
- | If your stack push() isn't working, is it because of a problem in push()? Or might it be in an underlying list operation it relies upon? Or perhaps even the lowest-level node functions.. | ||
- | |||
- | To aid you in your development efforts, you now have the ability to import a functioning node and list implementation into your project for the purposes of testing your stack functionality. | ||
- | |||
- | This also provides another opportunity for those who have fallen behind to stay current, as they can work on this project without having needed to successfully get full list functionality. | ||
- | |||
- | ===Using the test reference implementation=== | ||
- | You'll notice that, upon running **make help** in the base-level Makefile, the following new options appear (about halfway in the middle): | ||
- | |||
- | <cli> | ||
- | ** ** | ||
- | ** make use-test-reference | ||
- | ** make use-your-own-code | ||
- | ** ** | ||
- | </ | ||
- | |||
- | In order to make use of it, you'll need to run **make use-test-reference** from the base of your **dlq0** project directory, as follows: | ||
- | |||
- | <cli> | ||
- | lab46: | ||
- | ... | ||
- | NODE and LIST reference implementation in place, run ' | ||
- | lab46: | ||
- | </ | ||
- | |||
- | You'll see that final message indicating everything is in place (it automatically runs a **make clean** for you), and then you can go ahead and build everything with it: | ||
- | |||
- | <cli> | ||
- | lab46: | ||
- | ... | ||
- | </ | ||
- | |||
- | **__Debugging__: | ||
- | |||
- | ===Reverting back to using your code=== | ||
- | If you were trying out the reference implementation to verify queue functionality, | ||
- | |||
- | <cli> | ||
- | lab46: | ||
- | Local node/list implementation restored, run 'make clean; make' to build everything. | ||
- | lab46: | ||
- | </ | ||
====Queue library unit tests==== | ====Queue library unit tests==== | ||
- | In **testing/queue/unit/**, you will find these files: | + | In **unit/queue/**, you will find these files: |
* **unit-mkqueue.c** - unit test for **mkqueue()** library function | * **unit-mkqueue.c** - unit test for **mkqueue()** library function | ||
- | * **unit-cpqueue.c** - unit test for **cpqueue()** library function | ||
- | * **unit-rmqueue.c** - unit test for **rmqueue()** library function | ||
* **unit-enqueue.c** - unit test for **enqueue()** library function | * **unit-enqueue.c** - unit test for **enqueue()** library function | ||
* **unit-dequeue.c** - unit test for **dequeue()** library function | * **unit-dequeue.c** - unit test for **dequeue()** library function | ||
+ | * **unit-cpqueue.c** - unit test for **cpqueue()** library function | ||
+ | * **unit-rmqueue.c** - unit test for **rmqueue()** library function | ||
* **unit-purge.c** | * **unit-purge.c** | ||
- | There are also corresponding **verify-FUNCTION.sh** scripts that will output a " | + | There are also corresponding **verify-FUNCTION.sh** scripts that will output a " |
These are complete runnable programs (when compiled, and linked against the queue library, which is all handled for you by the **Makefile** system in place). | These are complete runnable programs (when compiled, and linked against the queue library, which is all handled for you by the **Makefile** system in place). | ||
Line 223: | Line 178: | ||
* make sure you understand what is going on | * make sure you understand what is going on | ||
* ask questions to get clarification! | * ask questions to get clarification! | ||
- | |||
=====Expected Results===== | =====Expected Results===== | ||
Line 234: | Line 188: | ||
<cli> | <cli> | ||
- | lab46: | + | lab46: |
- | coming soon... | + | ====================================================== |
+ | = Verifying Doubly-Linked Queue Functionality | ||
+ | ====================================================== | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | ====================================================== | ||
+ | | ||
+ | ====================================================== | ||
lab46: | lab46: | ||
</ | </ | ||
- | =====Submission | + | =====Submission===== |
- | To be successful in this project, the following criteria must be met: | + | {{page> |
- | + | ||
- | * Project must be submit on time, by the posted deadline. | + | |
- | * Late submissions will lose 25% credit per day, with the submission window closing on the 4th day following the deadline. | + | |
- | * All code must compile cleanly (no warnings or errors) | + | |
- | * all requested functions must be implemented in the related library | + | |
- | * all requested functionality must conform to stated requirements (either on this project page or in comment banner in source code files themselves). | + | |
- | * Executed programs must display in a manner similar to provided output | + | |
- | * output formatted, where applicable, must match that of project requirements | + | |
- | * Processing must be correct based on input given and output requested | + | |
- | * Output, if applicable, must be correct based on values input | + | |
- | * Code must be nicely and consistently indented (you may use the **indent** tool) | + | |
- | * Code must be commented | + | |
- | * Any "to be implemented" | + | |
- | * these "to be implemented" | + | |
- | * Sufficient comments explaining the point of provided logic **MUST** be present | + | |
- | * Track/ | + | |
- | * Submit a copy of your source code to me using the **submit** tool (**make submit** will do this) by the deadline. | + | |