      1 var define = require("../define").define,
      2         Collection = require("./Collection"),
      3         base = require("../base");
      4
      5 /**
      6  * @class <p>FIFO Data structure</p>
      7  * @name Queue
      8  * @augments comb.collections.Collection
      9  * @memberOf comb.collections
     10  *
     11  * @property {Number} count the current number of elements in this queue
     12  * @property {Boolean} isEmpty true if this queue is empty
     13  * @property {Array} values a copy of the values contained in this queue
     14  */
     15 module.exports = exports = define(Collection, {
     16     instance : {
     17         /**@lends comb.collections.Queue.prototype*/
     18
     19         constructor : function() {
     20             this.__queue = [];
     21             this.__next = 0;
     22             this.__last = 0;
     23         },
     24
     25         /**
     26          * Add data to this queue
     27          * @param {*} data element to add
     28          */
     29         enqueue : function(data) {
     30             this.__queue[this.__last++] = data;
     31         },
     32
     33         /**
     34          * Removes first item from the head of the queue
     35          *
     36          * @return {*} The element removed from this queue. Returns undefined if the queue is empty.
     37          */
     38         dequeue : function() {
     39             var ret = undefined,next = this.__next, queue;
     40             if (next != this.__last) {
     41                 queue = this.__queue;
     42                 ret = queue[next];
     43                 queue[this.__next++] = undefined;
     44             }
     45             return ret;
     46         },
     47
     48         /**
     49          * Retrieves the item at the head of the queue without removing it
     50          *
     51          * @return {*} The element at the head of the queue. Returns undefined if the queue is empty.
     52          */
     53         peek : function() {
     54             var ret = undefined, next = this.__next;
     55             if (next != this.__last) {
     56                 ret = this.__queue[next];
     57             }
     58             return ret;
     59         },
     60
     61         /**
     62          * Removes all items from this queue
     63          */
     64         clear : function() {
     65             this.__queue.length = 0;
     66             this.__next = 0;
     67             this.__last = 0;
     68         },
     69
     70         /**
     71          * Determine if this queue contains the element
     72          * @param {*} obj the object to find
     73          *
     74          * @return {Boolean} true if this queue contains the element
     75          */
     76         contains : function(obj) {
     77             return this.__queue.indexOf(obj) != -1;
     78         },
     79         /**
     80          * Removes an element from this queue.
     81          * @param {*} obj the data to remove.
     82          *
     83          * @return {Boolean} true if the element was removed, false otherwise.
     84          */
     85         remove : function(obj) {
     86             var index = this.__queue.indexOf(obj), ret = false;
     87             if (index != -1) {
     88                 if (index == this.__next) {
     89                     this.dequeue();
     90                 } else {
     91                     this.__queue.splice(index, 1);
     92                     this.__last--;
     93                 }
     94                 ret = true;
     95             }
     96             return ret;
     97         },
     98
     99         getters : {
    100             count : function() {
    101                 return this.__last - this.__next;
    102             },
    103
    104             isEmpty : function() {
    105                 return this.__last - this.__next == 0;
    106             },
    107
    108             values : function() {
    109                 return this.__queue.slice(this.__next, this.__last);
    110             }
    111         }
    112     }
    113 });