Author: mreutegg
Date: Thu Jan  9 08:49:16 2014
New Revision: 1556761

URL: http://svn.apache.org/r1556761
Log:
OAK-1233: IllegalStateException in MergeSortedIterators

Added:
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/PropertyHistory.java
   (with props)
    
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/mongomk/ValueMapTest.java
   (with props)
Modified:
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/CommitQueue.java
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MemoryDocumentStore.java
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoDocumentStore.java
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/NodeDocument.java
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/StableRevisionComparator.java
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/ValueMap.java
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/sqlpersistence/SQLDocumentStore.java
    
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/mongomk/DocumentSplitTest.java
    
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/mongomk/util/MergeSortedIteratorsTest.java

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/CommitQueue.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/CommitQueue.java?rev=1556761&r1=1556760&r2=1556761&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/CommitQueue.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/CommitQueue.java
 Thu Jan  9 08:49:16 2014
@@ -44,7 +44,7 @@ class CommitQueue {
 
     private final MongoNodeStore store;
 
-    private final SortedMap<Revision, Entry> commits = new TreeMap<Revision, 
Entry>(new StableRevisionComparator());
+    private final SortedMap<Revision, Entry> commits = new TreeMap<Revision, 
Entry>(StableRevisionComparator.INSTANCE);
 
     private final ChangeDispatcher dispatcher;
 
@@ -61,8 +61,7 @@ class CommitQueue {
     @Nonnull
     SortedSet<Revision> createRevisions(int num) {
         checkArgument(num > 0);
-        SortedSet<Revision> revs = new TreeSet<Revision>(
-                new StableRevisionComparator());
+        SortedSet<Revision> revs = new 
TreeSet<Revision>(StableRevisionComparator.INSTANCE);
         Revision rev = null;
         synchronized (this) {
             for (int i = 0; i < num; i++) {

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MemoryDocumentStore.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MemoryDocumentStore.java?rev=1556761&r1=1556760&r2=1556761&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MemoryDocumentStore.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MemoryDocumentStore.java
 Thu Jan  9 08:49:16 2014
@@ -17,7 +17,6 @@
 package org.apache.jackrabbit.oak.plugins.mongomk;
 
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
 import java.util.concurrent.ConcurrentNavigableMap;
@@ -55,7 +54,7 @@ public class MemoryDocumentStore impleme
      * Comparator for maps with {@link Revision} keys. The maps are ordered
      * descending, newest revisions first!
      */
-    private final Comparator<Revision> comparator = 
Collections.reverseOrder(new StableRevisionComparator());
+    private final Comparator<Revision> comparator = 
StableRevisionComparator.REVERSE;
 
     @Override
     public <T extends Document> T find(Collection<T> collection, String key, 
int maxCacheAge) {

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoDocumentStore.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoDocumentStore.java?rev=1556761&r1=1556760&r2=1556761&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoDocumentStore.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/MongoDocumentStore.java
 Thu Jan  9 08:49:16 2014
@@ -85,7 +85,7 @@ public class MongoDocumentStore implemen
      * Comparator for maps with {@link Revision} keys. The maps are ordered
      * descending, newest revisions first!
      */
-    private final Comparator<Revision> comparator = 
Collections.reverseOrder(new StableRevisionComparator());
+    private final Comparator<Revision> comparator = 
StableRevisionComparator.REVERSE;
 
     public MongoDocumentStore(DB db, MongoMK.Builder builder) {
         nodes = db.getCollection(

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/NodeDocument.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/NodeDocument.java?rev=1556761&r1=1556760&r2=1556761&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/NodeDocument.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/NodeDocument.java
 Thu Jan  9 08:49:16 2014
@@ -19,7 +19,6 @@ package org.apache.jackrabbit.oak.plugin
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
-import java.util.Comparator;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -41,8 +40,6 @@ import org.apache.jackrabbit.oak.plugins
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.base.Function;
-import com.google.common.base.Predicate;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Maps;
 
@@ -173,12 +170,6 @@ public class NodeDocument extends Docume
 
     private final long time = System.currentTimeMillis();
 
-    /**
-     * Comparator for maps with {@link Revision} keys. The maps are ordered
-     * descending, newest revisions first!
-     */
-    private final Comparator<Revision> comparator = 
Collections.reverseOrder(new StableRevisionComparator());
-
     NodeDocument(@Nonnull DocumentStore store) {
         this.store = checkNotNull(store);
     }
@@ -279,7 +270,7 @@ public class NodeDocument extends Docume
             return Utils.isCommitted(value);
         }
         // check previous docs
-        for (NodeDocument prev : commitRootDoc.getPreviousDocs(revision, 
REVISIONS)) {
+        for (NodeDocument prev : commitRootDoc.getPreviousDocs(REVISIONS, 
revision)) {
             if (prev.containsRevision(revision)) {
                 return prev.isCommitted(revision);
             }
@@ -301,7 +292,7 @@ public class NodeDocument extends Docume
         if (getLocalRevisions().containsKey(revision)) {
             return true;
         }
-        for (NodeDocument prev : getPreviousDocs(revision, REVISIONS)) {
+        for (NodeDocument prev : getPreviousDocs(REVISIONS, revision)) {
             if (prev.containsRevision(revision)) {
                 return true;
             }
@@ -700,7 +691,7 @@ public class NodeDocument extends Docume
             splitOps = new ArrayList<UpdateOp>(2);
             // move to another document
             UpdateOp main = new UpdateOp(id, false);
-            main.setMapEntry(PREVIOUS, high, low.toString());
+            setPrevious(main, high, low);
             UpdateOp old = new UpdateOp(Utils.getPreviousIdFor(id, high), 
true);
             old.set(ID, old.getId());
             for (String property : splitValues.keySet()) {
@@ -736,7 +727,8 @@ public class NodeDocument extends Docume
             if (map.isEmpty()) {
                 previous = EMPTY_RANGE_MAP;
             } else {
-                SortedMap<Revision, Range> transformed = new TreeMap<Revision, 
Range>(comparator);
+                SortedMap<Revision, Range> transformed = new TreeMap<Revision, 
Range>(
+                        StableRevisionComparator.REVERSE);
                 for (Map.Entry<Revision, String> entry : map.entrySet()) {
                     Revision high = entry.getKey();
                     Revision low = Revision.fromString(entry.getValue());
@@ -755,45 +747,13 @@ public class NodeDocument extends Docume
      * documents are returned. The returned documents are returned in 
descending
      * revision order (newest first).
      *
-     * @param revision the revision to match or <code>null</code>.
      * @param property the name of a property.
+     * @param revision the revision to match or <code>null</code>.
      * @return previous documents.
      */
-    Iterable<NodeDocument> getPreviousDocs(@Nullable final Revision revision,
-                @Nonnull final String property) {
-        checkNotNull(property);
-        Iterable<NodeDocument> docs = Iterables.transform(
-                Iterables.filter(getPreviousRanges().entrySet(),
-                        new Predicate<Map.Entry<Revision, Range>>() {
-                            @Override
-                            public boolean apply(Map.Entry<Revision, Range> 
input) {
-                                return revision == null
-                                        || input.getValue().includes(revision);
-                            }
-                        }), new Function<Map.Entry<Revision, Range>, 
NodeDocument>() {
-            @Nullable
-            @Override
-            public NodeDocument apply(Map.Entry<Revision, Range> input) {
-                Revision r = input.getKey();
-                String prevId = Utils.getPreviousIdFor(getId(), r);
-                NodeDocument prev = store.find(Collection.NODES, prevId);
-                if (prev == null) {
-                    LOG.warn("Document with previous revisions not found: " + 
prevId);
-                }
-                return prev;
-            }
-        });
-        // filter out null docs and check if the revision is actually in there
-        return Iterables.filter(docs, new Predicate<NodeDocument>() {
-            @Override
-            public boolean apply(@Nullable NodeDocument input) {
-                if (input == null) {
-                    return false;
-                }
-                return revision == null
-                        || input.getLocalMap(property).containsKey(revision);
-            }
-        });
+    Iterable<NodeDocument> getPreviousDocs(@Nonnull final String property,
+                                           @Nullable final Revision revision) {
+        return new PropertyHistory(store, this, property, revision);
     }
 
     /**
@@ -905,6 +865,13 @@ public class NodeDocument extends Docume
         checkNotNull(op).removeMapEntry(DELETED, revision);
     }
 
+    public static void setPrevious(@Nonnull UpdateOp op,
+                                   @Nonnull Revision high,
+                                   @Nonnull Revision low) {
+        checkNotNull(op).setMapEntry(PREVIOUS, checkNotNull(high),
+                checkNotNull(low).toString());
+    }
+
     //----------------------------< internal 
>----------------------------------
 
     /**
@@ -1000,7 +967,7 @@ public class NodeDocument extends Docume
         String value = getLocalRevisions().get(revision);
         if (value == null) {
             // check previous
-            for (NodeDocument prev : getPreviousDocs(revision, REVISIONS)) {
+            for (NodeDocument prev : getPreviousDocs(REVISIONS, revision)) {
                 value = prev.getLocalRevisions().get(revision);
                 if (value != null) {
                     break;

Added: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/PropertyHistory.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/PropertyHistory.java?rev=1556761&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/PropertyHistory.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/PropertyHistory.java
 Thu Jan  9 08:49:16 2014
@@ -0,0 +1,188 @@
+/*
+ * 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.mongomk;
+
+import java.util.Iterator;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.SortedMap;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.apache.jackrabbit.oak.plugins.mongomk.util.Utils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Iterators;
+import com.google.common.collect.Maps;
+import com.google.common.collect.PeekingIterator;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static java.util.AbstractMap.SimpleImmutableEntry;
+
+/**
+ * The revision history for a given property. The history may span multiple
+ * previous documents.
+ */
+class PropertyHistory implements Iterable<NodeDocument> {
+
+    private static final Logger LOG = 
LoggerFactory.getLogger(PropertyHistory.class);
+
+    private final DocumentStore store;
+    private final NodeDocument main;
+    private final String property;
+    private final Revision revision;
+    private final String id;
+
+    public PropertyHistory(@Nonnull DocumentStore store,
+                           @Nonnull NodeDocument main,
+                           @Nonnull String property,
+                           @Nullable Revision revision) {
+        this.store = checkNotNull(store);
+        this.main = checkNotNull(main);
+        this.property = checkNotNull(property);
+        this.revision = revision;
+        this.id = main.getId();
+    }
+
+    @Override
+    public Iterator<NodeDocument> iterator() {
+        Iterable<Map.Entry<Revision, Range>> ranges;
+        if (revision != null) {
+            ranges = Iterables.filter(
+                    main.getPreviousRanges().entrySet(),
+                    new Predicate<Map.Entry<Revision, Range>>() {
+                        @Override
+                        public boolean apply(Map.Entry<Revision, Range> input) 
{
+                            return input.getValue().includes(revision);
+                        }
+                    });
+        } else {
+            ranges = main.getPreviousRanges().entrySet();
+        }
+
+        Iterable<Map.Entry<Revision, NodeDocument>> docs = 
Iterables.transform(ranges,
+                new Function<Map.Entry<Revision, Range>, Map.Entry<Revision, 
NodeDocument>>() {
+            @Nullable
+            @Override
+            public Map.Entry<Revision, NodeDocument> apply(Map.Entry<Revision, 
Range> input) {
+                Revision r = input.getKey();
+                String prevId = Utils.getPreviousIdFor(id, r);
+                NodeDocument prev = store.find(Collection.NODES, prevId);
+                if (prev == null) {
+                    LOG.warn("Document with previous revisions not found: " + 
prevId);
+                    return null;
+                }
+                return new SimpleImmutableEntry<Revision, NodeDocument>(r, 
prev);
+            }
+        });
+
+        // filter out null docs and ensure order
+        return ensureOrder(Iterables.filter(docs, Predicates.notNull()));
+    }
+
+    /**
+     * Ensures the order of docs is correct with respect to the highest 
revision
+     * for each ValueMap for the given property.
+     *
+     * @param docs the docs to order.
+     * @return the docs in the correct order.
+     */
+    private Iterator<NodeDocument> ensureOrder(final 
Iterable<Map.Entry<Revision, NodeDocument>> docs) {
+        return new Iterator<NodeDocument>() {
+            PeekingIterator<Map.Entry<Revision, NodeDocument>> input
+                    = Iterators.peekingIterator(docs.iterator());
+            SortedMap<Revision, NodeDocument> queue = 
Maps.newTreeMap(StableRevisionComparator.INSTANCE);
+            NodeDocument next = fetchNext();
+
+            @Override
+            public boolean hasNext() {
+                return next != null;
+            }
+
+            @Override
+            public NodeDocument next() {
+                if (!hasNext()) {
+                    throw new NoSuchElementException();
+                }
+                NodeDocument doc = next;
+                next = fetchNext();
+                return doc;
+            }
+
+            @Override
+            public void remove() {
+                throw new UnsupportedOperationException();
+            }
+
+            private NodeDocument fetchNext() {
+                refillQueue();
+                if (queue.isEmpty()) {
+                    return null;
+                } else {
+                    return queue.remove(queue.lastKey());
+                }
+            }
+
+            /**
+             * Refill the queue until the highest entry in the queue is higher
+             * than the peeked entry from the input iterator.
+             */
+            private void refillQueue() {
+                for (;;) {
+                    // the doc to enqueue
+                    NodeDocument doc;
+                    if (queue.isEmpty()) {
+                        if (input.hasNext()) {
+                            doc = input.next().getValue();
+                        } else {
+                            // no more input -> done
+                            return;
+                        }
+                    } else {
+                        // peek first and compare with queue
+                        if (input.hasNext()) {
+                            if (queue.comparator().compare(queue.lastKey(), 
input.peek().getKey()) < 0) {
+                                doc = input.next().getValue();
+                            } else {
+                                // top of queue rev is higher than input -> 
done
+                                return;
+                            }
+                        } else {
+                            // no more input -> done
+                            return;
+                        }
+                    }
+                    // check if the revision is actually in there
+                    if (doc != null) {
+                        Map<Revision, String> values = 
doc.getValueMap(property);
+                        if (!values.isEmpty() && (revision == null || 
values.containsKey(revision))) {
+                            // put into queue with first (highest) revision
+                            // from value map
+                            queue.put(values.keySet().iterator().next(), doc);
+                        }
+                    }
+                }
+            }
+        };
+    }
+}

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

Propchange: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/PropertyHistory.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/StableRevisionComparator.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/StableRevisionComparator.java?rev=1556761&r1=1556760&r2=1556761&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/StableRevisionComparator.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/StableRevisionComparator.java
 Thu Jan  9 08:49:16 2014
@@ -16,6 +16,7 @@
  */
 package org.apache.jackrabbit.oak.plugins.mongomk;
 
+import java.util.Collections;
 import java.util.Comparator;
 
 /**
@@ -32,6 +33,13 @@ import java.util.Comparator;
  */
 public class StableRevisionComparator implements Comparator<Revision> {
 
+    public static final Comparator<Revision> INSTANCE = new 
StableRevisionComparator();
+
+    public static final Comparator<Revision> REVERSE = 
Collections.reverseOrder(INSTANCE);
+
+    private StableRevisionComparator() {
+    }
+
     @Override
     public int compare(Revision o1, Revision o2) {
         return o1.compareRevisionTimeThenClusterId(o2);

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/ValueMap.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/ValueMap.java?rev=1556761&r1=1556760&r2=1556761&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/ValueMap.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/ValueMap.java
 Thu Jan  9 08:49:16 2014
@@ -39,7 +39,7 @@ import com.google.common.collect.Iterato
 class ValueMap {
 
     static final SortedMap<Revision, String> EMPTY = 
Collections.unmodifiableSortedMap(
-            new TreeMap<Revision, String>(new StableRevisionComparator()));
+            new TreeMap<Revision, String>(StableRevisionComparator.INSTANCE));
 
     @Nonnull
     static Map<Revision, String> create(@Nonnull final NodeDocument doc,
@@ -51,7 +51,7 @@ class ValueMap {
         final Comparator<? super Revision> c = map.comparator();
         final Iterator<NodeDocument> docs = Iterators.concat(
                 Iterators.singletonIterator(doc),
-                doc.getPreviousDocs(null, property).iterator());
+                doc.getPreviousDocs(property, null).iterator());
         final Set<Map.Entry<Revision, String>> entrySet
                 = new AbstractSet<Map.Entry<Revision, String>>() {
 
@@ -82,7 +82,7 @@ class ValueMap {
             @Override
             public int size() {
                 int size = map.size();
-                for (NodeDocument prev : doc.getPreviousDocs(null, property)) {
+                for (NodeDocument prev : doc.getPreviousDocs(property, null)) {
                     size += prev.getLocalMap(property).size();
                 }
                 return size;
@@ -107,7 +107,7 @@ class ValueMap {
                     return value;
                 }
                 Revision r = (Revision) key;
-                for (NodeDocument prev : doc.getPreviousDocs(r, property)) {
+                for (NodeDocument prev : doc.getPreviousDocs(property, r)) {
                     value = prev.getLocalMap(property).get(key);
                     if (value != null) {
                         return value;

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/sqlpersistence/SQLDocumentStore.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/sqlpersistence/SQLDocumentStore.java?rev=1556761&r1=1556760&r2=1556761&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/sqlpersistence/SQLDocumentStore.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/sqlpersistence/SQLDocumentStore.java
 Thu Jan  9 08:49:16 2014
@@ -24,7 +24,6 @@ import java.sql.SQLException;
 import java.sql.Statement;
 import java.sql.Types;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
 import java.util.Map;
@@ -154,7 +153,7 @@ public class SQLDocumentStore implements
 
     private static final Logger LOG = 
LoggerFactory.getLogger(SQLDocumentStore.class);
 
-    private final Comparator<Revision> comparator = 
Collections.reverseOrder(new StableRevisionComparator());
+    private final Comparator<Revision> comparator = 
StableRevisionComparator.REVERSE;
 
     private Connection connection;
 

Modified: 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/mongomk/DocumentSplitTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/mongomk/DocumentSplitTest.java?rev=1556761&r1=1556760&r2=1556761&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/mongomk/DocumentSplitTest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/mongomk/DocumentSplitTest.java
 Thu Jan  9 08:49:16 2014
@@ -26,7 +26,6 @@ import java.util.Set;
 
 import org.apache.jackrabbit.mk.blobs.MemoryBlobStore;
 import org.apache.jackrabbit.oak.plugins.mongomk.util.Utils;
-import org.junit.Ignore;
 import org.junit.Test;
 
 import com.google.common.collect.Sets;
@@ -213,7 +212,6 @@ public class DocumentSplitTest extends B
         }
     }
 
-    @Ignore
     @Test // OAK-1233
     public void manyRevisions() {
         final int numMKs = 3;
@@ -237,7 +235,7 @@ public class DocumentSplitTest extends B
         List<String> propNames = Arrays.asList("prop1", "prop2", "prop3");
         Random random = new Random(0);
 
-        for (int i = 0; i < 10000; i++) {
+        for (int i = 0; i < 1000; i++) {
             int mkIdx = random.nextInt(mks.size());
             // pick mk
             MongoMK mk = mks.get(mkIdx);

Added: 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/mongomk/ValueMapTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/mongomk/ValueMapTest.java?rev=1556761&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/mongomk/ValueMapTest.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/mongomk/ValueMapTest.java
 Thu Jan  9 08:49:16 2014
@@ -0,0 +1,138 @@
+/*
+ * 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.mongomk;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.jackrabbit.oak.plugins.mongomk.util.Utils;
+import org.junit.Test;
+
+import com.google.common.collect.Lists;
+
+import static org.apache.jackrabbit.oak.plugins.mongomk.Collection.NODES;
+import static org.apache.jackrabbit.oak.plugins.mongomk.Document.ID;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Test cases for OAK-1233.
+ */
+public class ValueMapTest {
+
+    @Test
+    public void previousDocs1() {
+        String rootId = Utils.getIdFromPath("/");
+        Revision r0 = new Revision(0, 0, 1);
+        MemoryDocumentStore store = new MemoryDocumentStore();
+        // create previous docs
+        UpdateOp op = new UpdateOp(Utils.getPreviousIdFor(rootId, r0), true);
+        op.set(ID, op.getId());
+        op.setMapEntry("prop", r0, "0");
+        NodeDocument.setRevision(op, r0, "c");
+        store.createOrUpdate(NODES, op);
+        Revision r1low = new Revision(1, 0, 1);
+        Revision r1high = new Revision(1, 10, 1);
+        op = new UpdateOp(Utils.getPreviousIdFor(rootId, r1high), true);
+        op.set(ID, op.getId());
+        for (int i = r1low.getCounter(); i <= r1high.getCounter(); i++) {
+            Revision r = new Revision(1, i, 1);
+            op.setMapEntry("foo", r, String.valueOf(i));
+            NodeDocument.setRevision(op, r, "c");
+        }
+        store.createOrUpdate(NODES, op);
+        // create root doc
+        op = new UpdateOp(rootId, true);
+        op.set(ID, op.getId());
+        Revision r2 = new Revision(2, 0, 1);
+        op.setMapEntry("prop", r2, "1");
+        NodeDocument.setRevision(op, r2, "c");
+        NodeDocument.setPrevious(op, r0, r0);
+        NodeDocument.setPrevious(op, r1high, r1low);
+        store.createOrUpdate(NODES, op);
+
+        NodeDocument doc = store.find(NODES, rootId);
+        assertNotNull(doc);
+        Set<Revision> revs = doc.getValueMap("prop").keySet();
+        assertEquals(2, revs.size());
+        assertTrue(revs.contains(r0));
+        assertTrue(revs.contains(r2));
+        Iterator<Revision> it = revs.iterator();
+        assertTrue(it.hasNext());
+        assertEquals(r2, it.next());
+        assertTrue(it.hasNext());
+        assertEquals(r0, it.next());
+    }
+
+    @Test
+    public void previousDocs2() {
+        MemoryDocumentStore store = new MemoryDocumentStore();
+        String rootId = Utils.getIdFromPath("/");
+        Revision r01 = new Revision(0, 0, 1);
+        Revision r12 = new Revision(1, 0, 2);
+        Revision r22 = new Revision(2, 0, 2);
+        Revision r31 = new Revision(3, 0, 1);
+        Revision r42 = new Revision(4, 0, 2);
+        Revision r51 = new Revision(5, 0, 1);
+        // create previous docs
+        UpdateOp op = new UpdateOp(Utils.getPreviousIdFor(rootId, r31), true);
+        op.set(ID, op.getId());
+        op.setMapEntry("p0", r01, "0");
+        NodeDocument.setRevision(op, r01, "c");
+        op.setMapEntry("p1", r31, "1");
+        NodeDocument.setRevision(op, r31, "c");
+        store.createOrUpdate(NODES, op);
+
+        op = new UpdateOp(Utils.getPreviousIdFor(rootId, r42), true);
+        op.set(ID, op.getId());
+        op.setMapEntry("p1", r12, "0");
+        NodeDocument.setRevision(op, r12, "c");
+        op.setMapEntry("p1", r22, "1");
+        NodeDocument.setRevision(op, r22, "c");
+        op.setMapEntry("p0", r42, "1");
+        NodeDocument.setRevision(op, r42, "c");
+        store.createOrUpdate(NODES, op);
+
+        // create root doc
+        op = new UpdateOp(rootId, true);
+        op.set(ID, op.getId());
+        op.setMapEntry("p0", r51, "2");
+        op.setMapEntry("p1", r51, "2");
+        NodeDocument.setRevision(op, r51, "c");
+        NodeDocument.setPrevious(op, r42, r12);
+        NodeDocument.setPrevious(op, r31, r01);
+        store.createOrUpdate(NODES, op);
+
+        NodeDocument doc = store.find(NODES, rootId);
+        assertNotNull(doc);
+        List<NodeDocument> prevDocs = Lists.newArrayList(
+                doc.getPreviousDocs("p1", null));
+        assertEquals(2, prevDocs.size());
+        assertEquals(Utils.getPreviousIdFor(rootId, r31), 
prevDocs.get(0).getId());
+        assertEquals(Utils.getPreviousIdFor(rootId, r42), 
prevDocs.get(1).getId());
+
+        List<Revision> revs = new ArrayList<Revision>();
+        for (Revision r : doc.getValueMap("p1").keySet()) {
+            revs.add(r);
+        }
+        assertEquals(Arrays.asList(r51, r31, r22, r12), revs);
+    }
+}

Propchange: 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/mongomk/ValueMapTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/mongomk/ValueMapTest.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Modified: 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/mongomk/util/MergeSortedIteratorsTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/mongomk/util/MergeSortedIteratorsTest.java?rev=1556761&r1=1556760&r2=1556761&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/mongomk/util/MergeSortedIteratorsTest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/mongomk/util/MergeSortedIteratorsTest.java
 Thu Jan  9 08:49:16 2014
@@ -17,7 +17,6 @@
 package org.apache.jackrabbit.oak.plugins.mongomk.util;
 
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.Comparator;
 import java.util.Iterator;
 import java.util.List;
@@ -55,7 +54,7 @@ public class MergeSortedIteratorsTest {
     public void testData(){
         List<Iterator<Revision>> iterators = prepareData();
         final Iterator<Iterator<Revision>> it = iterators.iterator();
-        final Comparator<Revision> comp = Collections.reverseOrder(new 
StableRevisionComparator());
+        final Comparator<Revision> comp = StableRevisionComparator.REVERSE;
         MergeSortedIterators<Revision> sort = new 
MergeSortedIterators<Revision>(comp) {
             @Override
             public Iterator<Revision> nextIterator() {


Reply via email to