Author: catholicon
Date: Wed Nov 16 04:07:12 2016
New Revision: 1769922
URL: http://svn.apache.org/viewvc?rev=1769922&view=rev
Log:
OAK-3001: Simplify JournalGarbageCollector using a dedicated timestamp property
----Sub-tasks-----
OAK-3982: DocumentStore: add method to remove with a condition on an indexed
property
OAK-3985: MongoDocumentStore: implement new conditional remove method
OAK-3984: RDBDocumentStore: implement new conditional remove method
OAK-3983: JournalGarbageCollector: use new DocumentStore remove() method
Added interface method and implemented in Mem/Mongo/RDBDocStore as well as in
DocStoreWrappers.
Added test in BasicDocumentStoreTest against the new method. JournalGC tests
pass, so no new one added there.
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentStore.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/JournalGarbageCollector.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/memory/MemoryDocumentStore.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStore.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStore.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStoreJDBC.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/util/LeaseCheckDocumentStoreWrapper.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/util/LoggingDocumentStoreWrapper.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/util/SynchronizingDocumentStoreWrapper.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/util/TimingDocumentStoreWrapper.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/BasicDocumentStoreTest.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/CountingDocumentStore.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentStoreWrapper.java
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentStore.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentStore.java?rev=1769922&r1=1769921&r2=1769922&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentStore.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentStore.java
Wed Nov 16 04:07:12 2016
@@ -202,6 +202,34 @@ public interface DocumentStore {
Map<String, Map<UpdateOp.Key,
UpdateOp.Condition>> toRemove)
throws DocumentStoreException;
+
+ /**
+ * Batch remove documents where the given "indexed property" is within the
given
+ * range (inclusive) - {@code [startValue, endValue]}.
+ * <p>
+ * The indexed property is a {@link Long} value and numeric comparison
applies.
+ * <p>
+ * In case of a {@code DocumentStoreException}, the documents with the
given
+ * keys may or may not have been removed from the store. It may also be
+ * possible that only some have been removed from the store. It is the
+ * responsibility of the caller to check which documents still exist. The
+ * implementation however ensures that the result of the operation is
+ * properly reflected in the document cache. That is, an implementation
+ * could simply evict documents with the given keys from the cache.
+ *
+ * @param <T> the document type
+ * @param collection the collection.
+ * @param indexedProperty the name of the indexed property
+ * @param startValue the minimum value of the indexed property
+ * @param endValue the maximum value of the indexed property
+ * @return the number of removed documents.
+ * @throws DocumentStoreException if the operation failed. E.g. because of
+ * an I/O error.
+ */
+ <T extends Document> int remove(Collection<T> collection,
+ String indexedProperty, long startValue,
long endValue)
+ throws DocumentStoreException;
+
/**
* Try to create a list of documents. This method returns {@code true} iff
* none of the documents existed before and the create was successful. This
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/JournalGarbageCollector.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/JournalGarbageCollector.java?rev=1769922&r1=1769921&r2=1769922&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/JournalGarbageCollector.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/JournalGarbageCollector.java
Wed Nov 16 04:07:12 2016
@@ -90,68 +90,11 @@ public class JournalGarbageCollector {
}
Stopwatch sw = Stopwatch.createStarted();
- // the journal has ids of the following format:
- // 1-0000014db9aaf710-00000001
- // whereas the first number is the cluster node id.
- // now, this format prevents from doing a generic
- // query to get all 'old' entries, as the documentstore
- // can only query for a sequential list of entries.
- // (and the cluster node id here partitions the set
- // of entries that we have to delete)
- // To account for that, we simply iterate over all
- // cluster node ids and clean them up individually.
- // Note that there are possible alternatives, such
- // as: let each node clean up its own old entries
- // but the chosen path is also quite simple: it can
- // be started on any instance - but best on only one.
- // if it's run on multiple concurrently, then they
- // will compete at deletion, which is not optimal
- // due to performance, but does not harm.
-
// update the tail timestamp in the journalGC document
// of the settings collection
updateTailTimestamp(gcOlderThan);
- // 1. get the list of cluster node ids
- final List<ClusterNodeInfoDocument> clusterNodeInfos =
ClusterNodeInfoDocument.all(ds);
- int numDeleted = 0;
- for (ClusterNodeInfoDocument clusterNodeInfoDocument :
clusterNodeInfos) {
- // current algorithm is to simply look at all cluster nodes
- // irrespective of whether they are active or inactive etc.
- // this could be optimized for inactive ones: at some point, all
- // journal entries of inactive ones would have been cleaned up
- // and at that point we could stop including those
long-time-inactive ones.
- // that 'long time' aspect would have to be tracked though, to be
sure
- // we don't leave garbage.
- // so simpler is to quickly do a query even for long-time inactive
ones
- final int clusterNodeId = clusterNodeInfoDocument.getClusterId();
-
- // 2. iterate over that list and do a query with
- // a limit of 'batch size'
- boolean branch = false;
- long startPointer = 0;
- while (true) {
- String fromKey = JournalEntry.asId(new Revision(startPointer,
0, clusterNodeId, branch));
- String toKey = JournalEntry.asId(new Revision(gcOlderThan, 0,
clusterNodeId, branch));
- List<JournalEntry> deletionBatch =
ds.query(Collection.JOURNAL, fromKey, toKey, batchSize);
- if (deletionBatch.size() > 0) {
- ds.remove(Collection.JOURNAL, asKeys(deletionBatch));
- numDeleted += deletionBatch.size();
- }
- if (deletionBatch.size() < batchSize) {
- if (!branch) {
- // do the same for branches:
- // this will start at the beginning again with branch
set to true
- // and eventually finish too
- startPointer = 0;
- branch = true;
- continue;
- }
- break;
- }
- startPointer = deletionBatch.get(deletionBatch.size() -
1).getRevisionTimestamp();
- }
- }
+ int numDeleted = ds.remove(Collection.JOURNAL, JournalEntry.MODIFIED,
0, gcOlderThan);
sw.stop();
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/memory/MemoryDocumentStore.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/memory/MemoryDocumentStore.java?rev=1769922&r1=1769921&r2=1769922&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/memory/MemoryDocumentStore.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/memory/MemoryDocumentStore.java
Wed Nov 16 04:07:12 2016
@@ -27,8 +27,11 @@ import java.util.concurrent.locks.Reentr
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
import org.apache.jackrabbit.oak.cache.CacheStats;
import org.apache.jackrabbit.oak.plugins.document.Collection;
import org.apache.jackrabbit.oak.plugins.document.Document;
@@ -44,6 +47,7 @@ import com.google.common.base.Splitter;
import com.mongodb.ReadPreference;
import com.mongodb.WriteConcern;
import org.apache.jackrabbit.oak.plugins.document.cache.CacheInvalidationStats;
+import org.apache.jackrabbit.oak.plugins.document.util.Utils;
import static
org.apache.jackrabbit.oak.plugins.document.UpdateUtils.assertUnconditional;
import static
org.apache.jackrabbit.oak.plugins.document.UpdateUtils.checkConditions;
@@ -202,6 +206,31 @@ public class MemoryDocumentStore impleme
return num;
}
+ @Override
+ public <T extends Document> int remove(Collection<T> collection,
+ final String indexedProperty, final long
startValue, final long endValue)
+ throws DocumentStoreException {
+ ConcurrentSkipListMap<String, T> map = getMap(collection);
+ int num = map.size();
+
+ Lock lock = rwLock.writeLock();
+ lock.lock();
+ try {
+ Maps.filterValues(map, new Predicate<T>() {
+ @Override
+ public boolean apply(@Nullable T doc) {
+ Long modified = Utils.asLong((Number)
doc.get(indexedProperty));
+ return startValue <= modified && modified <= endValue;
+ }
+ }).clear();
+ } finally {
+ lock.unlock();
+ }
+
+ num -= map.size();
+ return num;
+ }
+
@CheckForNull
@Override
public <T extends Document> T createOrUpdate(Collection<T> collection,
UpdateOp update) {
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStore.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStore.java?rev=1769922&r1=1769921&r2=1769922&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStore.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStore.java
Wed Nov 16 04:07:12 2016
@@ -764,6 +764,39 @@ public class MongoDocumentStore implemen
return num;
}
+ @Override
+ public <T extends Document> int remove(Collection<T> collection,
+ String indexedProperty, long startValue,
long endValue)
+ throws DocumentStoreException {
+ log("remove", collection, indexedProperty, startValue, endValue);
+ int num = 0;
+ DBCollection dbCollection = getDBCollection(collection);
+ long start = PERFLOG.start();
+ try {
+ QueryBuilder queryBuilder = QueryBuilder.start(indexedProperty);
+ queryBuilder.greaterThanEquals(startValue);
+ queryBuilder.lessThanEquals(endValue);
+ try {
+ num = dbCollection.remove(queryBuilder.get()).getN();
+ } catch (Exception e) {
+ throw DocumentStoreException.convert(e, "Remove failed for " +
collection + ": " +
+ indexedProperty + " in [" + startValue + ", " + endValue +
"]");
+ } finally {
+ if (num > 0 && collection == Collection.NODES) {
+ // this method is currently being used only for Journal
collection while GC.
+ // But, to keep sanctity of the API, we need to
acknowledge that Nodes collection
+ // could've been used. But, in this signature, there's no
useful way to invalidate
+ // cache.
+ // So, we use the hammer for this task
+ invalidateCache();
+ }
+ }
+ } finally {
+ PERFLOG.end(start, 1, "remove from {}: {} in [{}, {}]",
collection, indexedProperty, startValue, endValue);
+ }
+ return num;
+ }
+
@SuppressWarnings("unchecked")
@CheckForNull
private <T extends Document> T findAndModify(Collection<T> collection,
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStore.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStore.java?rev=1769922&r1=1769921&r2=1769922&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStore.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStore.java
Wed Nov 16 04:07:12 2016
@@ -279,6 +279,27 @@ public class RDBDocumentStore implements
}
@Override
+ public <T extends Document> int remove(Collection<T> collection,
+ String indexedProperty, long startValue,
long endValue)
+ throws DocumentStoreException {
+ int num = 0;
+ try {
+ num = delete(collection, indexedProperty, startValue, endValue);
+ } finally {
+ if (num > 0 && collection == Collection.NODES) {
+ // this method is currently being used only for Journal
collection while GC.
+ // But, to keep sanctity of the API, we need to acknowledge
that Nodes collection
+ // could've been used. But, in this signature, there's no
useful way to invalidate
+ // cache.
+ // So, we use the hammer for this task
+ invalidateCache();
+ }
+ }
+ return num;
+ }
+
+
+ @Override
public <T extends Document> boolean create(Collection<T> collection,
List<UpdateOp> updateOps) {
return internalCreate(collection, updateOps);
}
@@ -1565,6 +1586,23 @@ public class RDBDocumentStore implements
}
return numDeleted;
}
+
+ private <T extends Document> int delete(Collection<T> collection,
+ String indexedProperty, long
startVal, long endVal) {
+ int numDeleted = 0;
+ RDBTableMetaData tmd = getTable(collection);
+ Connection connection = null;
+ try {
+ connection = this.ch.getRWConnection();
+ numDeleted = db.delete(connection, tmd, indexedProperty, startVal,
endVal);
+ connection.commit();
+ } catch (Exception ex) {
+ throw DocumentStoreException.convert(ex, "deleting " + collection
+ ": " + indexedProperty + " in [" + startVal + ", " + endVal + "]");
+ } finally {
+ this.ch.closeConnection(connection);
+ }
+ return numDeleted;
+ }
private <T extends Document> boolean updateDocument(@Nonnull Collection<T>
collection, @Nonnull T document,
@Nonnull UpdateOp update, Long oldmodcount) {
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStoreJDBC.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStoreJDBC.java?rev=1769922&r1=1769921&r2=1769922&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStoreJDBC.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStoreJDBC.java
Wed Nov 16 04:07:12 2016
@@ -225,6 +225,23 @@ public class RDBDocumentStoreJDBC {
}
}
+ public int delete(Connection connection, RDBTableMetaData tmd, String
property, long startVal, long endVal)
+ throws SQLException, DocumentStoreException {
+ if (!MODIFIED.equals(property)) {
+ throw new DocumentStoreException("Unsupported condition: " +
property + " in [" + startVal + ", " + endVal + "]");
+ }
+ PreparedStatement stmt = connection.prepareStatement("delete from " +
tmd.getName() +
+ " where MODIFIED >= ? AND MODIFIED <= ?");
+ try {
+ int i = 1;
+ stmt.setLong(i++, startVal);
+ stmt.setLong(i++, endVal);
+ return stmt.executeUpdate();
+ } finally {
+ stmt.close();
+ }
+ }
+
public long determineServerTimeDifferenceMillis(Connection connection) {
String sql = this.dbInfo.getCurrentTimeStampInSecondsSyntax();
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/util/LeaseCheckDocumentStoreWrapper.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/util/LeaseCheckDocumentStoreWrapper.java?rev=1769922&r1=1769921&r2=1769922&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/util/LeaseCheckDocumentStoreWrapper.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/util/LeaseCheckDocumentStoreWrapper.java
Wed Nov 16 04:07:12 2016
@@ -26,6 +26,7 @@ import org.apache.jackrabbit.oak.plugins
import org.apache.jackrabbit.oak.plugins.document.Collection;
import org.apache.jackrabbit.oak.plugins.document.Document;
import org.apache.jackrabbit.oak.plugins.document.DocumentStore;
+import org.apache.jackrabbit.oak.plugins.document.DocumentStoreException;
import org.apache.jackrabbit.oak.plugins.document.RevisionListener;
import org.apache.jackrabbit.oak.plugins.document.RevisionVector;
import org.apache.jackrabbit.oak.plugins.document.UpdateOp;
@@ -108,6 +109,14 @@ public final class LeaseCheckDocumentSto
}
@Override
+ public<T extends Document> int remove(Collection<T> collection,
+ String indexedProperty, long
startValue, long endValue)
+ throws DocumentStoreException {
+ performLeaseCheck();
+ return delegate.remove(collection, indexedProperty, startValue,
endValue);
+ }
+
+ @Override
public final <T extends Document> boolean create(Collection<T> collection,
List<UpdateOp> updateOps) {
performLeaseCheck();
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/util/LoggingDocumentStoreWrapper.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/util/LoggingDocumentStoreWrapper.java?rev=1769922&r1=1769921&r2=1769922&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/util/LoggingDocumentStoreWrapper.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/util/LoggingDocumentStoreWrapper.java
Wed Nov 16 04:07:12 2016
@@ -173,6 +173,24 @@ public class LoggingDocumentStoreWrapper
}
@Override
+ public <T extends Document> int remove(final Collection<T> collection,
+ final String indexedProperty, final
long startValue, final long endValue)
+ throws DocumentStoreException {
+ try {
+ logMethod("remove", collection, indexedProperty, startValue,
endValue);
+ return logResult(new Callable<Integer>() {
+ @Override
+ public Integer call() throws Exception {
+ return store.remove(collection, indexedProperty,
startValue, endValue);
+ }
+ });
+ } catch (Exception e) {
+ logException(e);
+ throw convert(e);
+ }
+ }
+
+ @Override
public <T extends Document> boolean create(final Collection<T> collection,
final List<UpdateOp> updateOps)
{
try {
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/util/SynchronizingDocumentStoreWrapper.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/util/SynchronizingDocumentStoreWrapper.java?rev=1769922&r1=1769921&r2=1769922&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/util/SynchronizingDocumentStoreWrapper.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/util/SynchronizingDocumentStoreWrapper.java
Wed Nov 16 04:07:12 2016
@@ -25,6 +25,7 @@ import org.apache.jackrabbit.oak.cache.C
import org.apache.jackrabbit.oak.plugins.document.Collection;
import org.apache.jackrabbit.oak.plugins.document.Document;
import org.apache.jackrabbit.oak.plugins.document.DocumentStore;
+import org.apache.jackrabbit.oak.plugins.document.DocumentStoreException;
import org.apache.jackrabbit.oak.plugins.document.RevisionListener;
import org.apache.jackrabbit.oak.plugins.document.RevisionVector;
import org.apache.jackrabbit.oak.plugins.document.UpdateOp;
@@ -83,6 +84,13 @@ public class SynchronizingDocumentStoreW
}
@Override
+ public <T extends Document> int remove(Collection<T> collection,
+ String indexedProperty, long
startValue, long endValue)
+ throws DocumentStoreException {
+ return store.remove(collection, indexedProperty, startValue, endValue);
+ }
+
+ @Override
public synchronized <T extends Document> boolean create(final
Collection<T> collection, final List<UpdateOp> updateOps) {
return store.create(collection, updateOps);
}
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/util/TimingDocumentStoreWrapper.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/util/TimingDocumentStoreWrapper.java?rev=1769922&r1=1769921&r2=1769922&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/util/TimingDocumentStoreWrapper.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/util/TimingDocumentStoreWrapper.java
Wed Nov 16 04:07:12 2016
@@ -212,6 +212,25 @@ public class TimingDocumentStoreWrapper
}
@Override
+ public <T extends Document> int remove(Collection<T> collection,
+ String indexedProperty, long
startValue, long endValue)
+ throws DocumentStoreException {
+ try {
+ long start = now();
+ int result = base.remove(collection, indexedProperty, startValue,
endValue);
+ updateAndLogTimes("remove", start, 0, 0);
+ if (logCommonCall()) {
+ logCommonCall(start, "remove " + collection + ";
indexedProperty" + indexedProperty +
+ "; range - [" + startValue + ", " + endValue + "]");
+ }
+ return result;
+ } catch (Exception e) {
+ throw convert(e);
+ }
+ }
+
+
+ @Override
public <T extends Document> boolean create(Collection<T> collection,
List<UpdateOp> updateOps) {
try {
long start = now();
Modified:
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/BasicDocumentStoreTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/BasicDocumentStoreTest.java?rev=1769922&r1=1769921&r2=1769922&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/BasicDocumentStoreTest.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/BasicDocumentStoreTest.java
Wed Nov 16 04:07:12 2016
@@ -41,8 +41,11 @@ import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.common.collect.ContiguousSet;
+import com.google.common.collect.DiscreteDomain;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
+import com.google.common.collect.Range;
public class BasicDocumentStoreTest extends AbstractDocumentStoreTest {
@@ -357,6 +360,50 @@ public class BasicDocumentStoreTest exte
}
}
+ //OAK-3001
+ @Test
+ public void testRangeRemove() {
+ String idPrefix = this.getClass().getName() + ".testRangeRemove";
+
+ com.google.common.collect.Range<Long> modTimes = Range.closed(1L, 30L);
+ for (Long modTime : ContiguousSet.create(modTimes,
DiscreteDomain.longs())) {
+ String id = idPrefix + modTime;
+ // remove if present
+ Document d = super.ds.find(Collection.JOURNAL, id);
+ if (d != null) {
+ super.ds.remove(Collection.JOURNAL, id);
+ }
+
+ // add
+ UpdateOp up = new UpdateOp(id, true);
+ up.set("_id", id);
+ up.set("_modified", modTime);
+ super.ds.create(Collection.JOURNAL, Collections.singletonList(up));
+ }
+
+ assertEquals("Number of entries removed didn't match", 5,
+ ds.remove(Collection.JOURNAL, "_modified", 20, 24));
+
+ assertEquals("Number of entries removed didn't match", 0,
+ ds.remove(Collection.JOURNAL, "_modified", 20, 24));
+
+ assertEquals("Number of entries removed didn't match", 5,
+ ds.remove(Collection.JOURNAL, "_modified", -1, 5));
+
+ assertEquals("Number of entries removed didn't match", 5,
+ ds.remove(Collection.JOURNAL, "_modified", 0, 10));
+
+ // interesting cases
+ assertEquals("Number of entries removed didn't match", 0,
+ ds.remove(Collection.JOURNAL, "_modified", 20, 19));
+
+ assertEquals("Number of entries removed didn't match", 0,
+ ds.remove(Collection.JOURNAL, "_modified", 31, 40));
+
+ assertEquals("Number of entries removed didn't match", 3,
+ ds.remove(Collection.JOURNAL, "_modified", 28, 40));
+ }
+
private int testMaxId(boolean ascii) {
int min = 0;
int max = 32768;
Modified:
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/CountingDocumentStore.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/CountingDocumentStore.java?rev=1769922&r1=1769921&r2=1769922&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/CountingDocumentStore.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/CountingDocumentStore.java
Wed Nov 16 04:07:12 2016
@@ -149,6 +149,14 @@ public class CountingDocumentStore imple
}
@Override
+ public <T extends Document> int remove(Collection<T> collection,
+ String indexedProperty, long
startValue, long endValue)
+ throws DocumentStoreException {
+ getStats(collection).numRemoveCalls++;
+ return delegate.remove(collection, indexedProperty, startValue,
endValue);
+ }
+
+ @Override
public <T extends Document> boolean create(Collection<T> collection,
List<UpdateOp> updateOps) {
getStats(collection).numCreateOrUpdateCalls++;
Modified:
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentStoreWrapper.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentStoreWrapper.java?rev=1769922&r1=1769921&r2=1769922&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentStoreWrapper.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentStoreWrapper.java
Wed Nov 16 04:07:12 2016
@@ -88,6 +88,13 @@ public class DocumentStoreWrapper implem
}
@Override
+ public <T extends Document> int remove(Collection<T> collection,
+ String indexedProperty, long
startValue, long endValue)
+ throws DocumentStoreException {
+ return store.remove(collection, indexedProperty, startValue, endValue);
+ }
+
+ @Override
public <T extends Document> boolean create(Collection<T> collection,
List<UpdateOp> updateOps) {
return store.create(collection, updateOps);