classpath-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[cp-patches] RFC: Using HashSet for event registration in DomNode


From: Guilhem Lavaux
Subject: [cp-patches] RFC: Using HashSet for event registration in DomNode
Date: Fri, 23 Dec 2005 19:00:07 +0100
User-agent: Mozilla Thunderbird 1.0.2 (X11/20050322)

Hi,

To improve performance in the case a DomNode has many event listeners
(which may be the case during a eclipse build) it is more efficient to use a
HashSet instead of the dumb algorithm currently in place of DomNode.
I am trying to check what is the performance boost at the moment but if someone wants
to check also...

Regards,
Guilhem.


ChangeLog:

2005-12-23  Guilhem Lavaux  <address@hidden>

   * gnu/xml/dom/DomNode.java
   (listeners): Use a HashSet now.
   (DomNode): Likewise.
   (compact, trimSize): Reduced to nop with a HashSet.
   (addEventListener, removeEventListener): Use HashSet operations.
   (dispatchEvent): Likewise.
   (notifyNode): Likewise.

Index: gnu/xml/dom/DomNode.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/xml/dom/DomNode.java,v
retrieving revision 1.9
diff -u -r1.9 DomNode.java
--- gnu/xml/dom/DomNode.java    23 Dec 2005 17:38:58 -0000      1.9
+++ gnu/xml/dom/DomNode.java    23 Dec 2005 17:43:53 -0000
@@ -38,6 +38,7 @@
 package gnu.xml.dom;
 
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Map;
 
@@ -149,7 +150,7 @@
   boolean readonly;
 
   // event registrations
-  private ListenerRecord[] listeners;
+  private HashSet listeners;
   private int nListeners;
 
   // DOM Level 3 userData dictionary.
@@ -167,19 +168,6 @@
    */
   public void compact()
   {
-    if (listeners != null && listeners.length != nListeners)
-      {
-        if (nListeners == 0)
-          {
-            listeners = null;
-          }
-        else
-          {
-            ListenerRecord[] l = new ListenerRecord[nListeners];
-            System.arraycopy(listeners, 0, l, 0, nListeners);
-            listeners = l;
-          }
-      }
   }
 
   /**
@@ -201,6 +189,7 @@
           }
       }
     this.owner = owner;
+    this.listeners = new HashSet();
   }
   
 
@@ -960,12 +949,6 @@
    */
   public void trimToSize()
   {
-    if (listeners != null && listeners.length != nListeners)
-      {
-        ListenerRecord[] newKids = new ListenerRecord[length];
-        System.arraycopy(listeners, 0, newKids, 0, nListeners);
-        listeners = newKids;
-      }
   }
 
   /**
@@ -1175,7 +1158,7 @@
         node.next = null;
         
         node.readonly = false;
-        node.listeners = null;
+        node.listeners = new HashSet();
         node.nListeners = 0;
         return node;
 
@@ -1264,7 +1247,7 @@
       elementName = name;
       matchAnyURI = "*".equals(uri);
       matchAnyName = "*".equals(name);
-      
+
       DomNode.this.addEventListener("DOMNodeInserted", this, true);
       DomNode.this.addEventListener("DOMNodeRemoved", this, true);
     }
@@ -1274,7 +1257,7 @@
       if (current != null)
         current.detach();
       current = null;
-      
+
       DomNode.this.removeEventListener("DOMNodeInserted", this, true);
       DomNode.this.removeEventListener("DOMNodeRemoved", this, true);
     }
@@ -1336,7 +1319,7 @@
         {
           return;
         }
-
+      
       if (current != null)
        current.detach();
       current = null;
@@ -1365,10 +1348,11 @@
       // somewhere after last node
       while (++lastIndex != index)
         current.nextNode ();
-        Node ret = current.nextNode ();
-        current.detach();
-       current = null;
-        return ret;
+
+      Node ret = current.nextNode ();
+      current.detach();
+      current = null;
+      return ret;
     }
     
     public int getLength()
@@ -1380,7 +1364,7 @@
         {
           retval++;
         }
-      iter.detach();      
+      iter.detach();
       return retval;
     }
     
@@ -1408,13 +1392,18 @@
       this.useCapture = useCapture;
     }
 
-    boolean equals(ListenerRecord rec)
+    public boolean equals(Object o)
     {
+      ListenerRecord rec = (ListenerRecord)o;
       return listener == rec.listener
         && useCapture == rec.useCapture
         && type == rec.type;
     }
     
+    public int hashCode()
+    {
+       return listener.hashCode() ^ type.hashCode();
+    }
   }
 
   /**
@@ -1469,30 +1458,12 @@
                                      EventListener listener,
                                      boolean useCapture)
   {
-    if (listeners == null)
-      {
-        listeners = new ListenerRecord[1];
-      }
-    else if (nListeners == listeners.length)
-      {
-        ListenerRecord[] newListeners =
-          new ListenerRecord[listeners.length + NKIDS_DELTA];
-        System.arraycopy(listeners, 0, newListeners, 0, nListeners);
-        listeners = newListeners;
-      }
-
     // prune duplicates
     ListenerRecord record;
 
     record = new ListenerRecord(type, listener, useCapture);
-    for (int i = 0; i < nListeners; i++)
-      {
-        if (record.equals(listeners[i]))
-          {
-            return;
-          }
-      }
-    listeners [nListeners++] = record;
+    listeners.add(record);
+    nListeners = listeners.size();
   }
 
   // XXX this exception should be discarded from DOM
@@ -1677,11 +1648,14 @@
                           ListenerRecord[] notificationSet)
   {
     int count = 0;
+    Iterator iter;
+
+    iter = current.listeners.iterator();
 
     // do any of this set of listeners get notified?
-    for (int i = 0; i < current.nListeners; i++)
+    while (iter.hasNext())
       {
-        ListenerRecord rec = current.listeners[i];
+        ListenerRecord rec = (ListenerRecord)iter.next();
 
         if (rec.useCapture != capture)
           {
@@ -1702,6 +1676,7 @@
           }
         notificationSet[count++] = rec;
       }
+    iter = null;
 
     // Notify just those listeners
     e.currentNode = current; 
@@ -1709,18 +1684,21 @@
       {
         try
           {
+           iter = current.listeners.iterator();
             // Late in the DOM CR process (3rd or 4th CR?) the
             // removeEventListener spec became asymmetric with respect
             // to addEventListener ... effect is now immediate.
-            for (int j = 0; j < current.nListeners; j++)
+           while (iter.hasNext())
               {
-                if (current.listeners[j].equals(notificationSet[i]))
+               ListenerRecord rec = (ListenerRecord)iter.next();
+
+                if (rec.equals(notificationSet[i]))
                   {
                     notificationSet[i].listener.handleEvent(e);
                     break;
                   }
               }
-            
+            iter = null;
           }
         catch (Exception x)
           {
@@ -1738,36 +1716,8 @@
                                         EventListener listener,
                                         boolean useCapture)
   {
-    for (int i = 0; i < nListeners; i++)
-      {
-        if (listeners[i].listener != listener)
-          {
-            continue;
-          }
-        if (listeners[i].useCapture != useCapture)
-          {
-            continue;
-          }
-        if (!listeners[i].type.equals(type))
-          {
-            continue;
-          }
-
-        if (nListeners == 1)
-          {
-            listeners = null;
-            nListeners = 0;
-          }
-        else
-          {
-            for (int j = i + 1; j < nListeners; j++)
-              {
-                listeners[i++] = listeners[j++];
-              }
-            listeners[--nListeners] = null;
-          }
-        break;
-      }
+    listeners.remove(new ListenerRecord(type, listener, useCapture));
+    nListeners = listeners.size();
     // no exceptions reported
   }
 

reply via email to

[Prev in Thread] Current Thread [Next in Thread]