Author: mreutegg
Date: Wed Jun 11 12:00:11 2014
New Revision: 1601865

URL: http://svn.apache.org/r1601865
Log:
OAK-1822: NodeDocument _modified may go back in time

Merged revisions 1594835,1594888,1601838 from trunk to 1.0 branch.

Added:
    
jackrabbit/oak/branches/1.0/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/AmnesiaDiffCache.java
      - copied unchanged from r1594888, 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/AmnesiaDiffCache.java
    
jackrabbit/oak/branches/1.0/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreIT.java
      - copied unchanged from r1601838, 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreIT.java
Modified:
    jackrabbit/oak/branches/1.0/   (props changed)
    jackrabbit/oak/branches/1.0/.travis.yml
    
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/Commit.java
    
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
    
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/MissingLastRevSeeker.java
    
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/NodeDocument.java
    
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/UpdateOp.java
    
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/UpdateUtils.java
    
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStore.java
    
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoMissingLastRevSeeker.java
    
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoVersionGCSupport.java
    
jackrabbit/oak/branches/1.0/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/AbstractDocumentStoreTest.java
    
jackrabbit/oak/branches/1.0/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/CommitTest.java
    
jackrabbit/oak/branches/1.0/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreTest.java

Propchange: jackrabbit/oak/branches/1.0/
------------------------------------------------------------------------------
  Merged /jackrabbit/oak/trunk:r1594835,1594888,1601838

Modified: jackrabbit/oak/branches/1.0/.travis.yml
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/.travis.yml?rev=1601865&r1=1601864&r2=1601865&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.0/.travis.yml (original)
+++ jackrabbit/oak/branches/1.0/.travis.yml Wed Jun 11 12:00:11 2014
@@ -18,7 +18,12 @@ script:   mvn verify -Ppedantic,integrat
 language: java
 jdk:
   - oraclejdk7
-services: mongodb
+# OAK-1822: use MongoDB 2.6.1 instead of version provided by travis (2.4.x)
+before_install:
+  - "sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 
7F0CEB10"
+  - "echo 'deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 
10gen' | sudo tee /etc/apt/sources.list.d/mongodb.list"
+  - "sudo apt-get update"
+  - "sudo apt-get install mongodb-org=2.6.1 mongodb-org-server=2.6.1 
mongodb-org-shell=2.6.1 mongodb-org-mongos=2.6.1 mongodb-org-tools=2.6.1"
 notifications:
   email: false
   webhooks:

Modified: 
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/Commit.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/Commit.java?rev=1601865&r1=1601864&r2=1601865&view=diff
==============================================================================
--- 
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/Commit.java
 (original)
+++ 
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/Commit.java
 Wed Jun 11 12:00:11 2014
@@ -23,7 +23,6 @@ import java.util.LinkedHashMap;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Set;
-import java.util.concurrent.TimeUnit;
 
 import javax.annotation.CheckForNull;
 import javax.annotation.Nonnull;
@@ -86,18 +85,6 @@ public class Commit {
     }
 
     /**
-     * Return time in seconds with 5 second resolution
-     *
-     * @param timestamp time in millis to convert
-     * @return
-     */
-    public static long getModifiedInSecs(long timestamp) {
-        // 5 second resolution
-        long timeInSec = TimeUnit.MILLISECONDS.toSeconds(timestamp);
-        return timeInSec - timeInSec % 5;
-    }
-
-    /**
      * The revision for this new commit. That is, the changes within this 
commit
      * will be visible with this revision.
      *

Modified: 
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java?rev=1601865&r1=1601864&r2=1601865&view=diff
==============================================================================
--- 
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
 (original)
+++ 
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
 Wed Jun 11 12:00:11 2014
@@ -1539,7 +1539,7 @@ public final class DocumentNodeStore
 
     private void diffManyChildren(JsopWriter w, String path, Revision fromRev, 
Revision toRev) {
         long minTimestamp = Math.min(fromRev.getTimestamp(), 
toRev.getTimestamp());
-        long minValue = Commit.getModifiedInSecs(minTimestamp);
+        long minValue = NodeDocument.getModifiedInSecs(minTimestamp);
         String fromKey = Utils.getKeyLowerLimit(path);
         String toKey = Utils.getKeyUpperLimit(path);
         Set<String> paths = Sets.newHashSet();

Modified: 
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/MissingLastRevSeeker.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/MissingLastRevSeeker.java?rev=1601865&r1=1601864&r2=1601865&view=diff
==============================================================================
--- 
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/MissingLastRevSeeker.java
 (original)
+++ 
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/MissingLastRevSeeker.java
 Wed Jun 11 12:00:11 2014
@@ -76,8 +76,8 @@ public class MissingLastRevSeeker {
             public boolean apply(NodeDocument input) {
                 Long modified = (Long) 
input.get(NodeDocument.MODIFIED_IN_SECS);
                 return (modified != null
-                        && (modified >= Commit.getModifiedInSecs(startTime))
-                        && (modified <= Commit.getModifiedInSecs(endTime)));
+                        && (modified >= 
NodeDocument.getModifiedInSecs(startTime))
+                        && (modified <= 
NodeDocument.getModifiedInSecs(endTime)));
             }
         });
     }

Modified: 
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/NodeDocument.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/NodeDocument.java?rev=1601865&r1=1601864&r2=1601865&view=diff
==============================================================================
--- 
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/NodeDocument.java
 (original)
+++ 
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/NodeDocument.java
 Wed Jun 11 12:00:11 2014
@@ -17,7 +17,6 @@
 package org.apache.jackrabbit.oak.plugins.document;
 
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Iterator;
@@ -38,6 +37,7 @@ import javax.annotation.Nullable;
 import com.google.common.base.Function;
 import com.google.common.base.Predicate;
 import com.google.common.collect.AbstractIterator;
+import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Iterators;
 import com.google.common.collect.Queues;
@@ -129,6 +129,11 @@ public final class NodeDocument extends 
      */
     public static final String MODIFIED_IN_SECS = "_modified";
 
+    /**
+     * The resolution of the modified time.
+     */
+    static final int MODIFIED_IN_SECS_RESOLUTION = 5;
+
     private static final NavigableMap<Revision, Range> EMPTY_RANGE_MAP =
             Maps.unmodifiableNavigableMap(new TreeMap<Revision, Range>());
 
@@ -219,6 +224,18 @@ public final class NodeDocument extends 
     public static final String SD_MAX_REV_TIME_IN_SECS = "_sdMaxRevTime";
 
     /**
+     * Return time in seconds with 5 second resolution
+     *
+     * @param timestamp time in millis to convert
+     * @return the time in seconds with the given resolution.
+     */
+    public static long getModifiedInSecs(long timestamp) {
+        // 5 second resolution
+        long timeInSec = TimeUnit.MILLISECONDS.toSeconds(timestamp);
+        return timeInSec - timeInSec % MODIFIED_IN_SECS_RESOLUTION;
+    }
+
+    /**
      * A document which is created from splitting a main document can be 
classified
      * into multiple types depending on the content i.e. weather it contains
      * REVISIONS, COMMIT_ROOT, property history etc
@@ -606,16 +623,14 @@ public final class NodeDocument extends 
         SortedMap<Revision, String> revisions = getLocalRevisions();
         SortedMap<Revision, String> commitRoots = getLocalCommitRoot();
         Iterator<Revision> it = filter(Iterables.mergeSorted(
-                Arrays.asList(revisions.keySet(), commitRoots.keySet()),
+                ImmutableList.of(revisions.keySet(), commitRoots.keySet()),
                 revisions.comparator()), predicate).iterator();
         if (it.hasNext()) {
             newestRev = it.next();
         } else {
             // check full history (only needed in rare cases)
             it = filter(Iterables.mergeSorted(
-                    Arrays.asList(
-                            getValueMap(REVISIONS).keySet(),
-                            getValueMap(COMMIT_ROOT).keySet()),
+                    ImmutableList.of(getValueMap(REVISIONS).keySet(), 
getValueMap(COMMIT_ROOT).keySet()),
                     revisions.comparator()), predicate).iterator();
             if (it.hasNext()) {
                 newestRev = it.next();
@@ -1186,7 +1201,7 @@ public final class NodeDocument extends 
 
     public static void setModified(@Nonnull UpdateOp op,
                                    @Nonnull Revision revision) {
-        checkNotNull(op).set(MODIFIED_IN_SECS, 
Commit.getModifiedInSecs(checkNotNull(revision).getTimestamp()));
+        checkNotNull(op).max(MODIFIED_IN_SECS, 
getModifiedInSecs(checkNotNull(revision).getTimestamp()));
     }
 
     public static void setRevision(@Nonnull UpdateOp op,
@@ -1291,7 +1306,7 @@ public final class NodeDocument extends 
 
     private static void setSplitDocMaxRev(@Nonnull UpdateOp op,
                                           @Nonnull Revision maxRev) {
-        checkNotNull(op).set(SD_MAX_REV_TIME_IN_SECS, 
Commit.getModifiedInSecs(maxRev.getTimestamp()));
+        checkNotNull(op).set(SD_MAX_REV_TIME_IN_SECS, 
getModifiedInSecs(maxRev.getTimestamp()));
     }
 
     //----------------------------< internal 
>----------------------------------

Modified: 
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/UpdateOp.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/UpdateOp.java?rev=1601865&r1=1601864&r2=1601865&view=diff
==============================================================================
--- 
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/UpdateOp.java
 (original)
+++ 
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/UpdateOp.java
 Wed Jun 11 12:00:11 2014
@@ -131,9 +131,7 @@ public final class UpdateOp {
      * @param value the value
      */
     void setMapEntry(@Nonnull String property, @Nonnull Revision revision, 
String value) {
-        Operation op = new Operation();
-        op.type = Operation.Type.SET_MAP_ENTRY;
-        op.value = value;
+        Operation op = new Operation(Operation.Type.SET_MAP_ENTRY, value);
         changes.put(new Key(property, checkNotNull(revision)), op);
     }
 
@@ -145,8 +143,7 @@ public final class UpdateOp {
      * @param revision the revision
      */
     public void removeMapEntry(@Nonnull String property, @Nonnull Revision 
revision) {
-        Operation op = new Operation();
-        op.type = Operation.Type.REMOVE_MAP_ENTRY;
+        Operation op = new Operation(Operation.Type.REMOVE_MAP_ENTRY, null);
         changes.put(new Key(property, checkNotNull(revision)), op);
     }
 
@@ -157,9 +154,23 @@ public final class UpdateOp {
      * @param value the value
      */
     void set(String property, Object value) {
-        Operation op = new Operation();
-        op.type = Operation.Type.SET;
-        op.value = value;
+        Operation op = new Operation(Operation.Type.SET, value);
+        changes.put(new Key(property, null), op);
+    }
+
+    /**
+     * Set the property to the given value if the new value is higher than the
+     * existing value. The property is also set to the given value if the
+     * property does not yet exist.
+     * <p>
+     * The result of a max operation with different types of values is
+     * undefined.
+     *
+     * @param property the name of the property to set.
+     * @param value the new value for the property.
+     */
+    <T> void max(String property, Comparable<T> value) {
+        Operation op = new Operation(Operation.Type.MAX, value);
         changes.put(new Key(property, null), op);
     }
 
@@ -187,9 +198,7 @@ public final class UpdateOp {
         if (isNew) {
             throw new IllegalStateException("Cannot use containsMapEntry() on 
new document");
         }
-        Operation op = new Operation();
-        op.type = Operation.Type.CONTAINS_MAP_ENTRY;
-        op.value = exists;
+        Operation op = new Operation(Operation.Type.CONTAINS_MAP_ENTRY, 
exists);
         changes.put(new Key(property, checkNotNull(revision)), op);
     }
 
@@ -200,9 +209,7 @@ public final class UpdateOp {
      * @param value the increment
      */
     public void increment(@Nonnull String property, long value) {
-        Operation op = new Operation();
-        op.type = Operation.Type.INCREMENT;
-        op.value = value;
+        Operation op = new Operation(Operation.Type.INCREMENT, value);
         changes.put(new Key(property, null), op);
     }
 
@@ -239,6 +246,14 @@ public final class UpdateOp {
             SET,
 
             /**
+             * Set the value if the new value is higher than the existing 
value.
+             * The new value is also considered higher, when there is no
+             * existing value.
+             * The sub-key is not used.
+             */
+            MAX,
+
+            /**
              * Increment the Long value with the provided Long value.
              * The sub-key is not used.
              */
@@ -267,12 +282,17 @@ public final class UpdateOp {
         /**
          * The operation type.
          */
-        public Type type;
+        public final Type type;
 
         /**
          * The value, if any.
          */
-        public Object value;
+        public final Object value;
+
+        Operation(Type type, Object value) {
+            this.type = checkNotNull(type);
+            this.value = value;
+        }
 
         @Override
         public String toString() {
@@ -283,18 +303,16 @@ public final class UpdateOp {
             Operation reverse = null;
             switch (type) {
             case INCREMENT:
-                reverse = new Operation();
-                reverse.type = Type.INCREMENT;
-                reverse.value = -(Long) value;
+                reverse = new Operation(Type.INCREMENT, -(Long) value);
                 break;
             case SET:
+            case MAX:
             case REMOVE_MAP_ENTRY:
             case CONTAINS_MAP_ENTRY:
                 // nothing to do
                 break;
             case SET_MAP_ENTRY:
-                reverse = new Operation();
-                reverse.type = Type.REMOVE_MAP_ENTRY;
+                reverse = new Operation(Type.REMOVE_MAP_ENTRY, null);
                 break;
             }
             return reverse;

Modified: 
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/UpdateUtils.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/UpdateUtils.java?rev=1601865&r1=1601864&r2=1601865&view=diff
==============================================================================
--- 
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/UpdateUtils.java
 (original)
+++ 
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/UpdateUtils.java
 Wed Jun 11 12:00:11 2014
@@ -44,7 +44,9 @@ public class UpdateUtils {
      * @param comparator
      *            the revision comparator.
      */
-    public static void applyChanges(@Nonnull Document doc, @Nonnull UpdateOp 
update, @Nonnull Comparator<Revision> comparator) {
+    public static void applyChanges(@Nonnull Document doc,
+                                    @Nonnull UpdateOp update,
+                                    @Nonnull Comparator<Revision> comparator) {
         for (Entry<Key, Operation> e : 
checkNotNull(update).getChanges().entrySet()) {
             Key k = e.getKey();
             Operation op = e.getValue();
@@ -53,6 +55,15 @@ public class UpdateUtils {
                     doc.put(k.toString(), op.value);
                     break;
                 }
+                case MAX: {
+                    Comparable newValue = (Comparable) op.value;
+                    Object old = doc.get(k.toString());
+                    //noinspection unchecked
+                    if (old == null || newValue.compareTo(old) > 0) {
+                        doc.put(k.toString(), op.value);
+                    }
+                    break;
+                }
                 case INCREMENT: {
                     Object old = doc.get(k.toString());
                     Long x = (Long) op.value;

Modified: 
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStore.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStore.java?rev=1601865&r1=1601864&r2=1601865&view=diff
==============================================================================
--- 
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStore.java
 (original)
+++ 
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoDocumentStore.java
 Wed Jun 11 12:00:11 2014
@@ -29,6 +29,8 @@ import java.util.TreeMap;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.locks.Lock;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import javax.annotation.CheckForNull;
 import javax.annotation.Nonnull;
@@ -115,6 +117,7 @@ public class MongoDocumentStore implemen
     private String lastReadWriteMode;
 
     public MongoDocumentStore(DB db, DocumentMK.Builder builder) {
+        checkVersion(db);
         nodes = db.getCollection(
                 Collection.NODES.toString());
         clusterNodes = db.getCollection(
@@ -165,6 +168,24 @@ public class MongoDocumentStore implemen
                 builder.getDocumentCacheSize());
     }
 
+    private static void checkVersion(DB db) {
+        String version = db.command("buildInfo").getString("version");
+        Matcher m = Pattern.compile("^(\\d+)\\.(\\d+)\\..*").matcher(version);
+        if (!m.matches()) {
+            throw new IllegalArgumentException("Malformed MongoDB version: " + 
version);
+        }
+        int major = Integer.parseInt(m.group(1));
+        int minor = Integer.parseInt(m.group(2));
+        if (major > 2) {
+            return;
+        }
+        if (minor < 6) {
+            String msg = "MongoDB version 2.6.0 or higher required. " +
+                    "Currently connected to a MongoDB with version: " + 
version;
+            throw new RuntimeException(msg);
+        }
+    }
+
     private Cache<CacheValue, NodeDocument> createOffHeapCache(
             DocumentMK.Builder builder) {
         ForwardingListener<CacheValue, NodeDocument> listener = 
ForwardingListener.newInstance();
@@ -523,6 +544,7 @@ public class MongoDocumentStore implemen
                 Operation op = entry.getValue();
                 switch (op.type) {
                     case SET:
+                    case MAX:
                     case INCREMENT: {
                         inserts[i].put(k.toString(), op.value);
                         break;
@@ -858,6 +880,7 @@ public class MongoDocumentStore implemen
     @Nonnull
     private static DBObject createUpdate(UpdateOp updateOp) {
         BasicDBObject setUpdates = new BasicDBObject();
+        BasicDBObject maxUpdates = new BasicDBObject();
         BasicDBObject incUpdates = new BasicDBObject();
         BasicDBObject unsetUpdates = new BasicDBObject();
 
@@ -873,16 +896,17 @@ public class MongoDocumentStore implemen
             }
             Operation op = entry.getValue();
             switch (op.type) {
-                case SET: {
+                case SET:
+                case SET_MAP_ENTRY: {
                     setUpdates.append(k.toString(), op.value);
                     break;
                 }
-                case INCREMENT: {
-                    incUpdates.append(k.toString(), op.value);
+                case MAX: {
+                    maxUpdates.append(k.toString(), op.value);
                     break;
                 }
-                case SET_MAP_ENTRY: {
-                    setUpdates.append(k.toString(), op.value);
+                case INCREMENT: {
+                    incUpdates.append(k.toString(), op.value);
                     break;
                 }
                 case REMOVE_MAP_ENTRY: {
@@ -896,6 +920,9 @@ public class MongoDocumentStore implemen
         if (!setUpdates.isEmpty()) {
             update.append("$set", setUpdates);
         }
+        if (!maxUpdates.isEmpty()) {
+            update.append("$max", maxUpdates);
+        }
         if (!incUpdates.isEmpty()) {
             update.append("$inc", incUpdates);
         }

Modified: 
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoMissingLastRevSeeker.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoMissingLastRevSeeker.java?rev=1601865&r1=1601864&r2=1601865&view=diff
==============================================================================
--- 
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoMissingLastRevSeeker.java
 (original)
+++ 
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoMissingLastRevSeeker.java
 Wed Jun 11 12:00:11 2014
@@ -33,7 +33,6 @@ import com.mongodb.ReadPreference;
 
 import org.apache.jackrabbit.oak.plugins.document.ClusterNodeInfo;
 import org.apache.jackrabbit.oak.plugins.document.Collection;
-import org.apache.jackrabbit.oak.plugins.document.Commit;
 import org.apache.jackrabbit.oak.plugins.document.Document;
 import org.apache.jackrabbit.oak.plugins.document.MissingLastRevSeeker;
 import org.apache.jackrabbit.oak.plugins.document.NodeDocument;
@@ -58,9 +57,9 @@ public class MongoMissingLastRevSeeker e
             final long endTime) {
         DBObject query =
                 start(NodeDocument.MODIFIED_IN_SECS).lessThanEquals(
-                                Commit.getModifiedInSecs(endTime))
+                                NodeDocument.getModifiedInSecs(endTime))
                         .put(NodeDocument.MODIFIED_IN_SECS).greaterThanEquals(
-                                Commit.getModifiedInSecs(startTime))
+                                NodeDocument.getModifiedInSecs(startTime))
                         .get();
         DBObject sortFields = new BasicDBObject(NodeDocument.MODIFIED_IN_SECS, 
-1);
 

Modified: 
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoVersionGCSupport.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoVersionGCSupport.java?rev=1601865&r1=1601864&r2=1601865&view=diff
==============================================================================
--- 
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoVersionGCSupport.java
 (original)
+++ 
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/mongo/MongoVersionGCSupport.java
 Wed Jun 11 12:00:11 2014
@@ -38,7 +38,6 @@ import com.mongodb.ReadPreference;
 import com.mongodb.WriteConcern;
 import com.mongodb.WriteResult;
 import org.apache.jackrabbit.oak.plugins.document.Collection;
-import org.apache.jackrabbit.oak.plugins.document.Commit;
 import org.apache.jackrabbit.oak.plugins.document.Document;
 import org.apache.jackrabbit.oak.plugins.document.NodeDocument;
 import org.apache.jackrabbit.oak.plugins.document.VersionGCSupport;
@@ -71,7 +70,7 @@ public class MongoVersionGCSupport exten
         //_deletedOnce == true && _modified < lastModifiedTime
         DBObject query =
                 start(NodeDocument.DELETED_ONCE).is(Boolean.TRUE)
-                                
.put(NodeDocument.MODIFIED_IN_SECS).lessThan(Commit.getModifiedInSecs(lastModifiedTime))
+                                
.put(NodeDocument.MODIFIED_IN_SECS).lessThan(NodeDocument.getModifiedInSecs(lastModifiedTime))
                         .get();
         DBCursor cursor = 
getNodeCollection().find(query).setReadPreference(ReadPreference.secondaryPreferred());
         return CloseableIterable.wrap(transform(cursor, new Function<DBObject, 
NodeDocument>() {
@@ -94,7 +93,7 @@ public class MongoVersionGCSupport exten
                 .and(
                     orClause.get(),
                     start(NodeDocument.SD_MAX_REV_TIME_IN_SECS)
-                        .lessThan(Commit.getModifiedInSecs(oldestRevTimeStamp))
+                        
.lessThan(NodeDocument.getModifiedInSecs(oldestRevTimeStamp))
                         .get()
                 ).get();
 

Modified: 
jackrabbit/oak/branches/1.0/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/AbstractDocumentStoreTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/AbstractDocumentStoreTest.java?rev=1601865&r1=1601864&r2=1601865&view=diff
==============================================================================
--- 
jackrabbit/oak/branches/1.0/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/AbstractDocumentStoreTest.java
 (original)
+++ 
jackrabbit/oak/branches/1.0/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/AbstractDocumentStoreTest.java
 Wed Jun 11 12:00:11 2014
@@ -31,14 +31,16 @@ public abstract class AbstractDocumentSt
     protected String dsname;
     protected DocumentStore ds;
     protected Set<String> removeMe = new HashSet<String>();
+    protected DocumentStoreFixture dsf;
 
     public AbstractDocumentStoreTest(DocumentStoreFixture dsf) {
         this.ds = dsf.createDocumentStore();
+        this.dsf = dsf;
         this.dsname = dsf.getName();
     }
 
     @After
-    public void cleanUp() {
+    public void cleanUp() throws Exception {
         for (String id : removeMe) {
             try {
                 
ds.remove(org.apache.jackrabbit.oak.plugins.document.Collection.NODES, id);
@@ -46,6 +48,7 @@ public abstract class AbstractDocumentSt
                 // best effort
             }
         }
+        dsf.dispose();
     }
 
     @Parameterized.Parameters

Modified: 
jackrabbit/oak/branches/1.0/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/CommitTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/CommitTest.java?rev=1601865&r1=1601864&r2=1601865&view=diff
==============================================================================
--- 
jackrabbit/oak/branches/1.0/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/CommitTest.java
 (original)
+++ 
jackrabbit/oak/branches/1.0/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/CommitTest.java
 Wed Jun 11 12:00:11 2014
@@ -27,10 +27,10 @@ public class CommitTest {
 
     @Test
     public void testModifiedTime(){
-        assertEquals(10, Commit.getModifiedInSecs(10000));
-        assertEquals(10, Commit.getModifiedInSecs(10003));
-        assertEquals(10, Commit.getModifiedInSecs(12000));
-        assertEquals(15, Commit.getModifiedInSecs(15000));
-        assertEquals(15, Commit.getModifiedInSecs(15006));
+        assertEquals(10, NodeDocument.getModifiedInSecs(10000));
+        assertEquals(10, NodeDocument.getModifiedInSecs(10003));
+        assertEquals(10, NodeDocument.getModifiedInSecs(12000));
+        assertEquals(15, NodeDocument.getModifiedInSecs(15000));
+        assertEquals(15, NodeDocument.getModifiedInSecs(15006));
     }
 }

Modified: 
jackrabbit/oak/branches/1.0/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreTest.java?rev=1601865&r1=1601864&r2=1601865&view=diff
==============================================================================
--- 
jackrabbit/oak/branches/1.0/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreTest.java
 (original)
+++ 
jackrabbit/oak/branches/1.0/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreTest.java
 Wed Jun 11 12:00:11 2014
@@ -55,8 +55,11 @@ import org.junit.Test;
 
 import com.google.common.collect.Iterables;
 
+import static java.util.concurrent.TimeUnit.SECONDS;
 import static org.apache.jackrabbit.oak.api.CommitFailedException.CONSTRAINT;
 import static org.apache.jackrabbit.oak.plugins.document.Collection.NODES;
+import static 
org.apache.jackrabbit.oak.plugins.document.NodeDocument.MODIFIED_IN_SECS;
+import static 
org.apache.jackrabbit.oak.plugins.document.NodeDocument.MODIFIED_IN_SECS_RESOLUTION;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
@@ -391,6 +394,55 @@ public class DocumentNodeStoreTest {
         nodeStore3.dispose();
     }
 
+    @Test
+    public void modifiedReset() throws Exception {
+        Clock clock = new Clock.Virtual();
+        clock.waitUntil(System.currentTimeMillis());
+        Revision.setClock(clock);
+        MemoryDocumentStore docStore = new MemoryDocumentStore();
+        DocumentNodeStore ns1 = new DocumentMK.Builder()
+                .setDocumentStore(docStore).setClusterId(1)
+                .setAsyncDelay(0).clock(clock).getNodeStore();
+        NodeBuilder builder1 = ns1.getRoot().builder();
+        builder1.child("node");
+        ns1.merge(builder1, EmptyHook.INSTANCE, CommitInfo.EMPTY);
+        ns1.runBackgroundOperations();
+
+        DocumentNodeStore ns2 = new DocumentMK.Builder()
+                .setDocumentStore(docStore).setClusterId(2)
+                .setAsyncDelay(0).clock(clock).getNodeStore();
+
+        NodeBuilder builder2 = ns2.getRoot().builder();
+        builder2.child("node").child("child-2");
+        ns2.merge(builder2, EmptyHook.INSTANCE, CommitInfo.EMPTY);
+
+        // wait at least _modified resolution. in reality the wait may
+        // not be necessary. e.g. when the clock passes the resolution boundary
+        // exactly at this time
+        clock.waitUntil(System.currentTimeMillis() +
+                SECONDS.toMillis(MODIFIED_IN_SECS_RESOLUTION + 1));
+
+        builder1 = ns1.getRoot().builder();
+        builder1.child("node").child("child-1");
+        ns1.merge(builder1, EmptyHook.INSTANCE, CommitInfo.EMPTY);
+
+        ns1.runBackgroundOperations();
+
+        // get current _modified timestamp on /node
+        NodeDocument doc = docStore.find(NODES, Utils.getIdFromPath("/node"));
+        Long mod1 = (Long) doc.get(MODIFIED_IN_SECS);
+        assertNotNull(mod1);
+
+        ns2.runBackgroundOperations();
+
+        doc = docStore.find(NODES, Utils.getIdFromPath("/node"));
+        Long mod2 = (Long) doc.get(MODIFIED_IN_SECS);
+        assertTrue("" + mod2 + " < " + mod1, mod2 >= mod1);
+
+        ns1.dispose();
+        ns2.dispose();
+    }
+
     private static class TestHook extends EditorHook {
 
         TestHook(final String prefix) {


Reply via email to