jackrabbit-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mdue...@apache.org
Subject svn commit: r1174215 - in /jackrabbit/sandbox/jackrabbit-mk: jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ItemState.java jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/util/WeakIdentityCollection.java
Date Thu, 22 Sep 2011 15:41:56 GMT
Author: mduerig
Date: Thu Sep 22 15:41:55 2011
New Revision: 1174215

URL: http://svn.apache.org/viewvc?rev=1174215&view=rev
Log:
Microkernel based Jackrabbit prototype (WIP)
slim down WeakIdentityCollection

Modified:
    jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ItemState.java
    jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/util/WeakIdentityCollection.java

Modified: jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ItemState.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ItemState.java?rev=1174215&r1=1174214&r2=1174215&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ItemState.java
(original)
+++ jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ItemState.java
Thu Sep 22 15:41:55 2011
@@ -54,7 +54,7 @@ public abstract class ItemState<ENTRY_TY
     /**
      * Listeners (weak references)
      */
-    private final transient Collection<ItemStateLifeCycleListener> listeners = new
WeakIdentityCollection<ItemStateLifeCycleListener>(5);
+    private final transient Collection<ItemStateLifeCycleListener> listeners = new
WeakIdentityCollection<ItemStateLifeCycleListener>();
 
     /**
      * The {@code ItemStateFactory} which is used to create new

Modified: jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/util/WeakIdentityCollection.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/util/WeakIdentityCollection.java?rev=1174215&r1=1174214&r2=1174215&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/util/WeakIdentityCollection.java
(original)
+++ jackrabbit/sandbox/jackrabbit-mk/jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/util/WeakIdentityCollection.java
Thu Sep 22 15:41:55 2011
@@ -19,12 +19,10 @@ package org.apache.jackrabbit.spi.common
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.lang.ref.ReferenceQueue;
 import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.BitSet;
 import java.util.Collection;
 import java.util.Iterator;
+import java.util.NoSuchElementException;
 
 import static org.apache.jackrabbit.spi.commons.util.Unchecked.cast;
 
@@ -37,38 +35,40 @@ import static org.apache.jackrabbit.spi.
  * by this collection might return {@code null} values. The same applies
  * to the method {@link #toArray()} in both its variants.
  */
-public class WeakIdentityCollection<E> implements Collection<E> {
+public final class WeakIdentityCollection<E> implements Collection<E> {
     private static final Logger log = LoggerFactory.getLogger(WeakIdentityCollection.class);
 
-    /**
-     * The weak references.
-     */
-    private final transient ArrayList<WeakReferenceWithIndex> elementData;
+    /** Threshold after what number of operations the collection is automatically trimmed
*/
+    private static final int TRIM_THRESHOLD = 32;
 
-    /**
-     * The reference queue to poll for references that point to unreachable
-     * objects.
-     */
-    private final ReferenceQueue<E> refQueue = new ReferenceQueue<E>();
+    /** Head of the linked list of {@code LinkedReference}s */
+    private LinkedReference head;
 
-    /**
-     * BitSet where a set bit indicates that the slot at this position in
-     * {@link #elementData} is empty and can be reused.
-     */
-    private final BitSet emptySlots = new BitSet();
+    /** Current number of elements in the linked list */
+    private int size;
+
+    /** Number of operations performed since the collections has been trimmed */
+    private int opCount;
 
     /**
-     * Creates a new WeakIdentityCollection.
-     *
-     * @param initialCapacity the initial capacity.
+     * Trim the collections such that all cleared references are removed. 
      */
-    public WeakIdentityCollection(int initialCapacity) {
-        if (initialCapacity < 0) {
-            IllegalArgumentException e = new IllegalArgumentException("Illegal Capacity:
" + initialCapacity);
-            log.error(e.getMessage(), e);
-            throw e;
+    public void trim() {
+        opCount = 0;
+        while (head != null && head.get() == null) {
+            head = head.next;
+            size--;
+        }
+        if (head == null) {
+            return;
+        }
+
+        for (LinkedReference ref = head; ref.next != null; ref = ref.next) {
+            if (ref.next.get() == null) {
+                ref.next = ref.next.next;
+                size--;
+            }
         }
-        elementData = new ArrayList<WeakReferenceWithIndex>(initialCapacity);
     }
 
     /**
@@ -78,7 +78,7 @@ public class WeakIdentityCollection<E> i
      */
     @Override
     public int size() {
-        return elementData.size();
+        return size;
     }
 
     /**
@@ -88,7 +88,8 @@ public class WeakIdentityCollection<E> i
      */
     @Override
     public boolean isEmpty() {
-        return elementData.isEmpty();
+        trimIfNecessary();
+        return size == 0;
     }
 
     /**
@@ -96,8 +97,7 @@ public class WeakIdentityCollection<E> i
      */
     @Override
     public void clear() {
-        elementData.clear();
-        emptySlots.clear();
+        head = null;
     }
 
     /**
@@ -105,25 +105,13 @@ public class WeakIdentityCollection<E> i
      *
      * @param o the object to add.
      * @return always {@code true} as this collection allows duplicates.
-     * @throws NullPointerException if {@code o} is {@code null}.
      */
     @Override
     public boolean add(E o) {
-        if (o == null) {
-            throw new NullPointerException("Object must not be null");
-        }
-        // poll refQueue for a slot we can reuse
-        WeakReferenceWithIndex ref = (WeakReferenceWithIndex) refQueue.poll();
-        if (ref != null) {
-            elementData.set(ref.index, new WeakReferenceWithIndex(o, ref.index));
-            cleanQueue();
-        } else if (!emptySlots.isEmpty()) {
-            int idx = emptySlots.nextSetBit(0);
-            elementData.set(idx, new WeakReferenceWithIndex(o, idx));
-            emptySlots.clear(idx);
-        } else {
-            elementData.add(new WeakReferenceWithIndex(o, elementData.size()));
-        }
+        trimIfNecessary();
+        opCount++;
+        head = new LinkedReference(o, head);
+        size++;
         return true;
     }
 
@@ -135,8 +123,10 @@ public class WeakIdentityCollection<E> i
      */
     @Override
     public boolean contains(Object o) {
-        for (WeakReferenceWithIndex anElementData : elementData) {
-            if (anElementData.get() == o) {
+        trimIfNecessary();
+        trimIfNecessary();
+        for (LinkedReference ref = head; ref != null; ref = ref.next) {
+            if (ref.get() == o) {
                 return true;
             }
         }
@@ -151,11 +141,21 @@ public class WeakIdentityCollection<E> i
      */
     @Override
     public boolean remove(Object o) {
-        for (int i = 0; i < elementData.size(); i++) {
-            if (elementData.get(i).get() == o) {
-                emptySlots.set(i);
-                // overwrite entry with dummy ref
-                elementData.set(i, new WeakReferenceWithIndex(null, i));
+        trimIfNecessary();
+        opCount++;
+        if (head == null) {
+            return false;
+        }
+        if (head.get() == o) {
+            head = head.next;
+            size--;
+            return true;
+        }
+
+        for (LinkedReference ref = head; ref.next != null; ref = ref.next) {
+            if (ref.next.get() == o) {
+                ref.next = ref.next.next;
+                size--;
                 return true;
             }
         }
@@ -212,22 +212,30 @@ public class WeakIdentityCollection<E> i
      */
     @Override
     public Iterator<E> iterator() {
+        trimIfNecessary();
         return new Iterator<E>() {
-            private final Iterator<WeakReferenceWithIndex> elementIterator = elementData.iterator();
+            private LinkedReference current = head;
 
             @Override
             public boolean hasNext() {
-                return elementIterator.hasNext();
+                return current != null;
             }
 
             @Override
             public E next() {
-                return elementIterator.next().get();
+                if (current == null) {
+                    throw new NoSuchElementException();
+                }
+                E e = current.get();
+                current = current.next;
+                return e;
             }
 
             @Override
             public void remove() {
-                elementIterator.remove();
+                UnsupportedOperationException e = new UnsupportedOperationException("remove");
+                log.error(e.getMessage(), e);
+                throw e;
             }
         };
     }
@@ -240,9 +248,10 @@ public class WeakIdentityCollection<E> i
      */
     @Override
     public Object[] toArray() {
-        Object[] result = new Object[elementData.size()];
-        for (int i = 0; i < result.length; i++) {
-            result[i] = elementData.get(i).get();
+        Object[] result = new Object[size];
+        int k = 0;
+        for (LinkedReference ref = head; ref != null; k++, ref = ref.next) {
+            result[k] = ref.get();
         }
         return result;
     }
@@ -253,15 +262,14 @@ public class WeakIdentityCollection<E> i
      */
     @Override
     public <T> T[] toArray(T[] a) {
-        int size = elementData.size();
-        
         if (a.length < size) {
             a = cast(java.lang.reflect.Array.newInstance(a.getClass().getComponentType(),
size));
         }
 
-        for (int i = 0; i < size; i++) {
+        int k = 0;
+        for (LinkedReference ref = head; ref != null; k++, ref = ref.next) {
             //noinspection RedundantTypeArguments
-            a[i] = Unchecked.<T>cast(elementData.get(i).get());
+            a[k] = Unchecked.<T>cast(ref.get());
         }
 
         if (a.length > size) {
@@ -271,36 +279,24 @@ public class WeakIdentityCollection<E> i
         return a;
     }
 
-    /**
-     * Polls the reference queue until no reference is available anymore.
-     */
-    private void cleanQueue() {
-        WeakReferenceWithIndex ref;
-        while ((ref = (WeakReferenceWithIndex) refQueue.poll()) != null) {
-            emptySlots.set(ref.index);
+    //------------------------------------------< private >---
+
+    private void trimIfNecessary() {
+        if (opCount > TRIM_THRESHOLD) {
+            trim();
         }
     }
 
     /**
-     * Weak reference with index value that points to the slot in {@link
-     * WeakIdentityCollection#elementData}.
+     * A reference which holds a link to a next reference in a list of
+     * references. 
      */
-    private final class WeakReferenceWithIndex extends WeakReference<E> {
-
-        /**
-         * The index of this weak reference.
-         */
-        private final int index;
+    private final class LinkedReference extends WeakReference<E> {
+        private LinkedReference next;
 
-        /**
-         * Creates a new WeakReferenceWithIndex.
-         *
-         * @param referent object the new weak reference will refer to.
-         * @param index    the index of this weak reference.
-         */
-        public WeakReferenceWithIndex(E referent, int index) {
-            super(referent, refQueue);
-            this.index = index;
+        public LinkedReference(E referent, LinkedReference next) {
+            super(referent);
+            this.next = next;
         }
     }
 }



Mime
View raw message