You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by ju...@apache.org on 2014/01/27 16:24:51 UTC

svn commit: r1561710 - in /jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation: ./ filter/

Author: jukka
Date: Mon Jan 27 15:24:51 2014
New Revision: 1561710

URL: http://svn.apache.org/r1561710
Log:
OAK-1332: Large number of changes to the same node can fill observation queue

Merge EventIterable and JcrListener to EventGenerator to simplify the code
and to use just a single list of events as the event queue.

Added:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/filter/VisibleFilter.java   (with props)
Removed:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/EventIterable.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/JcrListener.java
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/EventContext.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/EventGenerator.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/filter/EventFilter.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=1561710&r1=1561709&r2=1561710&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 Mon Jan 27 15:24:51 2014
@@ -20,13 +20,11 @@ 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;
 
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
-import javax.jcr.observation.Event;
 import javax.jcr.observation.EventListener;
 
 import com.google.common.util.concurrent.Monitor;
@@ -163,15 +161,12 @@ public class ChangeProcessor implements 
                     EventFilter acFilter = new ACFilter(previousRoot, root, permissionProvider, basePath);
                     ImmutableTree beforeTree = getTree(previousRoot, basePath);
                     ImmutableTree afterTree = getTree(root, basePath);
-                    EventContext context = new EventContext(namePathMapper, info);
-                    EventIterable<Event> events = new EventIterable<Event>(
-                            beforeTree.getNodeState(), afterTree.getNodeState(),
-                            Filters.all(userFilter, acFilter),
-                            new JcrListener(context, beforeTree, afterTree));
-                    Iterator<Event> iterator = events.iterator();
-                    if (iterator.hasNext() && runningMonitor.enterIf(running)) {
+                    EventGenerator events = new EventGenerator(
+                            namePathMapper, info, beforeTree, afterTree,
+                            Filters.all(userFilter, acFilter));
+                    if (events.hasNext() && runningMonitor.enterIf(running)) {
                         try {
-                            eventListener.onEvent(new EventIteratorAdapter(iterator));
+                            eventListener.onEvent(new EventIteratorAdapter(events));
                         } finally {
                             runningMonitor.leave();
                         }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/EventContext.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/EventContext.java?rev=1561710&r1=1561709&r2=1561710&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/EventContext.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/EventContext.java Mon Jan 27 15:24:51 2014
@@ -92,4 +92,4 @@ final class EventContext {
         return info.toString();
     }
 
-}
\ No newline at end of file
+}

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/EventGenerator.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/EventGenerator.java?rev=1561710&r1=1561709&r2=1561710&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/EventGenerator.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/EventGenerator.java Mon Jan 27 15:24:51 2014
@@ -19,174 +19,279 @@
 package org.apache.jackrabbit.oak.plugins.observation;
 
 import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.collect.Lists.newArrayList;
+import static com.google.common.collect.Lists.newLinkedList;
+import static javax.jcr.observation.Event.NODE_ADDED;
+import static javax.jcr.observation.Event.NODE_MOVED;
+import static javax.jcr.observation.Event.NODE_REMOVED;
+import static javax.jcr.observation.Event.PROPERTY_ADDED;
+import static javax.jcr.observation.Event.PROPERTY_CHANGED;
+import static javax.jcr.observation.Event.PROPERTY_REMOVED;
+import static org.apache.jackrabbit.oak.api.Type.STRING;
+import static org.apache.jackrabbit.oak.core.AbstractTree.OAK_CHILD_ORDER;
 import static org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState.MISSING_NODE;
+import static org.apache.jackrabbit.oak.spi.state.MoveDetector.SOURCE_PATH;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
 
 import javax.annotation.Nonnull;
+import javax.jcr.observation.Event;
+import javax.jcr.observation.EventIterator;
 
-import org.apache.jackrabbit.oak.api.CommitFailedException;
 import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.apache.jackrabbit.oak.core.ImmutableTree;
+import org.apache.jackrabbit.oak.namepath.NamePathMapper;
 import org.apache.jackrabbit.oak.plugins.observation.filter.EventFilter;
-import org.apache.jackrabbit.oak.spi.state.MoveValidator;
+import org.apache.jackrabbit.oak.plugins.observation.filter.Filters;
+import org.apache.jackrabbit.oak.plugins.observation.filter.VisibleFilter;
+import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
 import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.apache.jackrabbit.oak.spi.state.NodeStateDiff;
+
+import com.google.common.collect.ImmutableMap;
 
 /**
- * {@link EventFilter filter} and report changes between node states to the {@link Listener}.
+ * Generator of a traversable view of events.
  */
-public class EventGenerator implements MoveValidator {
-    private final EventFilter filter;
-    private final Listener listener;
+public class EventGenerator implements EventIterator {
+
+    private final EventContext context;
+
+    private final LinkedList<Event> events = newLinkedList();
+    private final LinkedList<Runnable> generators = newLinkedList();
+
+    private long position = 0;
 
     /**
-     * Listener for listening to changes.
+     * Create a new instance of a {@code EventGenerator} reporting events to the
+     * passed {@code listener} after filtering with the passed {@code filter}.
+     *
+     * @param filter filter for filtering changes
      */
-    public interface Listener {
+    public EventGenerator(
+            @Nonnull NamePathMapper namePathMapper, CommitInfo info,
+            @Nonnull ImmutableTree before, @Nonnull ImmutableTree after,
+            @Nonnull EventFilter filter) {
+        this.context = new EventContext(namePathMapper, info);
+
+        filter = Filters.all(new VisibleFilter(), checkNotNull(filter));
+        new EventDiff(before, after, filter).run();
+    }
+
+    private class EventDiff implements NodeStateDiff, Runnable {
+
+        private final EventFilter filter;
+        private final NodeState before;
+        private final NodeState after;
+        private final ImmutableTree beforeTree;
+        private final ImmutableTree afterTree;
+
+        EventDiff(ImmutableTree before, ImmutableTree after,
+                EventFilter filter) {
+            this.before = before.getNodeState();
+            this.after = after.getNodeState();
+            this.filter = filter;
+            this.beforeTree = before;
+            this.afterTree = after;
+        }
 
-        /**
-         * Notification for an added property
-         * @param after  added property
-         */
-        void propertyAdded(PropertyState after);
+        public EventDiff(
+                EventDiff parent, String name,
+                NodeState before, NodeState after, EventFilter filter) {
+            this.before = before;
+            this.after = after;
+            this.filter = filter;
+            this.beforeTree = new ImmutableTree(parent.beforeTree, name, before);
+            this.afterTree = new ImmutableTree(parent.afterTree, name, after);
+        }
 
-        /**
-         * Notification for a changed property
-         * @param before  property before the change
-         * @param after  property after the change
-         */
-        void propertyChanged(PropertyState before, PropertyState after);
+        //------------------------------------------------------< Runnable >--
 
-        /**
-         * Notification for a deleted property
-         * @param before  deleted property
-         */
-        void propertyDeleted(PropertyState before);
+        @Override
+        public void run() {
+            after.compareAgainstBaseState(before, this);
+        }
 
-        /**
-         * Notification for an added node
-         * @param name  name of the node
-         * @param after  added node
-         */
-        void childNodeAdded(String name, NodeState after);
+        @Override
+        public boolean propertyAdded(PropertyState after) {
+            if (filter.includeAdd(after)) {
+                events.add(new EventImpl(
+                        context, PROPERTY_ADDED, afterTree, after.getName()));
+            }
+            return true;
+        }
 
-        /**
-         * Notification for a changed node
-         * @param name  name of the node
-         * @param before  node before the change
-         * @param after  node after the change
-         */
-        void childNodeChanged(String name, NodeState before, NodeState after);
+        @Override
+        public boolean propertyChanged(
+                PropertyState before, PropertyState after) {
+            if (filter.includeChange(before, after)) {
+                events.add(new EventImpl(
+                        context, PROPERTY_CHANGED, afterTree, after.getName()));
+            }
+            return true;
+        }
 
-        /**
-         * Notification for a deleted node
-         * @param name  name of the deleted node
-         * @param before  deleted node
-         */
-        void childNodeDeleted(String name, NodeState before);
+        @Override
+        public boolean propertyDeleted(PropertyState before) {
+            if (filter.includeDelete(before)) {
+                events.add(new EventImpl(
+                        context, PROPERTY_REMOVED, beforeTree, before.getName()));
+            }
+            return true;
+        }
 
-        /**
-         * Notification for a moved node
-         * @param sourcePath  source of the moved node
-         * @param name        name of the moved node
-         * @param moved       moved node
-         */
-        void nodeMoved(String sourcePath, String name, NodeState moved);
+        @Override
+        public boolean childNodeAdded(String name, NodeState after) {
+            PropertyState sourceProperty = after.getProperty(SOURCE_PATH);
+            if (sourceProperty != null) {
+                String sourcePath = sourceProperty.getValue(STRING);
+                if (filter.includeMove(sourcePath, name, after)) {
+                    String destPath = PathUtils.concat(afterTree.getPath(), name);
+                    Map<String, String> info = ImmutableMap.of(
+                            "srcAbsPath", context.getJcrPath(sourcePath),
+                            "destAbsPath", context.getJcrPath(destPath));
+                    ImmutableTree tree = new ImmutableTree(afterTree, name, after);
+                    events.add(new EventImpl(context, NODE_MOVED, tree, info));
+                }
+            }
+            if (filter.includeAdd(name, after)) {
+                ImmutableTree tree = new ImmutableTree(afterTree, name, after);
+                events.add(new EventImpl(context, NODE_ADDED, tree));
+            }
+            addChildGenerator(name, MISSING_NODE, after);
+            return true;
+        }
+
+        @Override
+        public boolean childNodeChanged(
+                String name, NodeState before, NodeState after) {
+            if (filter.includeChange(name, before, after)) {
+                detectReorder(name, before, after);
+            }
+            addChildGenerator(name, before, after);
+            return true;
+        }
+
+        @Override
+        public boolean childNodeDeleted(String name, NodeState before) {
+            if (filter.includeDelete(name, before)) {
+                ImmutableTree tree = new ImmutableTree(beforeTree, name, before);
+                events.add(new EventImpl(context, NODE_REMOVED, tree));
+            }
+            addChildGenerator(name, before, MISSING_NODE);
+            return true;
+        }
+
+        //------------------------------------------------------------< private >---
+
+        private void detectReorder(String name, NodeState before, NodeState after) {
+            List<String> afterNames = newArrayList(after.getNames(OAK_CHILD_ORDER));
+            List<String> beforeNames = newArrayList(before.getNames(OAK_CHILD_ORDER));
+
+            afterNames.retainAll(beforeNames);
+            beforeNames.retainAll(afterNames);
+
+            // Selection sort beforeNames into afterNames recording the swaps as we go
+            ImmutableTree parent = new ImmutableTree(afterTree, name, after);
+            for (int a = 0; a < afterNames.size(); a++) {
+                String afterName = afterNames.get(a);
+                for (int b = a; b < beforeNames.size(); b++) {
+                    String beforeName = beforeNames.get(b);
+                    if (a != b && beforeName.equals(afterName)) {
+                        beforeNames.set(b, beforeNames.get(a));
+                        beforeNames.set(a, beforeName);
+                        Map<String, String> info = ImmutableMap.of(
+                                "srcChildRelPath", beforeNames.get(a),
+                                "destChildRelPath", beforeNames.get(a + 1));
+                        ImmutableTree tree = parent.getChild(afterName);
+                        events.add(new EventImpl(context, NODE_MOVED, tree, info));
+                    }
+                }
+            }
+        }
 
         /**
-         * Factory for creating a filter instance for the given child node
-         * @param name name of the child node
+         * Factory method for creating {@code EventGenerator} instances of child nodes.
+         * @param name  name of the child node
          * @param before  before state of the child node
          * @param after  after state of the child node
-         * @return  listener for the child node
          */
-        @Nonnull
-        Listener create(String name, NodeState before, NodeState after);
-    }
-
-    /**
-     * Create a new instance of a {@code EventGenerator} reporting events to the
-     * passed {@code listener} after filtering with the passed {@code filter}.
-     * @param filter  filter for filtering changes
-     * @param listener  listener for listening to the filtered changes
-     */
-    public EventGenerator(@Nonnull EventFilter filter, @Nonnull Listener listener) {
-        this.filter = checkNotNull(filter);
-        this.listener = checkNotNull(listener);
-    }
-
-    @Override
-    public void move(String name, String sourcePath, NodeState moved) throws CommitFailedException {
-        if (filter.includeMove(sourcePath, name, moved)) {
-            listener.nodeMoved(sourcePath, name, moved);
+        private void addChildGenerator(
+                String name, NodeState before, NodeState after) {
+            EventFilter childFilter = filter.create(name, before, after);
+            if (childFilter != null) {
+                generators.add(
+                        new EventDiff(this, name, before, after, childFilter));
+            }
         }
-    }
 
-    @Override
-    public void enter(NodeState before, NodeState after) throws CommitFailedException {
     }
 
-    @Override
-    public void leave(NodeState before, NodeState after) throws CommitFailedException {
-    }
+    //-----------------------------------------------------< EventIterator >--
 
     @Override
-    public void propertyAdded(PropertyState after) throws CommitFailedException {
-        if (filter.includeAdd(after)) {
-            listener.propertyAdded(after);
+    public long getSize() {
+        if (generators.isEmpty()) {
+            return position + events.size();
+        } else {
+            return -1;
         }
     }
 
     @Override
-    public void propertyChanged(PropertyState before, PropertyState after) throws CommitFailedException {
-        if (filter.includeChange(before, after)) {
-            listener.propertyChanged(before, after);
-        }
+    public long getPosition() {
+        return position;
     }
 
     @Override
-    public void propertyDeleted(PropertyState before) throws CommitFailedException {
-        if (filter.includeDelete(before)) {
-            listener.propertyDeleted(before);
+    public boolean hasNext() {
+        while (events.isEmpty()) {
+            if (generators.isEmpty()) {
+                return false;
+            } else {
+                generators.removeFirst().run();
+            }
         }
+        return true;
     }
 
     @Override
-    public MoveValidator childNodeAdded(String name, NodeState after) throws CommitFailedException {
-        if (filter.includeAdd(name, after)) {
-            listener.childNodeAdded(name, after);
+    public void skip(long skipNum) {
+        while (skipNum > events.size()) {
+            position += events.size();
+            skipNum -= events.size();
+            events.clear();
+            // the remove below throws NoSuchElementException if there
+            // are no more generators, which is correct as then we can't
+            // skip over enough events
+            generators.removeFirst().run();
         }
-        return createChildGenerator(name, MISSING_NODE, after);
+        position += skipNum;
+        events.subList(0, (int) skipNum).clear();
     }
 
     @Override
-    public MoveValidator childNodeChanged(String name, NodeState before, NodeState after) throws CommitFailedException {
-        if (filter.includeChange(name, before, after)) {
-            listener.childNodeChanged(name, before, after);
+    public Event nextEvent() {
+        if (hasNext()) {
+            position++;
+            return events.removeFirst();
+        } else {
+            throw new NoSuchElementException();
         }
-        return createChildGenerator(name, before, after);
     }
 
     @Override
-    public MoveValidator childNodeDeleted(String name, NodeState before) throws CommitFailedException {
-        if (filter.includeDelete(name, before)) {
-            listener.childNodeDeleted(name, before);
-        }
-        return createChildGenerator(name, before, MISSING_NODE);
+    public Event next() {
+        return nextEvent();
     }
 
-    /**
-     * Factory method for creating {@code EventGenerator} instances of child nodes.
-     * @param name  name of the child node
-     * @param before  before state of the child node
-     * @param after  after state of the child node
-     * @return {@code EventGenerator} for a child node
-     */
-    protected EventGenerator createChildGenerator(String name, NodeState before, NodeState after) {
-        EventFilter childFilter = filter.create(name, before, after);
-        if (childFilter != null) {
-            return new EventGenerator(
-                    childFilter,
-                    listener.create(name, before, after));
-        } else {
-            return null;
-        }
+    @Override
+    public void remove() {
+        throw new UnsupportedOperationException();
     }
+
 }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/filter/EventFilter.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/filter/EventFilter.java?rev=1561710&r1=1561709&r2=1561710&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/filter/EventFilter.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/filter/EventFilter.java Mon Jan 27 15:24:51 2014
@@ -21,11 +21,10 @@ package org.apache.jackrabbit.oak.plugin
 import javax.annotation.CheckForNull;
 
 import org.apache.jackrabbit.oak.api.PropertyState;
-import org.apache.jackrabbit.oak.plugins.observation.EventGenerator.Listener;
 import org.apache.jackrabbit.oak.spi.state.NodeState;
 
 /**
- * Filter for determining what changes to report the the {@link Listener}.
+ * Filter for determining what changes to report the the event listener.
  */
 public interface EventFilter {
 

Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/filter/VisibleFilter.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/filter/VisibleFilter.java?rev=1561710&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/filter/VisibleFilter.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/filter/VisibleFilter.java Mon Jan 27 15:24:51 2014
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.jackrabbit.oak.plugins.observation.filter;
+
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+
+/**
+ * Event filter that hides all non-visible content.
+ */
+public class VisibleFilter implements EventFilter {
+
+    private boolean isVisible(String name) {
+        return !name.startsWith(":");
+    }
+
+    @Override
+    public boolean includeAdd(PropertyState after) {
+        return isVisible(after.getName());
+    }
+
+    @Override
+    public boolean includeChange(PropertyState before, PropertyState after) {
+        return isVisible(after.getName());
+    }
+
+    @Override
+    public boolean includeDelete(PropertyState before) {
+        return isVisible(before.getName());
+    }
+
+    @Override
+    public boolean includeAdd(String name, NodeState after) {
+        return isVisible(name);
+    }
+
+    @Override
+    public boolean includeChange(String name, NodeState before, NodeState after) {
+        return isVisible(name);
+    }
+
+    @Override
+    public boolean includeDelete(String name, NodeState before) {
+        return isVisible(name);
+    }
+
+    @Override
+    public boolean includeMove(String sourcePath, String name, NodeState moved) {
+        return isVisible(name);
+    }
+
+    @Override
+    public EventFilter create(String name, NodeState before, NodeState after) {
+        if (isVisible(name)) {
+            return this;
+        } else {
+            return null;
+        }
+    }
+
+}

Propchange: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/filter/VisibleFilter.java
------------------------------------------------------------------------------
    svn:eol-style = native



Re: svn commit: r1561710 - in /jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation: ./ filter/

Posted by Michael Dürig <mi...@gmail.com>.

On 27.1.14 6:17 , Jukka Zitting wrote:
> How about I restore the mechanism, but in a way that generalizes the
> nice continuation feature you added for JCR events?

Makes sense. The distinction between EventIterable and EventGenerator is 
probably not too useful and merging these into a single class as you did 
makes sense. However having a mechanism for hooking up a custom listener 
is useful for cases where you want to handle these callbacks directly 
for one reason or another.

Michael

Re: svn commit: r1561710 - in /jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation: ./ filter/

Posted by Jukka Zitting <ju...@gmail.com>.
Hi,

On Mon, Jan 27, 2014 at 11:48 AM, Michael Dürig <md...@apache.org> wrote:
> Have a look at the EventGenerator constructor before your changes. There you
> could pass in a Listener instance which then would receive the respective
> call backs. The JcrListner class was just one such Listener implementation,
> materialising the call backs to EventImpl instances. The idea was that low
> level implementation could use this for their own purposes when a different
> materialisation was needed (e.g. including jcr:content).

OK, thanks. It seemed as if this mechanism was no longer used as the
EventIterable class overrode key parts of it to postpone traversal of
the changed subtrees.

How about I restore the mechanism, but in a way that generalizes the
nice continuation feature you added for JCR events?

BR,

Jukka Zitting

Re: svn commit: r1561710 - in /jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation: ./ filter/

Posted by Michael Dürig <md...@apache.org>.

On 27.1.14 5:20 , Jukka Zitting wrote:
> Hi,
>
> On Mon, Jan 27, 2014 at 10:42 AM, Michael Dürig <md...@apache.org> wrote:
>> This renders much of my work from OAK-1133 useless as now there is no way to
>> plug in a custom listener.
>
> Hmm, perhaps I'm mistaking the pluggability that was built in
> OAK-1133. My assumption was that it was mostly in the EventFilter
> mechanism, which I didn't touch.
>
> Can you provide an example of the kind of code that I broke?

Have a look at the EventGenerator constructor before your changes. There 
you could pass in a Listener instance which then would receive the 
respective call backs. The JcrListner class was just one such Listener 
implementation, materialising the call backs to EventImpl instances. The 
idea was that low level implementation could use this for their own 
purposes when a different materialisation was needed (e.g. including 
jcr:content).

Michael

>
> BR,
>
> Jukka Zitting
>

Re: svn commit: r1561710 - in /jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation: ./ filter/

Posted by Jukka Zitting <ju...@gmail.com>.
Hi,

On Mon, Jan 27, 2014 at 10:42 AM, Michael Dürig <md...@apache.org> wrote:
> This renders much of my work from OAK-1133 useless as now there is no way to
> plug in a custom listener.

Hmm, perhaps I'm mistaking the pluggability that was built in
OAK-1133. My assumption was that it was mostly in the EventFilter
mechanism, which I didn't touch.

Can you provide an example of the kind of code that I broke?

BR,

Jukka Zitting

Re: svn commit: r1561710 - in /jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation: ./ filter/

Posted by Michael Dürig <md...@apache.org>.

On 27.1.14 4:24 , jukka@apache.org wrote:
> Author: jukka
> Date: Mon Jan 27 15:24:51 2014
> New Revision: 1561710
>
> URL:http://svn.apache.org/r1561710
> Log:
> OAK-1332: Large number of changes to the same node can fill observation queue
>
> Merge EventIterable and JcrListener to EventGenerator to simplify the code
> and to use just a single list of events as the event queue.

This renders much of my work from OAK-1133 useless as now there is no 
way to plug in a custom listener.

Michael