Author: stefanegli
Date: Wed Nov  2 13:11:10 2016
New Revision: 1767668

URL: http://svn.apache.org/viewvc?rev=1767668&view=rev
Log:
OAK-4916 : adding support for excluding commits to BackgroundObserver via a 
composing FilteringObserver: the FilteringObserver wraps a BackgroundObserver 
and only forwards content changes that are not excluded

Added:
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/Filter.java
   (with props)
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/FilteringAwareObserver.java
   (with props)
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/FilteringDispatcher.java
   (with props)
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/FilteringObserver.java
   (with props)

Added: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/Filter.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/Filter.java?rev=1767668&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/Filter.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/Filter.java
 Wed Nov  2 13:11:10 2016
@@ -0,0 +1,46 @@
+/*
+ * 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;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+
+/**
+ * A filter is used by the FilteringObserver to decide whether or not a content
+ * change should be forwarded.
+ */
+public interface Filter {
+
+    /**
+     * Whether or not to exclude a particular content change from being
+     * forwarded to downstream observers.
+     * 
+     * @param root
+     *            the new root state
+     * @param info
+     *            the associated CommitInfo
+     * @return true to exclude this content change (not forward), false to
+     *         include it (forward)
+     */
+    public boolean excludes(@Nonnull NodeState root, @Nullable CommitInfo 
info);
+
+}

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

Added: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/FilteringAwareObserver.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/FilteringAwareObserver.java?rev=1767668&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/FilteringAwareObserver.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/FilteringAwareObserver.java
 Wed Nov  2 13:11:10 2016
@@ -0,0 +1,49 @@
+/*
+ * 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;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+
+/**
+ * A FilteringAwareObserver is the stateless-variant of
+ * an Observer which gets an explicit before as well as the
+ * after NodeState.
+ * <p>
+ * It is used by the FilteringObserver (or more precisely
+ * by the FilteringDispatcher) to support skipping (ie filtering)
+ * of content changes.
+ */
+public interface FilteringAwareObserver {
+
+    /**
+     * Equivalent to the state-full contentChanged() method of the Observer
+     * with one important difference being that this variation explicitly
+     * passes the before NodeState (thus the observer must in this case
+     * not remember the previous state)
+     * @param before the before NodeState
+     * @param after the after NodeState
+     * @param info the associated CommitInfo
+     */
+    public void contentChanged(@Nonnull NodeState before, @Nonnull NodeState 
after, @Nullable CommitInfo info);
+    
+}

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

Added: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/FilteringDispatcher.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/FilteringDispatcher.java?rev=1767668&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/FilteringDispatcher.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/FilteringDispatcher.java
 Wed Nov  2 13:11:10 2016
@@ -0,0 +1,55 @@
+/*
+ * 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;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
+import org.apache.jackrabbit.oak.spi.commit.Observer;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+
+/**
+ * Part of the FilteringObserver: the FilteringDispatcher is used
+ * to implement the skipping (filtering) of content changes
+ * which the FilteringDispatcher flags as NOOP_CHANGE.
+ * When the FilteringDispatcher notices a NOOP_CHANGE it does
+ * not forward the change but only updates the before NodeState.
+ */
+public class FilteringDispatcher implements Observer {
+    
+    private final FilteringAwareObserver observer;
+
+    private NodeState before;
+
+    public FilteringDispatcher(FilteringAwareObserver observer) {
+        this.observer = checkNotNull(observer);
+    }
+
+    @Override
+    public void contentChanged(@Nonnull NodeState root,
+                               @Nullable CommitInfo info) {
+        if (info != FilteringObserver.NOOP_CHANGE) {
+            observer.contentChanged(before, root, info);
+        }
+        before = root;
+    }
+}
\ No newline at end of file

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

Added: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/FilteringObserver.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/FilteringObserver.java?rev=1767668&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/FilteringObserver.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/FilteringObserver.java
 Wed Nov  2 13:11:10 2016
@@ -0,0 +1,113 @@
+/*
+ * 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;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.io.Closeable;
+import java.util.concurrent.Executor;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.apache.jackrabbit.oak.spi.commit.BackgroundObserver;
+import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
+import org.apache.jackrabbit.oak.spi.commit.Observer;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+
+/**
+ * An observer that implements filtering of content changes
+ * while at the same time supporting (wrapping) a BackgroundObserver
+ * underneath.
+ * <p>
+ * The FilteringObserver uses an explicit Filter to decide whether
+ * or not to forward a content change to the BackgroundObserver.
+ * If the Filter decides to include the change things happen as usual.
+ * If the Filter decides to exclude the change, this FilteringObserver
+ * does not forward the change, but remembers the fact that the last
+ * change was filtered. The first included change after excluded ones
+ * will cause a NOOP_CHANGE commitInfo to be passed along to the
+ * BackgroundObserver. That NOOP_CHANGE is then used by the
+ * FilteringDispatcher: if a CommitInfo is a NOOP_CHANGE then the
+ * FilteringDispatcher will not forward anything to the FilteringAwareObserver
+ * and only adjust the 'before' state accordingly (which it does also
+ * for a NOOP_CHANGE, to exactly achieve the skipping effect).
+ */
+public class FilteringObserver implements Observer, Closeable {
+
+    /** package protected CommitInfo used between FilteringObserver and 
FilteringDispatcher **/
+    final static CommitInfo NOOP_CHANGE = new 
CommitInfo(CommitInfo.OAK_UNKNOWN, CommitInfo.OAK_UNKNOWN);
+
+    private final BackgroundObserver backgroundObserver;
+
+    private final Filter filter;
+
+    private NodeState lastNoop;
+
+    /**
+     * Default constructor which creates a BackgroundObserver automatically, 
including
+     * creating a FilteringDispatcher.
+     * @param executor the executor that should be used for the 
BackgroundObserver
+     * @param queueLength the queue length of the BackgroundObserver
+     * @param filter the Filter to be used for filtering
+     * @param observer the FilteringAwareObserver to which content changes 
ultimately
+     * are delivered after going through a chain of 
+     * FilteringObserver->BackgroundObserver->FilteringDispatcher.
+     */
+    public FilteringObserver(@Nonnull Executor executor, int queueLength, 
@Nonnull Filter filter,
+            @Nonnull FilteringAwareObserver observer) {
+        this(new BackgroundObserver(new 
FilteringDispatcher(checkNotNull(observer)), checkNotNull(executor),
+                queueLength), filter);
+    }
+
+    /**
+     * Alternative constructor where the BackgroundObserver is created 
elsewhere
+     * @param backgroundObserver the BackgroundObserver to be used by this 
FilteringObserver
+     * @param filter the Filter to be used for filtering
+     */
+    public FilteringObserver(@Nonnull BackgroundObserver backgroundObserver, 
@Nonnull Filter filter) {
+        this.backgroundObserver = backgroundObserver;
+        this.filter = checkNotNull(filter);
+    }
+
+    public BackgroundObserver getBackgroundObserver() {
+        return backgroundObserver;
+    }
+
+    @Override
+    public final void contentChanged(@Nonnull NodeState root, @Nullable 
CommitInfo info) {
+        if (filter.excludes(root, info)) {
+            lastNoop = root;
+            return;
+        }
+        // current change is not an noop
+        if (lastNoop != null) {
+            // report up to previous noop
+            backgroundObserver.contentChanged(lastNoop, NOOP_CHANGE);
+            lastNoop = null;
+        }
+        backgroundObserver.contentChanged(root, info);
+    }
+
+    @Override
+    public void close() {
+        backgroundObserver.close();
+    }
+
+}

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


Reply via email to