1 /* Licensed to the Apache Software Foundation (ASF) under one or more 2 * contributor license agreements. See the NOTICE file distributed with 3 * this work for additional information regarding copyright ownership. 4 * The ASF licenses this file to you under the Apache License, Version 2.0 5 * (the "License"); you may not use this file except in compliance with 6 * the License. You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 /** 18 * @class 19 * @name _Queue 20 * @memberOf myfaces._impl._util 21 * @description Queue implementation used by our runtime system 22 * improved version of 23 * @see <a href="http://safalra.com/web-design/javascript/queues/Queue.js">http://safalra.com/web-design/javascript/queues/Queue.js</a> 24 */ 25 _MF_CLS(_PFX_UTIL+"_Queue", _MF_OBJECT, 26 /** 27 * @lends myfaces._impl._util._Queue.prototype 28 */ 29 { 30 //faster queue by http://safalra.com/web-design/javascript/queues/Queue.js 31 //license public domain 32 //The trick is to simply reduce the number of slice and slice ops to a bare minimum. 33 34 _q : null, 35 _space : 0, 36 _size: -1, 37 38 /** 39 * Standard constructor 40 */ 41 constructor_: function() { 42 this._callSuper("constructor_"); 43 this._q = []; 44 }, 45 46 /** 47 * @return the length of the queue as integer 48 */ 49 length: function() { 50 // return the number of elements in the queue 51 return this._q.length - this._space; 52 53 }, 54 55 /** 56 * @return true if the current queue is empty false otherwise 57 */ 58 isEmpty: function() { 59 // return true if the queue is empty, and false otherwise 60 return (this._q.length == 0); 61 }, 62 63 /** 64 * Sets the current queue to a new size, all overflow elements at the end are stripped 65 * automatically 66 * 67 * @param {int} newSize as numeric value 68 */ 69 setQueueSize: function(newSize) { 70 this._size = newSize; 71 this._readjust(); 72 }, 73 74 /** 75 * adds a listener to the queue 76 * 77 * @param element the listener to be added 78 */ 79 enqueue : function(/*function*/element) { 80 this._q.push(element); 81 //qeuesize is bigger than the limit we drop one element so that we are 82 //back in line 83 84 this._readjust(); 85 }, 86 87 _readjust: function() { 88 var size = this._size; 89 while (size && size > -1 && this.length() > size) { 90 this.dequeue(); 91 } 92 }, 93 94 /** 95 * removes a listener form the queue 96 * 97 * @param element the listener to be removed 98 */ 99 remove : function(/*function*/element) { 100 /*find element in queue*/ 101 var index = this.indexOf(element); 102 /*found*/ 103 if (index != -1) { 104 this._q.splice(index, 1); 105 } 106 }, 107 108 /** 109 * dequeues the last element in the queue 110 * @return {Object} element which is dequeued 111 */ 112 dequeue: function() { 113 // initialise the element to return to be undefined 114 var element = null; 115 116 // check whether the queue is empty 117 var qLen = this._q.length; 118 var queue = this._q; 119 120 if (qLen) { 121 122 // fetch the oldest element in the queue 123 element = queue[this._space]; 124 125 // update the amount of space and check whether a shift should occur 126 //added here a max limit of 30 127 //now bit shift left is a tad faster than multiplication on most vms and does the same 128 //unless we run into a bit skipping which is impossible in our usecases here 129 if ((++this._space) << 1 >= qLen) { 130 131 // set the queue equal to the non-empty portion of the queue 132 this._q = queue.slice(this._space); 133 134 // reset the amount of space at the front of the queue 135 this._space = 0; 136 137 } 138 139 } 140 141 // return the removed element 142 return element; 143 }, 144 145 /** 146 * simple foreach 147 * 148 * @param closure a closure which processes the element 149 * @code 150 * queue.each(function(element) { 151 * //do something with the element 152 * }); 153 */ 154 each: function(closure) { 155 this._Lang.arrForEach(this._q, closure, this._space); 156 }, 157 158 /** 159 * Simple filter 160 * 161 * @param closure a closure which returns true or false depending 162 * whether the filter has triggered 163 * 164 * @return an array of filtered queue entries 165 */ 166 arrFilter: function(closure) { 167 return this._Lang.arrFilter(this._q, closure, this._space); 168 }, 169 170 /** 171 * @param element 172 * @return the current index of the element in the queue or -1 if it is not found 173 */ 174 indexOf: function(element) { 175 return this._Lang.arrIndexOf(this._q, element); 176 }, 177 178 /** 179 * resets the queue to initial empty state 180 */ 181 cleanup: function() { 182 this._q = []; 183 this._space = 0; 184 } 185 }); 186 187