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

Reply via email to