From: rjung Date: Thu, 28 Oct 2010 16:27:31 +0000 (+0000) Subject: Overhaul JspQueue, no functional change for Jasper. X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=72443ba50174b36da5f0216fa93894938ecfdc11;p=tomcat7.0 Overhaul JspQueue, no functional change for Jasper. - Rename class to FastRemovalDequeue, because it can be used gnerally. Nothing jsp related in it. - Rename "head" to "first" as a better match for the existing "last" - Switch previous and next: "previous" was pointing from first to last, "next" from last to first. Mind-bending. - Add a bit to the description. Remove "ticket" language. - Use more standard terminology "push" to insert in front and "pop" to remove from last - Add methods shift and unshift for the operations at the other ends. Not used yet. - Add remove() method (not used yet). - Rename makeYoungest() to moveFirst() and add moveLast() (not used yet). This data structure doesn't actually know about young or old. Add "Entry-" prefix to Entry.toString(). Rename makeFirst() in JspRuntimeContext to makeYoungest(), because there we actually are using timestamp information. git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@1028377 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/java/org/apache/jasper/compiler/JspRuntimeContext.java b/java/org/apache/jasper/compiler/JspRuntimeContext.java index 429263d27..94347214b 100644 --- a/java/org/apache/jasper/compiler/JspRuntimeContext.java +++ b/java/org/apache/jasper/compiler/JspRuntimeContext.java @@ -41,7 +41,7 @@ import org.apache.jasper.runtime.JspFactoryImpl; import org.apache.jasper.security.SecurityClassLoad; import org.apache.jasper.servlet.JspServletWrapper; import org.apache.jasper.util.ExceptionUtils; -import org.apache.jasper.util.JspQueue; +import org.apache.jasper.util.FastRemovalDequeue; import org.apache.juli.logging.Log; import org.apache.juli.logging.LogFactory; @@ -178,7 +178,7 @@ public final class JspRuntimeContext { /** * Keeps JSP pages ordered by last access. */ - private JspQueue jspQueue = new JspQueue(); + private FastRemovalDequeue jspQueue = new FastRemovalDequeue(); // ------------------------------------------------------ Public Methods @@ -229,9 +229,9 @@ public final class JspRuntimeContext { * * @param ticket the ticket for the jsp. * */ - public void makeFirst(org.apache.jasper.util.Entry ticket) { - synchronized( jspQueue ) { - jspQueue.makeYoungest(ticket); + public void makeYoungest(org.apache.jasper.util.Entry ticket) { + synchronized(jspQueue) { + jspQueue.moveFirst(ticket); } } @@ -505,7 +505,7 @@ public final class JspRuntimeContext { if( jsps.size() > maxLoadedJsps ) { synchronized( jsps ) { JspServletWrapper oldest; - synchronized( jspQueue) { + synchronized(jspQueue) { oldest = jspQueue.pop(); } if (oldest != null) { diff --git a/java/org/apache/jasper/servlet/JspServletWrapper.java b/java/org/apache/jasper/servlet/JspServletWrapper.java index 2f92446ba..96bc10051 100644 --- a/java/org/apache/jasper/servlet/JspServletWrapper.java +++ b/java/org/apache/jasper/servlet/JspServletWrapper.java @@ -391,7 +391,7 @@ public class JspServletWrapper { if (ticket == null) ticket = ctxt.getRuntimeContext().push(this); else - ctxt.getRuntimeContext().makeFirst(ticket); + ctxt.getRuntimeContext().makeYoungest(ticket); } } } catch (UnavailableException ex) { diff --git a/java/org/apache/jasper/util/Entry.java b/java/org/apache/jasper/util/Entry.java index 60d1d8e5e..31bb71b87 100644 --- a/java/org/apache/jasper/util/Entry.java +++ b/java/org/apache/jasper/util/Entry.java @@ -17,8 +17,8 @@ package org.apache.jasper.util; /** - * Implementation of a list entry. It exposes links to previous and next - * elements on package level only. + * Implementation of a doubly linked list entry. + * It exposes links to previous and next elements on package level only. */ public class Entry { @@ -55,6 +55,6 @@ public class Entry { @Override public String toString() { - return content.toString(); + return "Entry-" + content.toString(); } } diff --git a/java/org/apache/jasper/util/FastRemovalDequeue.java b/java/org/apache/jasper/util/FastRemovalDequeue.java new file mode 100644 index 000000000..b30597a6f --- /dev/null +++ b/java/org/apache/jasper/util/FastRemovalDequeue.java @@ -0,0 +1,195 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.jasper.util; + +/** + * + * The FastRemovalDequeue is a Dequeue that supports constant time removal of + * entries. This is achieved by using a doubly linked list and wrapping any object + * added to the collection with an Entry type, that is returned to the consumer. + * When removing an object from the list, the consumer provides this Entry object. + * + * The Entry type is mostly opaque to the consumer itself. The consumer can only + * retrieve the original object - named content - from the Entry. + * + * The Entry object contains the links pointing to the neighbours in the doubly + * linked list, so that removal of an Entry does not need to search for it but + * instead can be done in constant time. + * + * A typical use of the FastRemovalDequeue is a list of entries in sorted order, + * where the sort position of an object will only switch to first or last. + * + * Whenever the sort position needs to change, the consumer can remove the object + * and reinsert it in front or at the end in constant time. + * So keeping the list sorted is very cheap. + * + */ +public class FastRemovalDequeue { + + /** First element of the queue. */ + private Entry first; + /** Last element of the queue. */ + private Entry last; + + /** Initialize empty queue. */ + public FastRemovalDequeue() { + first = null; + last = null; + } + + /** + * Adds an object to the start of the list and returns the entry created for + * said object. The entry can later be reused for moving the entry. + * + * @param object the object to prepend to the start of the list. + * @return an entry for use when the object should be moved. + * */ + public Entry push(final T object) { + Entry entry = new Entry(object); + if (first == null) { + first = last = entry; + } else { + first.setPrevious(entry); + entry.setNext(first); + first = entry; + } + + return entry; + } + + /** + * Adds an object to the end of the list and returns the entry created for + * said object. The entry can later be reused for moving the entry. + * + * @param object the object to append to the end of the list. + * @return an entry for use when the object should be moved. + * */ + public Entry unpop(final T object) { + Entry entry = new Entry(object); + if (first == null) { + first = last = entry; + } else { + last.setNext(entry); + entry.setPrevious(last); + last = entry; + } + + return entry; + } + + /** + * Removes the first element of the list and returns its content. + * + * @return the content of the first element of the list. + **/ + public T unpush() { + T content = null; + if (first != null) { + content = first.getContent(); + first = first.getNext(); + if (first != null) { + first.setPrevious(null); + } + } + return content; + } + + /** + * Removes the last element of the list and returns its content. + * + * @return the content of the last element of the list. + **/ + public T pop() { + T content = null; + if (last != null) { + content = last.getContent(); + last = last.getPrevious(); + if (last != null) { + last.setNext(null); + } + } + return content; + } + + /** + * Removes any element of the list and returns its content. + **/ + public void remove(final Entry element) { + Entry next = element.getNext(); + Entry prev = element.getPrevious(); + if (next != null) { + next.setPrevious(prev); + } else { + last = prev; + } + if (prev != null) { + prev.setNext(next); + } else { + first = next; + } + } + + /** + * Moves the element in front. + * + * Could also be implemented as remove() and + * push(), but explicitely coding might be a bit faster. + * + * @param element the entry to move in front. + * */ + public void moveFirst(final Entry element) { + if (element.getPrevious() != null) { + Entry prev = element.getPrevious(); + Entry next = element.getNext(); + prev.setNext(next); + if (next != null) { + next.setPrevious(prev); + } else { + last = prev; + } + first.setPrevious(element); + element.setNext(first); + element.setPrevious(null); + first = element; + } + } + + /** + * Moves the element to the back. + * + * Could also be implemented as remove() and + * unpop(), but explicitely coding might be a bit faster. + * + * @param element the entry to move to the back. + * */ + public void moveLast(final Entry element) { + if (element.getNext() != null) { + Entry next = element.getNext(); + Entry prev = element.getPrevious(); + next.setPrevious(prev); + if (prev != null) { + prev.setNext(next); + } else { + first = next; + } + last.setNext(element); + element.setPrevious(last); + element.setNext(null); + last = element; + } + } +} diff --git a/java/org/apache/jasper/util/JspQueue.java b/java/org/apache/jasper/util/JspQueue.java deleted file mode 100644 index 3a8a65b94..000000000 --- a/java/org/apache/jasper/util/JspQueue.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.jasper.util; - -/** - * - * The JspQueue is supposed to hold a set of instances in sorted order. Sorting - * order is determined by the instances' content. As this content may change - * during instance lifetime, the Queue must be cheap to update - ideally in - * constant time. - * - * Access to the first element in the queue must happen in constant time. - * - * Only a minimal set of operations is implemented. - */ -public class JspQueue { - - /** Head of the queue. */ - private Entry head; - /** Last element of the queue. */ - private Entry last; - - /** Initialize empty queue. */ - public JspQueue() { - head = null; - last = null; - } - - /** - * Adds an object to the end of the queue and returns the entry created for - * said object. The entry can later be reused for moving the entry back to - * the front of the list. - * - * @param object - * the object to append to the end of the list. - * @return a ticket for use when the object should be moved back to the - * front. - * */ - public Entry push(final T object) { - Entry entry = new Entry(object); - if (head == null) { - head = last = entry; - } else { - last.setPrevious(entry); - entry.setNext(last); - last = entry; - } - - return entry; - } - - /** - * Removes the head of the queue and returns its content. - * - * @return the content of the head of the queue. - **/ - public T pop() { - T content = null; - if (head != null) { - content = head.getContent(); - if (head.getPrevious() != null) - head.getPrevious().setNext(null); - head = head.getPrevious(); - } - return content; - } - - /** - * Moves the candidate to the front of the queue. - * - * @param candidate - * the entry to move to the front of the queue. - * */ - public void makeYoungest(final Entry candidate) { - if (candidate.getPrevious() != null) { - Entry candidateNext = candidate.getNext(); - Entry candidatePrev = candidate.getPrevious(); - candidatePrev.setNext(candidateNext); - if (candidateNext != null) - candidateNext.setPrevious(candidatePrev); - else - head = candidatePrev; - candidate.setNext(last); - candidate.setPrevious(null); - last.setPrevious(candidate); - last = candidate; - } - } -}