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 myfaces._impl.core._Runtime.extendClass("myfaces._impl._util._Queue", 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._q = []; 43 this._Lang = myfaces._impl._util._Lang; 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 (null != size && 'undefined' != typeof size && 90 size > -1 && this.length() > size) { 91 this.dequeue(); 92 } 93 }, 94 95 /** 96 * removes a listener form the queue 97 * 98 * @param element the listener to be removed 99 */ 100 remove : function(/*function*/element) { 101 /*find element in queue*/ 102 var index = this.indexOf(element); 103 /*found*/ 104 if (index != -1) { 105 this._q.splice(index, 1); 106 } 107 }, 108 109 /** 110 * dequeues the last element in the queue 111 * @return {Object} element which is dequeued 112 */ 113 dequeue: function() { 114 // initialise the element to return to be undefined 115 var element = null; 116 117 // check whether the queue is empty 118 var qLen = this._q.length; 119 var queue = this._q; 120 121 if (qLen) { 122 123 // fetch the oldest element in the queue 124 element = queue[this._space]; 125 126 // update the amount of space and check whether a shift should occur 127 //added here a max limit of 30 128 //now bit shift left is a tad faster than multiplication on most vms and does the same 129 //unless we run into a bit skipping which is impossible in our usecases here 130 if ((++this._space) << 1 >= qLen) { 131 132 // set the queue equal to the non-empty portion of the queue 133 this._q = queue.slice(this._space); 134 135 // reset the amount of space at the front of the queue 136 this._space = 0; 137 138 } 139 140 } 141 142 // return the removed element 143 return element; 144 }, 145 146 /** 147 * simple foreach 148 * 149 * @param closure a closure which processes the element 150 * @code 151 * queue.each(function(element) { 152 * //do something with the element 153 * }); 154 */ 155 each: function(closure) { 156 this._Lang.arrForEach(this._q, closure, this._space); 157 }, 158 159 /** 160 * Simple filter 161 * 162 * @param closure a closure which returns true or false depending 163 * whether the filter has triggered 164 * 165 * @return an array of filtered queue entries 166 */ 167 arrFilter: function(closure) { 168 return this._Lang.arrFilter(this._q, closure, this._space); 169 }, 170 171 /** 172 * @param element 173 * @return the current index of the element in the queue or -1 if it is not found 174 */ 175 indexOf: function(element) { 176 return this._Lang.arrIndexOf(this._q, element); 177 }, 178 179 /** 180 * resets the queue to initial empty state 181 */ 182 cleanup: function() { 183 this._q = []; 184 this._space = 0; 185 } 186 }); 187 188