Author: jukka
Date: Fri Jan 10 17:47:52 2014
New Revision: 1557203
URL: http://svn.apache.org/r1557203
Log:
OAK-1318: EventIterator keeps references to already seen events
Use a custom Iterator wrapper that only keeps a reference to a single
underlying Iterator at a time, and discard already procesed EventIterators.
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/ChangeProcessor.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/EventIterator.java
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/ChangeProcessor.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/ChangeProcessor.java?rev=1557203&r1=1557202&r2=1557203&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/ChangeProcessor.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/ChangeProcessor.java
Fri Jan 10 17:47:52 2014
@@ -20,6 +20,7 @@ package org.apache.jackrabbit.oak.plugin
import static com.google.common.base.Preconditions.checkState;
+import java.util.Iterator;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
@@ -166,9 +167,10 @@ public class ChangeProcessor implements
beforeTree.getNodeState(),
afterTree.getNodeState(),
Filters.all(userFilter, acFilter),
new JcrListener(beforeTree, afterTree,
namePathMapper, info));
- if (events.hasNext() && runningMonitor.enterIf(running)) {
+ Iterator<Event> iterator = events.iterator();
+ if (iterator.hasNext() && runningMonitor.enterIf(running))
{
try {
- eventListener.onEvent(new
EventIteratorAdapter(events));
+ eventListener.onEvent(new
EventIteratorAdapter(iterator));
} finally {
runningMonitor.leave();
}
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/EventIterator.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/EventIterator.java?rev=1557203&r1=1557202&r2=1557203&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/EventIterator.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/EventIterator.java
Fri Jan 10 17:47:52 2014
@@ -19,11 +19,11 @@
package org.apache.jackrabbit.oak.plugins.observation;
import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.collect.Iterators.concat;
-import static com.google.common.collect.Lists.newArrayList;
+import static com.google.common.collect.Lists.newLinkedList;
import java.util.Iterator;
-import java.util.List;
+import java.util.LinkedList;
+import java.util.NoSuchElementException;
import javax.annotation.Nonnull;
@@ -33,7 +33,6 @@ import org.apache.jackrabbit.oak.spi.com
import org.apache.jackrabbit.oak.spi.commit.VisibleEditor;
import org.apache.jackrabbit.oak.spi.state.MoveDetector;
import org.apache.jackrabbit.oak.spi.state.NodeState;
-import org.apache.jackrabbit.oak.util.LazyValue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -42,7 +41,7 @@ import org.slf4j.LoggerFactory;
* events.
* @param <T> type of the event returned by this iterator
*/
-public class EventIterator<T> extends EventGenerator implements Iterator<T> {
+public class EventIterator<T> extends EventGenerator implements Iterable<T> {
private static final Logger LOG =
LoggerFactory.getLogger(EventIterator.class);
private final NodeState before;
@@ -51,23 +50,7 @@ public class EventIterator<T> extends Ev
private final EventFilter filter;
private final IterableListener<T> listener;
- private final List<Iterator<T>> childEvents = newArrayList();
-
- private final LazyValue<Iterator<T>> eventIterator = new
LazyValue<Iterator<T>>() {
- @Override
- protected Iterator<T> createValue() {
- CommitFailedException e = EditorDiff.process(
- new VisibleEditor(
- new MoveDetector(EventIterator.this)),
- before, after);
-
- if (e != null) {
- LOG.error("Error while extracting observation events", e);
- }
-
- return concat(listener.iterator(), concat(childEvents.iterator()));
- }
- };
+ private final LinkedList<EventIterator<T>> childEvents = newLinkedList();
/**
* Specialisation of {@link Listener} that provides the events reported
@@ -113,21 +96,48 @@ public class EventIterator<T> extends Ev
return null;
}
- //------------------------------------------------------------< Iterator
>---
+ //----------------------------------------------------------< Iterable >--
@Override
- public boolean hasNext() {
- return eventIterator.get().hasNext();
- }
+ public Iterator<T> iterator() {
+ CommitFailedException e = EditorDiff.process(
+ new VisibleEditor(new MoveDetector(this)),
+ before, after);
+ if (e != null) {
+ LOG.error("Error while extracting observation events", e);
+ }
- @Override
- public T next() {
- return eventIterator.get().next();
- }
+ return new Iterator<T>() {
- @Override
- public void remove() {
- throw new UnsupportedOperationException();
+ private Iterator<T> iterator = listener.iterator();
+
+ @Override
+ public boolean hasNext() {
+ while (!iterator.hasNext()) {
+ if (childEvents.isEmpty()) {
+ return false;
+ } else {
+ iterator = childEvents.removeFirst().iterator();
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public T next() {
+ if (hasNext()) {
+ return iterator.next();
+ } else {
+ throw new NoSuchElementException();
+ }
+ }
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+
+ };
}
}