You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xerces.apache.org by mr...@apache.org on 2009/12/15 07:41:40 UTC

svn commit: r890668 - /xerces/java/branches/xml-schema-1.1-dev/src/org/apache/xerces/dom/DocumentImpl.java

Author: mrglavas
Date: Tue Dec 15 06:41:40 2009
New Revision: 890668

URL: http://svn.apache.org/viewvc?rev=890668&view=rev
Log:
JIRA Issue #1300: https://issues.apache.org/jira/browse/XERCESJ-1300. Use weak references for storing the Ranges so that they can be garbage collected if the application no longer has any references to them. Inspired by the patch by Ludger Bünger except that I used a LinkedList instead of a WeakHashMap due its good memory management when items are removed (and also good for bulk removals through its iterator).

Modified:
    xerces/java/branches/xml-schema-1.1-dev/src/org/apache/xerces/dom/DocumentImpl.java

Modified: xerces/java/branches/xml-schema-1.1-dev/src/org/apache/xerces/dom/DocumentImpl.java
URL: http://svn.apache.org/viewvc/xerces/java/branches/xml-schema-1.1-dev/src/org/apache/xerces/dom/DocumentImpl.java?rev=890668&r1=890667&r2=890668&view=diff
==============================================================================
--- xerces/java/branches/xml-schema-1.1-dev/src/org/apache/xerces/dom/DocumentImpl.java (original)
+++ xerces/java/branches/xml-schema-1.1-dev/src/org/apache/xerces/dom/DocumentImpl.java Tue Dec 15 06:41:40 2009
@@ -106,9 +106,11 @@
     /** Reference queue for cleared Node Iterator references */
     protected transient ReferenceQueue iteratorReferenceQueue;
 
-     /** Ranges */
-    // REVISIT: Should this be transient? -Ac
-    protected Vector ranges;
+    /** Ranges */
+    protected transient List ranges;
+    
+    /** Reference queue for cleared Range references */
+    protected transient ReferenceQueue rangeReferenceQueue;
 
     /** Table for event listeners registered to this document nodes. */
     protected Hashtable eventListeners;
@@ -316,18 +318,25 @@
     /**
      * Remove stale iterator references from the iterator list.
      */
-    void removeStaleIteratorReferences() {
-        Reference ref = iteratorReferenceQueue.poll();
+    private void removeStaleIteratorReferences() {
+        removeStaleReferences(iteratorReferenceQueue, iterators);
+    }
+    
+    /**
+     * Remove stale references from the given list.
+     */
+    private void removeStaleReferences(ReferenceQueue queue, List list) {
+        Reference ref = queue.poll();
         int count = 0;
         while (ref != null) {
             ++count;
-            ref = iteratorReferenceQueue.poll();
+            ref = queue.poll();
         }
         if (count > 0) {
-            Iterator i = iterators.iterator();
+            final Iterator i = list.iterator();
             while (i.hasNext()) {
-                Object iterator = ((Reference) i.next()).get();
-                if (iterator == null) {
+                Object o = ((Reference) i.next()).get();
+                if (o == null) {
                     i.remove();
                     if (--count <= 0) {
                         return;
@@ -345,17 +354,19 @@
     public Range createRange() {
 
         if (ranges == null) {
-            ranges = new Vector();
+            ranges = new LinkedList();
+            rangeReferenceQueue = new ReferenceQueue();
         }
 
         Range range = new RangeImpl(this);
 
-        ranges.addElement(range);
+        removeStaleRangeReferences();
+        ranges.add(new WeakReference(range, rangeReferenceQueue));
 
         return range;
 
     }
-
+    
     /** Not a client function. Called by Range.detach(),
      *  so a Range can remove itself from the list of
      *  Ranges.
@@ -365,7 +376,19 @@
         if (range == null) return;
         if (ranges == null) return;
 
-        ranges.removeElement(range);
+        removeStaleRangeReferences();
+        Iterator i = ranges.iterator();
+        while (i.hasNext()) {
+            Object otherRange = ((Reference) i.next()).get();
+            if (otherRange == range) {
+                i.remove();
+                return;
+            }
+            // Remove stale reference from the list.
+            else if (otherRange == null) {
+                i.remove();
+            } 
+        }
     }
 
     /**
@@ -380,9 +403,17 @@
     }
     
     private void notifyRangesReplacedText(CharacterDataImpl node) {
-        final int size = ranges.size();
-        for (int i = 0; i != size; i++) {
-            ((RangeImpl)ranges.elementAt(i)).receiveReplacedText(node);
+        removeStaleRangeReferences();
+        final Iterator i = ranges.iterator();
+        while (i.hasNext()) {
+            RangeImpl range = (RangeImpl) ((Reference) i.next()).get();
+            if (range != null) {
+                range.receiveReplacedText(node);
+            }
+            // Remove stale reference from the list.
+            else {
+                i.remove();
+            }
         }
     }
 
@@ -398,9 +429,17 @@
     }
     
     private void notifyRangesDeletedText(CharacterDataImpl node, int offset, int count) {
-        final int size = ranges.size();
-        for (int i = 0; i != size; i++) {
-            ((RangeImpl)ranges.elementAt(i)).receiveDeletedText(node, offset, count);
+        removeStaleRangeReferences();
+        final Iterator i = ranges.iterator();
+        while (i.hasNext()) {
+            RangeImpl range = (RangeImpl) ((Reference) i.next()).get();
+            if (range != null) {
+                range.receiveDeletedText(node, offset, count);
+            }
+            // Remove stale reference from the list.
+            else {
+                i.remove();
+            }
         }
     }
 
@@ -416,9 +455,17 @@
     }
     
     private void notifyRangesInsertedText(CharacterDataImpl node, int offset, int count) {
-        final int size = ranges.size();
-        for (int i = 0; i != size; i++) {
-            ((RangeImpl)ranges.elementAt(i)).receiveInsertedText(node, offset, count);
+        removeStaleRangeReferences();
+        final Iterator i = ranges.iterator();
+        while (i.hasNext()) {
+            RangeImpl range = (RangeImpl) ((Reference) i.next()).get();
+            if (range != null) {
+                range.receiveInsertedText(node, offset, count);
+            }
+            // Remove stale reference from the list.
+            else {
+                i.remove();
+            }
         }
     }
 
@@ -434,11 +481,26 @@
     }
     
     private void notifyRangesSplitData(Node node, Node newNode, int offset) {
-        final int size = ranges.size();
-        for (int i = 0; i != size; i++) {
-            ((RangeImpl)ranges.elementAt(i)).receiveSplitData(node, newNode, offset);
+        removeStaleRangeReferences();
+        final Iterator i = ranges.iterator();
+        while (i.hasNext()) {
+            RangeImpl range = (RangeImpl) ((Reference) i.next()).get();
+            if (range != null) {
+                range.receiveSplitData(node, newNode, offset);
+            }
+            // Remove stale reference from the list.
+            else {
+                i.remove();
+            }
         }
     }
+    
+    /**
+     * Remove stale range references from the range list.
+     */
+    private void removeStaleRangeReferences() {
+        removeStaleReferences(rangeReferenceQueue, ranges);
+    }
 
     //
     // DocumentEvent methods
@@ -1196,9 +1258,17 @@
     }
     
     private void notifyRangesInsertedNode(NodeImpl newInternal) {
-        final int size = ranges.size();
-        for (int i = 0; i != size; i++) {
-            ((RangeImpl)ranges.elementAt(i)).insertedNodeFromDOM(newInternal);
+        removeStaleRangeReferences();
+        final Iterator i = ranges.iterator();
+        while (i.hasNext()) {
+            RangeImpl range = (RangeImpl) ((Reference) i.next()).get();
+            if (range != null) {
+                range.insertedNodeFromDOM(newInternal);
+            }
+            // Remove stale reference from the list.
+            else {
+                i.remove();
+            }
         }
     }
 
@@ -1239,9 +1309,17 @@
     }
     
     private void notifyRangesRemovingNode(NodeImpl oldChild) {
-        final int size = ranges.size();
-        for (int i = 0; i != size; i++) {
-            ((RangeImpl)ranges.elementAt(i)).removeNode(oldChild);
+        removeStaleRangeReferences();
+        final Iterator i = ranges.iterator();
+        while (i.hasNext()) {
+            RangeImpl range = (RangeImpl) ((Reference) i.next()).get();
+            if (range != null) {
+                range.removeNode(oldChild);
+            }
+            // Remove stale reference from the list.
+            else {
+                i.remove();
+            }
         }
     }
     



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@xerces.apache.org
For additional commands, e-mail: commits-help@xerces.apache.org