You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by ju...@apache.org on 2010/08/20 18:49:32 UTC
svn commit: r987567 - in /jackrabbit/trunk/jackrabbit-jcr-commons/src:
main/java/org/apache/jackrabbit/commons/iterator/
test/java/org/apache/jackrabbit/commons/iterator/
Author: jukka
Date: Fri Aug 20 16:49:32 2010
New Revision: 987567
URL: http://svn.apache.org/viewvc?rev=987567&view=rev
Log:
JCR-2722: Add a filtered RangeIterator
Added:
jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/iterator/FilteredRangeIterator.java (with props)
jackrabbit/trunk/jackrabbit-jcr-commons/src/test/java/org/apache/jackrabbit/commons/iterator/
jackrabbit/trunk/jackrabbit-jcr-commons/src/test/java/org/apache/jackrabbit/commons/iterator/FilteredRangeIteratorTest.java (with props)
Added: jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/iterator/FilteredRangeIterator.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/iterator/FilteredRangeIterator.java?rev=987567&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/iterator/FilteredRangeIterator.java (added)
+++ jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/iterator/FilteredRangeIterator.java Fri Aug 20 16:49:32 2010
@@ -0,0 +1,204 @@
+/*
+ * 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.commons.iterator;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import javax.jcr.RangeIterator;
+
+import org.apache.jackrabbit.commons.predicate.Predicate;
+
+/**
+ * Filtering decorator for iterators.
+ */
+public class FilteredRangeIterator implements RangeIterator {
+
+ /**
+ * The underlying iterator.
+ */
+ private final Iterator<?> iterator;
+
+ /**
+ * Predicate used for filtering.
+ */
+ private final Predicate predicate;
+
+ /**
+ * Buffer of pre-fetched objects from the underlying iterator.
+ */
+ private final Object[] buffer;
+
+ /**
+ * Current position within the buffer. Guaranteed to be within the
+ * range [0, {@link #bufferSize}].
+ */
+ private int bufferPosition = 0;
+
+ /**
+ * Number of pre-fetched objects in the buffer.
+ */
+ private int bufferSize = 0;
+
+ /**
+ * The zero-based position of the first element in the buffer.
+ */
+ private long position = 0;
+
+ /**
+ * The number of filtered items up to the end of the buffer.
+ */
+ private long size = 0;
+
+
+ /**
+ * Creates a new filtered iterator.
+ *
+ * @param iterator underlying iterator
+ * @param predicate
+ * @param bufferSize
+ */
+ public FilteredRangeIterator(
+ Iterator<?> iterator, Predicate predicate, int bufferSize) {
+ this.iterator = iterator;
+ this.predicate = predicate;
+ this.buffer = new Object[bufferSize];
+ }
+
+ /**
+ * Creates a new filtered iterator with the default pre-fetch buffer size.
+ *
+ * @param iterator underlying iterator
+ * @param predicate predicate used for filtering
+ */
+ public FilteredRangeIterator(Iterator<?> iterator, Predicate predicate) {
+ this(iterator, predicate, 1000);
+ }
+
+ /**
+ * Creates a pre-fetching decorator for the given iterator. This
+ * constructor is mostly useful when it is desirable to use the
+ * pre-fetching feature to automatically
+ *
+ *
+ * @param iterator underlying iterator
+ * @param predicate predicate used for filtering
+ */
+ public FilteredRangeIterator(Iterator<?> iterator) {
+ this(iterator, Predicate.TRUE, 1000);
+ }
+
+ /**
+ * Pre-fetches more items into the buffer.
+ */
+ private void fetch() {
+ if (bufferPosition == bufferSize) {
+ position += bufferSize;
+ bufferPosition = 0;
+ bufferSize = 0;
+ while (bufferSize < buffer.length && iterator.hasNext()) {
+ Object object = iterator.next();
+ if (predicate.evaluate(object)) {
+ buffer[bufferSize++] = object;
+ }
+ }
+ size += bufferSize;
+ }
+ }
+
+ /**
+ * Returns the zero-based position of the next element in this iterator.
+ *
+ * @return position of the next element
+ */
+ public long getPosition() {
+ return position + bufferPosition;
+ }
+
+ /**
+ * Returns the total number of elements in this iterator, or -1 if that
+ * number is unknown.
+ *
+ * @return number of elements in this iterator, or -1
+ */
+ public long getSize() {
+ fetch();
+ if (iterator.hasNext()) {
+ return -1; // still unknown
+ } else {
+ return size;
+ }
+ }
+
+ /**
+ * Skips the next n elements.
+ *
+ * @param n number of elements to skip
+ * @throws IllegalArgumentException if n is negative
+ * @throws NoSuchElementException if there are not enough elements to skip
+ */
+ public void skip(long n)
+ throws IllegalArgumentException, NoSuchElementException {
+ if (n < 0) {
+ throw new IllegalArgumentException();
+ }
+ while (n > 0) {
+ fetch();
+ if (bufferPosition < bufferSize) {
+ long m = Math.min(n, bufferSize - bufferPosition);
+ bufferPosition += m;
+ n -= m;
+ } else {
+ throw new NoSuchElementException();
+ }
+ }
+ }
+
+ /**
+ * Checks whether there are more elements in this iterator.
+ *
+ * @return <code>true</code> if there are more elements,
+ * <code>false</code> otherwise
+ */
+ public boolean hasNext() {
+ fetch();
+ return bufferPosition < bufferSize;
+ }
+
+ /**
+ * Returns the next element in this iterator.
+ *
+ * @return next element
+ * @throws NoSuchElementException if there are no more elements
+ */
+ public Object next() throws NoSuchElementException {
+ fetch();
+ if (bufferPosition < bufferSize) {
+ return buffer[bufferPosition++];
+ } else {
+ throw new NoSuchElementException();
+ }
+ }
+
+ /**
+ * Not supported.
+ */
+ public void remove() throws UnsupportedOperationException {
+ throw new UnsupportedOperationException();
+ }
+
+}
Propchange: jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/iterator/FilteredRangeIterator.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: jackrabbit/trunk/jackrabbit-jcr-commons/src/test/java/org/apache/jackrabbit/commons/iterator/FilteredRangeIteratorTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr-commons/src/test/java/org/apache/jackrabbit/commons/iterator/FilteredRangeIteratorTest.java?rev=987567&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr-commons/src/test/java/org/apache/jackrabbit/commons/iterator/FilteredRangeIteratorTest.java (added)
+++ jackrabbit/trunk/jackrabbit-jcr-commons/src/test/java/org/apache/jackrabbit/commons/iterator/FilteredRangeIteratorTest.java Fri Aug 20 16:49:32 2010
@@ -0,0 +1,83 @@
+/*
+ * 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.commons.iterator;
+
+import java.util.Arrays;
+import java.util.List;
+
+import javax.jcr.RangeIterator;
+
+import org.apache.jackrabbit.commons.predicate.Predicate;
+
+import junit.framework.TestCase;
+
+/**
+ * Test cases for the {@link FilteredRangeIterator} class.
+ *
+ * @see <a href="https://issues.apache.org/jira/browse/JCR-2722">JCR-2722</a>
+ */
+public class FilteredRangeIteratorTest extends TestCase {
+
+ private static final List<String> LIST = Arrays.asList("x", "y", "z");
+
+ public void testMatchAll() {
+ RangeIterator iterator = new FilteredRangeIterator(LIST.iterator());
+ assertEquals(3, iterator.getSize());
+
+ assertEquals(0, iterator.getPosition());
+ assertTrue(iterator.hasNext());
+ assertEquals("x", iterator.next());
+
+ assertEquals(1, iterator.getPosition());
+ assertTrue(iterator.hasNext());
+ assertEquals("y", iterator.next());
+
+ assertEquals(2, iterator.getPosition());
+ assertTrue(iterator.hasNext());
+ assertEquals("z", iterator.next());
+
+ assertEquals(3, iterator.getPosition());
+ assertFalse(iterator.hasNext());
+ }
+
+ public void testMatchNone() {
+ RangeIterator iterator =
+ new FilteredRangeIterator(LIST.iterator(), Predicate.FALSE);
+ assertEquals(0, iterator.getSize());
+ assertEquals(0, iterator.getPosition());
+ assertFalse(iterator.hasNext());
+ }
+
+ public void testSkip() {
+ RangeIterator iterator = new FilteredRangeIterator(LIST.iterator());
+ assertEquals(3, iterator.getSize());
+
+ assertEquals(0, iterator.getPosition());
+ assertTrue(iterator.hasNext());
+ assertEquals("x", iterator.next());
+
+ iterator.skip(1);
+
+ assertEquals(2, iterator.getPosition());
+ assertTrue(iterator.hasNext());
+ assertEquals("z", iterator.next());
+
+ assertEquals(3, iterator.getPosition());
+ assertFalse(iterator.hasNext());
+ }
+
+}
Propchange: jackrabbit/trunk/jackrabbit-jcr-commons/src/test/java/org/apache/jackrabbit/commons/iterator/FilteredRangeIteratorTest.java
------------------------------------------------------------------------------
svn:eol-style = native