Author: rjung Date: Fri Oct 29 17:41:05 2010 New Revision: 1028861 URL: http://svn.apache.org/viewvc?rev=1028861&view=rev Log: Improve Jsp limiter:
- Under high load entries removed from the jspQueue were already re-added via moveFirst by some other concurrent request, before the JspWrapper was unregistered. Add "valid" field to the Entry object to mark as invalid during removal. - Improve comment about thread-safetyness and add comment about the new "valid" field. - Add new getSize(). Will be used soon. - Reorder getters and setters of Entry. Modified: tomcat/trunk/java/org/apache/jasper/util/FastRemovalDequeue.java Modified: tomcat/trunk/java/org/apache/jasper/util/FastRemovalDequeue.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/jasper/util/FastRemovalDequeue.java?rev=1028861&r1=1028860&r2=1028861&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/jasper/util/FastRemovalDequeue.java (original) +++ tomcat/trunk/java/org/apache/jasper/util/FastRemovalDequeue.java Fri Oct 29 17:41:05 2010 @@ -29,6 +29,11 @@ package org.apache.jasper.util; * linked list, so that removal of an Entry does not need to search for it but * instead can be done in constant time. * + * The implementation is not thread-safe. Full synchronisation has to be provided + * externally. Invalidation of Entry objects during removal from the list is done + * by setting their valid field to false. All public methods which take Entry + * objects as arguments are NOP if the entry is no longer valid. + * * 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. * @@ -43,11 +48,25 @@ public class FastRemovalDequeue<T> { private Entry first; /** Last element of the queue. */ private Entry last; + /** Size of the queue */ + private int size; /** Initialize empty queue. */ public FastRemovalDequeue() { first = null; last = null; + size = 0; + } + + /** + * Retrieve the size of the list. + * This method also needs to be externaly synchronized to + * ensure correct publication of changes. + * + * @return the size of the list. + * */ + public int getSize() { + return size; } /** @@ -66,6 +85,7 @@ public class FastRemovalDequeue<T> { entry.setNext(first); first = entry; } + size++; return entry; } @@ -86,6 +106,7 @@ public class FastRemovalDequeue<T> { entry.setPrevious(last); last = entry; } + size++; return entry; } @@ -99,10 +120,12 @@ public class FastRemovalDequeue<T> { T content = null; if (first != null) { content = first.getContent(); + first.setValid(false); first = first.getNext(); if (first != null) { first.setPrevious(null); } + size--; } return content; } @@ -116,10 +139,12 @@ public class FastRemovalDequeue<T> { T content = null; if (last != null) { content = last.getContent(); + last.setValid(false); last = last.getPrevious(); if (last != null) { last.setNext(null); } + size--; } return content; } @@ -128,6 +153,9 @@ public class FastRemovalDequeue<T> { * Removes any element of the list and returns its content. **/ public void remove(final Entry element) { + if (!element.getValid()) { + return; + } Entry next = element.getNext(); Entry prev = element.getPrevious(); if (next != null) { @@ -140,6 +168,7 @@ public class FastRemovalDequeue<T> { } else { first = next; } + size--; } /** @@ -151,7 +180,8 @@ public class FastRemovalDequeue<T> { * @param element the entry to move in front. * */ public void moveFirst(final Entry element) { - if (element.getPrevious() != null) { + if (element.getValid() && + element.getPrevious() != null) { Entry prev = element.getPrevious(); Entry next = element.getNext(); prev.setNext(next); @@ -176,7 +206,8 @@ public class FastRemovalDequeue<T> { * @param element the entry to move to the back. * */ public void moveLast(final Entry element) { - if (element.getNext() != null) { + if (element.getValid() && + element.getNext() != null) { Entry next = element.getNext(); Entry prev = element.getPrevious(); next.setPrevious(prev); @@ -200,35 +231,45 @@ public class FastRemovalDequeue<T> { */ public class Entry { + /** Is this entry still valid? */ + private boolean valid = true; /** The content this entry is valid for. */ private final T content; /** Pointer to next element in queue. */ - private Entry next; + private Entry next = null; /** Pointer to previous element in queue. */ - private Entry previous; + private Entry previous = null; private Entry(T object) { content = object; } - private final void setNext(final Entry next) { - this.next = next; + private final boolean getValid() { + return valid; } - private final void setPrevious(final Entry previous) { - this.previous = previous; + private final void setValid(final boolean valid) { + this.valid = valid; } private final T getContent() { return content; } + private final Entry getNext() { + return next; + } + + private final void setNext(final Entry next) { + this.next = next; + } + private final Entry getPrevious() { return previous; } - private final Entry getNext() { - return next; + private final void setPrevious(final Entry previous) { + this.previous = previous; } @Override --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org