You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by st...@apache.org on 2005/07/13 17:45:22 UTC
svn commit: r216177 - in
/incubator/jackrabbit/trunk/core/src/java/org/apache/jackrabbit/core:
LazyItemIterator.java NodeImpl.java version/VersionHistoryImpl.java
version/VersionImpl.java
Author: stefan
Date: Wed Jul 13 08:45:20 2005
New Revision: 216177
URL: http://svn.apache.org/viewcvs?rev=216177&view=rev
Log:
optimized LazyItemIterator and made it more forgiving
Modified:
incubator/jackrabbit/trunk/core/src/java/org/apache/jackrabbit/core/LazyItemIterator.java
incubator/jackrabbit/trunk/core/src/java/org/apache/jackrabbit/core/NodeImpl.java
incubator/jackrabbit/trunk/core/src/java/org/apache/jackrabbit/core/version/VersionHistoryImpl.java
incubator/jackrabbit/trunk/core/src/java/org/apache/jackrabbit/core/version/VersionImpl.java
Modified: incubator/jackrabbit/trunk/core/src/java/org/apache/jackrabbit/core/LazyItemIterator.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/core/src/java/org/apache/jackrabbit/core/LazyItemIterator.java?rev=216177&r1=216176&r2=216177&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/core/src/java/org/apache/jackrabbit/core/LazyItemIterator.java (original)
+++ incubator/jackrabbit/trunk/core/src/java/org/apache/jackrabbit/core/LazyItemIterator.java Wed Jul 13 08:45:20 2005
@@ -18,38 +18,46 @@
import org.apache.log4j.Logger;
+import javax.jcr.Item;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.Property;
import javax.jcr.PropertyIterator;
import javax.jcr.RepositoryException;
-import java.util.ArrayList;
-import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
+import java.util.ArrayList;
/**
* <code>LazyItemIterator</code> is an id-based iterator that instantiates
* the <code>Item</code>s only when they are requested.
+ * <p/>
+ * <strong>Important:</strong> <code>Item</code>s that appear to be nonexistent
+ * for some reason (e.g. because of insufficient access rights or because they
+ * have been removed since the iterator has been retrieved) are silently
+ * skipped. As a result the size of the iterator as reported by
+ * {@link #getSize()} might appear to be shrinking while iterating over the
+ * items.
+ * todo should getSize() better always return -1?
+ *
+ * @see #getSize()
*/
class LazyItemIterator implements NodeIterator, PropertyIterator {
+ /** Logger instance for this class */
private static Logger log = Logger.getLogger(LazyItemIterator.class);
- /**
- * the item manager that is used to fetch the items
- */
+ /** the item manager that is used to lazily fetch the items */
private final ItemManager itemMgr;
- /**
- * the list of item ids
- */
+ /** the list of item ids */
private final List idList;
- /**
- * the position of the next item
- */
- private int pos = 0;
+ /** the position of the next item */
+ private int pos;
+
+ /** prefetched item to be returned on <code>{@link #next()}</code> */
+ private Item next;
/**
* Creates a new <code>LazyItemIterator</code> instance.
@@ -58,35 +66,40 @@
* @param idList list of item id's
*/
public LazyItemIterator(ItemManager itemMgr, List idList) {
- this(itemMgr, idList, false);
+ this.itemMgr = itemMgr;
+ this.idList = new ArrayList(idList);
+ // prefetch first item
+ pos = 0;
+ prefetchNext();
}
/**
- * Creates a new <code>LazyItemIterator</code> instance.
- *
- * @param itemMgr item manager
- * @param idList list of item id's
- * @param skipInexistent if <code>true</code> the id's of those items
- * that appear to be non-existent will be filtered
- * out silently; otherwise such entries will cause
- * a <code>NoSuchElementException</code> on
- * <code>{@link #next()}</code> .
- */
- public LazyItemIterator(ItemManager itemMgr, List idList,
- boolean skipInexistent) {
- this.itemMgr = itemMgr;
- if (skipInexistent) {
- // check existence of all items first
- this.idList = new ArrayList();
- Iterator iter = idList.iterator();
- while (iter.hasNext()) {
- ItemId id = (ItemId) iter.next();
- if (itemMgr.itemExists(id)) {
- this.idList.add(id);
- }
+ * Prefetches next item.
+ * <p/>
+ * {@link #next} is set to the next available item in this iterator or to
+ * <code>null</code> in case there are no more items.
+ */
+ private void prefetchNext() {
+ // reset
+ next = null;
+ while (next == null && pos < idList.size()) {
+ ItemId id = (ItemId) idList.get(pos);
+ if (!itemMgr.itemExists(id)) {
+ log.debug("ignoring nonexistent item " + id);
+ // remove invalid id
+ idList.remove(pos);
+ // try next
+ continue;
+ }
+ try {
+ next = itemMgr.getItem(id);
+ } catch (RepositoryException e) {
+ // should never get here since existence has already been checked...
+ log.error("failed to fetch item " + id + ", skipping...", e);
+ // remove invalid id
+ idList.remove(pos);
+ // try next
}
- } else {
- this.idList = idList;
}
}
@@ -106,7 +119,7 @@
return (Property) next();
}
- //------------------------------------------------------< RangeIterator >---
+ //--------------------------------------------------------< RangeIterator >
/**
* {@inheritDoc}
*/
@@ -116,6 +129,13 @@
/**
* {@inheritDoc}
+ * <p/>
+ * Note that the size of the iterator as reported by {@link #getSize()}
+ * might appear to be shrinking while iterating because items that for
+ * some reason cannot be retrieved through this iterator are silently
+ * skipped, thus reducing the size of this iterator.
+ *
+ * todo better to always return -1?
*/
public long getSize() {
return idList.size();
@@ -126,12 +146,42 @@
*/
public void skip(long skipNum) {
if (skipNum < 0) {
- throw new IllegalArgumentException("skipNum must be a positive number");
+ throw new IllegalArgumentException("skipNum must not be negative");
+ }
+ if (skipNum == 0) {
+ return;
+ }
+ if (next == null) {
+ throw new NoSuchElementException();
}
- if (pos + skipNum > idList.size()) {
- throw new NoSuchElementException("skipNum + pos greater than size");
+
+ // reset
+ next = null;
+ // skip the first (skipNum - 1) items without actually retrieving them
+ while (--skipNum > 0) {
+ pos++;
+ if (pos >= idList.size()) {
+ // skipped past last item
+ throw new NoSuchElementException();
+ }
+ ItemId id = (ItemId) idList.get(pos);
+ // eliminate invalid items from this iterator
+ while (!itemMgr.itemExists(id)) {
+ log.debug("ignoring nonexistent item " + id);
+ // remove invalid id
+ idList.remove(pos);
+ if (pos >= idList.size()) {
+ // skipped past last item
+ throw new NoSuchElementException();
+ }
+ id = (ItemId) idList.get(pos);
+ // try next
+ continue;
+ }
}
- pos += skipNum;
+ // prefetch final item (the one to be returned on next())
+ pos++;
+ prefetchNext();
}
//-------------------------------------------------------------< Iterator >
@@ -139,23 +189,20 @@
* {@inheritDoc}
*/
public boolean hasNext() {
- return pos < idList.size();
+ return next != null;
}
/**
* {@inheritDoc}
*/
public Object next() {
- if (pos >= idList.size()) {
+ if (next == null) {
throw new NoSuchElementException();
}
- ItemId id = (ItemId) idList.get(pos++);
- try {
- return itemMgr.getItem(id);
- } catch (RepositoryException e) {
- log.debug("failed to fetch item " + id, e);
- throw new NoSuchElementException(e.getMessage());
- }
+ Item item = next;
+ pos++;
+ prefetchNext();
+ return item;
}
/**
Modified: incubator/jackrabbit/trunk/core/src/java/org/apache/jackrabbit/core/NodeImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/core/src/java/org/apache/jackrabbit/core/NodeImpl.java?rev=216177&r1=216176&r2=216177&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/core/src/java/org/apache/jackrabbit/core/NodeImpl.java (original)
+++ incubator/jackrabbit/trunk/core/src/java/org/apache/jackrabbit/core/NodeImpl.java Wed Jul 13 08:45:20 2005
@@ -925,28 +925,6 @@
}
/**
- * Same as <code>{@link Node#getReferences()}</code> except that
- * this method also filters out the references that appear to be non-existent
- * in this workspace if <code>skipInexistent</code> is set to <code>true</code>.
- *
- * @param skipInexistent if set to <code>true</code> inexistent items are skipped
- */
- protected PropertyIterator getReferences(boolean skipInexistent)
- throws RepositoryException {
- try {
- NodeReferencesId targetId = new NodeReferencesId(((NodeId) id).getUUID());
- NodeReferences refs = getOrCreateNodeReferences(targetId);
- // refs.getReferences returns a list of PropertyId's
- List idList = refs.getReferences();
- return new LazyItemIterator(itemMgr, idList, skipInexistent);
- } catch (ItemStateException e) {
- String msg = "Unable to retrieve node references for: " + id;
- log.debug(msg);
- throw new RepositoryException(msg, e);
- }
- }
-
- /**
* Same as {@link Node#addMixin(String)}, but takes a <code>QName</code>
* instad of a <code>String</code>.
*
@@ -2532,7 +2510,17 @@
// check state of this instance
sanityCheck();
- return getReferences(false);
+ try {
+ NodeReferencesId targetId = new NodeReferencesId(((NodeId) id).getUUID());
+ NodeReferences refs = getOrCreateNodeReferences(targetId);
+ // refs.getReferences() returns a list of PropertyId's
+ List idList = refs.getReferences();
+ return new LazyItemIterator(itemMgr, idList);
+ } catch (ItemStateException e) {
+ String msg = "Unable to retrieve REFERENCE properties that refer to " + id;
+ log.debug(msg);
+ throw new RepositoryException(msg, e);
+ }
}
/**
Modified: incubator/jackrabbit/trunk/core/src/java/org/apache/jackrabbit/core/version/VersionHistoryImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/core/src/java/org/apache/jackrabbit/core/version/VersionHistoryImpl.java?rev=216177&r1=216176&r2=216177&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/core/src/java/org/apache/jackrabbit/core/version/VersionHistoryImpl.java (original)
+++ incubator/jackrabbit/trunk/core/src/java/org/apache/jackrabbit/core/version/VersionHistoryImpl.java Wed Jul 13 08:45:20 2005
@@ -28,7 +28,6 @@
import org.apache.jackrabbit.name.UnknownPrefixException;
import javax.jcr.Item;
-import javax.jcr.PropertyIterator;
import javax.jcr.RepositoryException;
import javax.jcr.UnsupportedRepositoryOperationException;
import javax.jcr.nodetype.NodeDefinition;
@@ -277,17 +276,6 @@
throw new VersionException("Specified version not contained in this history.");
}
}
-
- /**
- * {@inheritDoc}
- * <p/>
- * In addition to the normal behaviour, this method also filters out the
- * references that do not exist in this workspace.
- */
- public PropertyIterator getReferences() throws RepositoryException {
- return getReferences(true);
- }
-
/**
* Returns the internal version history
Modified: incubator/jackrabbit/trunk/core/src/java/org/apache/jackrabbit/core/version/VersionImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/core/src/java/org/apache/jackrabbit/core/version/VersionImpl.java?rev=216177&r1=216176&r2=216177&view=diff
==============================================================================
--- incubator/jackrabbit/trunk/core/src/java/org/apache/jackrabbit/core/version/VersionImpl.java (original)
+++ incubator/jackrabbit/trunk/core/src/java/org/apache/jackrabbit/core/version/VersionImpl.java Wed Jul 13 08:45:20 2005
@@ -24,7 +24,6 @@
import org.apache.jackrabbit.core.state.NodeState;
import javax.jcr.Item;
-import javax.jcr.PropertyIterator;
import javax.jcr.RepositoryException;
import javax.jcr.UnsupportedRepositoryOperationException;
import javax.jcr.nodetype.NodeDefinition;
@@ -139,15 +138,4 @@
return false;
}
}
-
- /**
- * {@inheritDoc}
- * <p/>
- * In addition to the normal behaviour, this method also filters out the
- * references that do not exist in this workspace.
- */
- public PropertyIterator getReferences() throws RepositoryException {
- return getReferences(true);
- }
-
}