jackrabbit-oak-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Marcel Reutegger <mreut...@adobe.com>
Subject RE: svn commit: r1522553 - in /jackrabbit/oak/trunk/oak-core/src: main/java/org/apache/jackrabbit/oak/plugins/mongomk/ test/java/org/apache/jackrabbit/oak/plugins/mongomk/
Date Mon, 16 Sep 2013 07:45:07 GMT
hi,

hmm, I didn't notice the failure in my checkout and cannot reproduce,
but it must be related to recent changes.

how often do you see the failure?

regards
 marcel

> -----Original Message-----
> From: Angela Schreiber
> Sent: Donnerstag, 12. September 2013 19:12
> To: oak-dev@jackrabbit.apache.org; Marcel Reutegger
> Subject: Re: svn commit: r1522553 - in /jackrabbit/oak/trunk/oak-core/src:
> main/java/org/apache/jackrabbit/oak/plugins/mongomk/
> test/java/org/apache/jackrabbit/oak/plugins/mongomk/
>
> hi marcel
>
> could it be that this commit is related to the following test failure?
> i experience it in a up to date checkout of the trunk.
>
> regards
> angela
>
> concurrent[1](org.apache.jackrabbit.oak.jcr.ConcurrentFileOperationsTest)
> Time elapsed: 0.473 sec  <<< ERROR!
> javax.jcr.RepositoryException: OakKernel0001: Failed to merge changes to
> the underlying MicroKernel
>       at
> org.apache.jackrabbit.oak.api.CommitFailedException.asRepositoryExceptio
> n(C
> ommitFailedException.java:242)
>       at
> org.apache.jackrabbit.oak.api.CommitFailedException.asRepositoryExceptio
> n(C
> ommitFailedException.java:207)
>       at
> org.apache.jackrabbit.oak.jcr.delegate.SessionDelegate.newRepositoryExce
> pti
> on(SessionDelegate.java:434)
>       at
> org.apache.jackrabbit.oak.jcr.delegate.SessionDelegate.save(SessionDelegat
> e
> .java:297)
>       at
> org.apache.jackrabbit.oak.jcr.session.SessionImpl$8.perform(SessionImpl.ja
> v
> a:399)
>       at
> org.apache.jackrabbit.oak.jcr.session.SessionImpl$8.perform(SessionImpl.ja
> v
> a:396)
>       at
> org.apache.jackrabbit.oak.jcr.delegate.SessionDelegate.perform(SessionDel
> eg
> ate.java:124)
>       at
> org.apache.jackrabbit.oak.jcr.session.SessionImpl.perform(SessionImpl.java:
> 117)
>       at
> org.apache.jackrabbit.oak.jcr.session.SessionImpl.save(SessionImpl.java:396
> )
>       at
> org.apache.jackrabbit.oak.jcr.ConcurrentFileOperationsTest$1.run(Concurre
> nt
> FileOperationsTest.java:103)
>       at java.lang.Thread.run(Thread.java:680)
> Caused by: org.apache.jackrabbit.oak.api.CommitFailedException:
> OakKernel0001: Failed to merge changes to the underlying MicroKernel
>       at
> org.apache.jackrabbit.oak.kernel.KernelNodeStoreBranch$Persisted.merge(
> Kern
> elNodeStoreBranch.java:384)
>       at
> org.apache.jackrabbit.oak.kernel.KernelNodeStoreBranch.merge(KernelNod
> eStor
> eBranch.java:136)
>       at
> org.apache.jackrabbit.oak.core.AbstractRoot$2.run(AbstractRoot.java:247)
>       at
> org.apache.jackrabbit.oak.core.AbstractRoot$2.run(AbstractRoot.java:243)
>       at java.security.AccessController.doPrivileged(Native Method)
>       at javax.security.auth.Subject.doAs(Subject.java:337)
>       at
> org.apache.jackrabbit.oak.core.AbstractRoot.commit(AbstractRoot.java:242)
>       at
> org.apache.jackrabbit.oak.jcr.delegate.SessionDelegate.save(SessionDelegat
> e
> .java:295)
>       ... 7 more
> Caused by: org.apache.jackrabbit.mk.api.MicroKernelException: Conflicting
> concurrent change. Update operation failed: key: 0:/ update
> {_collisions.r1411315f24a-0-1=CONTAINS_MAP_ENTRY false,
> _collisions.r1411315f251-0-1=CONTAINS_MAP_ENTRY false,
> _collisions.r1411315f3f6-0-1=CONTAINS_MAP_ENTRY false,
> _collisions.r1411315f402-0-1=CONTAINS_MAP_ENTRY false, _modified=SET
> 275800941, _revisions.r1411315f24a-0-1=SET_MAP_ENTRY c-r1411315f404-0-
> 1,
> _revisions.r1411315f251-0-1=SET_MAP_ENTRY c-r1411315f404-0-1,
> _revisions.r1411315f3f6-0-1=SET_MAP_ENTRY c-r1411315f404-0-1,
> _revisions.r1411315f402-0-1=SET_MAP_ENTRY c-r1411315f404-0-1}
>       at
> org.apache.jackrabbit.oak.plugins.mongomk.MongoMK.merge(MongoMK.ja
> va:1130)
>       at
> org.apache.jackrabbit.oak.kernel.KernelNodeStore.merge(KernelNodeStore
> .java
> :208)
>       at
> org.apache.jackrabbit.oak.kernel.KernelNodeStoreBranch$Persisted.merge(
> Kern
> elNodeStoreBranch.java:378)
>       ... 14 more
>
>
>
>
>
>
> On 9/12/13 2:45 PM, "mreutegg@apache.org" <mreutegg@apache.org>
> wrote:
>
> >Author: mreutegg
> >Date: Thu Sep 12 12:45:19 2013
> >New Revision: 1522553
> >
> >URL: http://svn.apache.org/r1522553
> >Log:
> >OAK-926: MongoMK: split documents when they are too large
> >- Generalize access to previous documents (WIP)
> >
> >Added:
> >
> >jackrabbit/oak/trunk/oak-
> core/src/main/java/org/apache/jackrabbit/oak/plug
> >ins/mongomk/Range.java   (with props)
> >
> >jackrabbit/oak/trunk/oak-
> core/src/main/java/org/apache/jackrabbit/oak/plug
> >ins/mongomk/ValueMap.java   (with props)
> >Modified:
> >
> >jackrabbit/oak/trunk/oak-
> core/src/main/java/org/apache/jackrabbit/oak/plug
> >ins/mongomk/NodeDocument.java
> >
> >jackrabbit/oak/trunk/oak-
> core/src/test/java/org/apache/jackrabbit/oak/plug
> >ins/mongomk/DocumentSplitTest.java
> >
> >Modified:
> >jackrabbit/oak/trunk/oak-
> core/src/main/java/org/apache/jackrabbit/oak/plug
> >ins/mongomk/NodeDocument.java
> >URL:
> >http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-
> core/src/main/java/o
> >rg/apache/jackrabbit/oak/plugins/mongomk/NodeDocument.java?rev=152
> 2553&r1=
> >1522552&r2=1522553&view=diff
> >=========================================================
> =================
> >====
> >---
> >jackrabbit/oak/trunk/oak-
> core/src/main/java/org/apache/jackrabbit/oak/plug
> >ins/mongomk/NodeDocument.java (original)
> >+++
> >jackrabbit/oak/trunk/oak-
> core/src/main/java/org/apache/jackrabbit/oak/plug
> >ins/mongomk/NodeDocument.java Thu Sep 12 12:45:19 2013
> >@@ -16,8 +16,6 @@
> >  */
> > package org.apache.jackrabbit.oak.plugins.mongomk;
> >
> >-import java.util.AbstractMap;
> >-import java.util.AbstractSet;
> > import java.util.ArrayList;
> > import java.util.Collections;
> > import java.util.Comparator;
> >@@ -44,10 +42,8 @@ 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.Iterators;
> > import com.google.common.collect.Maps;
> >
> >-import static com.google.common.base.Preconditions.checkArgument;
> > import static com.google.common.base.Preconditions.checkNotNull;
> >
> > /**
> >@@ -186,7 +182,7 @@ public class NodeDocument extends Docume
> >      */
> >     public boolean containsRevision(@Nonnull Revision revision) {
> >         String rev = checkNotNull(revision).toString();
> >-        if (getRevisionsMap().containsKey(rev)) {
> >+        if (getLocalRevisions().containsKey(rev)) {
> >             return true;
> >         }
> >         for (NodeDocument prev : getPreviousDocs(revision)) {
> >@@ -219,7 +215,7 @@ public class NodeDocument extends Docume
> >     public SortedMap<Revision, Revision>
> >getUncommittedRevisions(RevisionContext context) {
> >         // only look at revisions in this document.
> >         // uncommitted revisions are not split off
> >-        Map<String, String> valueMap = getRevisionsMap();
> >+        Map<String, String> valueMap = getLocalRevisions();
> >         SortedMap<Revision, Revision> revisions =
> >                 new TreeMap<Revision,
> >Revision>(context.getRevisionComparator());
> >         for (Map.Entry<String, String> commit : valueMap.entrySet()) {
> >@@ -244,11 +240,7 @@ public class NodeDocument extends Docume
> >      */
> >     @CheckForNull
> >     public String getCommitRootPath(String revision) {
> >-        @SuppressWarnings("unchecked")
> >-        Map<String, Integer> valueMap = (Map<String, Integer>)
> >get(COMMIT_ROOT);
> >-        if (valueMap == null) {
> >-            return null;
> >-        }
> >+        Map<String, Integer> valueMap = getCommitRoot();
> >         Integer depth = valueMap.get(revision);
> >         if (depth != null) {
> >             String p = Utils.getPathFromId(getId());
> >@@ -274,13 +266,9 @@ public class NodeDocument extends Docume
> >                                       CollisionHandler handler) {
> >         SortedSet<String> revisions = new
> >TreeSet<String>(Collections.reverseOrder());
> >         revisions.addAll(getRevisions().keySet());
> >-        if (data.containsKey(COMMIT_ROOT)) {
> >-            revisions.addAll(((Map<String, Integer>)
> >get(COMMIT_ROOT)).keySet());
> >-        }
> >-        Map<String, String> deletedMap = (Map<String, String>)
> >get(DELETED);
> >-        if (deletedMap != null) {
> >-            revisions.addAll(deletedMap.keySet());
> >-        }
> >+        revisions.addAll(getCommitRoot().keySet());
> >+        Map<String, String> deletedMap = getDeleted();
> >+        revisions.addAll(deletedMap.keySet());
> >         Revision newestRev = null;
> >         for (String r : revisions) {
> >             Revision propRev = Revision.fromString(r);
> >@@ -304,12 +292,10 @@ public class NodeDocument extends Docume
> >         if (newestRev == null) {
> >             return null;
> >         }
> >-        if (deletedMap != null) {
> >-            String value = deletedMap.get(newestRev.toString());
> >-            if ("true".equals(value)) {
> >-                // deleted in the newest revision
> >-                return null;
> >-            }
> >+        String value = deletedMap.get(newestRev.toString());
> >+        if ("true".equals(value)) {
> >+            // deleted in the newest revision
> >+            return null;
> >         }
> >         return newestRev;
> >     }
> >@@ -444,9 +430,8 @@ public class NodeDocument extends Docume
> >     public boolean isDeleted(RevisionContext context,
> >                              Revision readRevision,
> >                              Set<Revision> validRevisions) {
> >-        @SuppressWarnings("unchecked")
> >-        Map<String, String> valueMap = (Map<String, String>)
> >get(NodeDocument.DELETED);
> >-        if (valueMap == null) {
> >+        Map<String, String> valueMap = getDeleted();
> >+        if (valueMap.isEmpty()) {
> >             return false;
> >         }
> >         if (valueMap instanceof NavigableMap) {
> >@@ -487,9 +472,8 @@ public class NodeDocument extends Docume
> >     @CheckForNull
> >     public Revision getLiveRevision(RevisionContext context, Revision
> >maxRev,
> >                                     Set<Revision> validRevisions) {
> >-        @SuppressWarnings("unchecked")
> >-        Map<String, String> valueMap = (Map<String, String>)
> >get(NodeDocument.DELETED);
> >-        if (valueMap == null) {
> >+        Map<String, String> valueMap = getDeleted();
> >+        if (valueMap.isEmpty()) {
> >             return null;
> >         }
> >         // first, search the newest deleted revision
> >@@ -552,13 +536,10 @@ public class NodeDocument extends Docume
> >                                  @Nonnull Revision baseRevision,
> >                                  @Nonnull RevisionContext context) {
> >         // did existence of node change after baseRevision?
> >-        @SuppressWarnings("unchecked")
> >-        Map<String, String> deleted = (Map<String, String>) get(DELETED);
> >-        if (deleted != null) {
> >-            for (Map.Entry<String, String> entry : deleted.entrySet()) {
> >-                if (isRevisionNewer(context,
> >Revision.fromString(entry.getKey()), baseRevision)) {
> >-                    return true;
> >-                }
> >+        Map<String, String> deleted = getDeleted();
> >+        for (Map.Entry<String, String> entry : deleted.entrySet()) {
> >+            if (isRevisionNewer(context,
> >Revision.fromString(entry.getKey()), baseRevision)) {
> >+                return true;
> >             }
> >         }
> >
> >@@ -615,7 +596,7 @@ public class NodeDocument extends Docume
> >         }
> >         NavigableMap<Revision, String> splitRevs
> >                 = new TreeMap<Revision,
> >String>(context.getRevisionComparator());
> >-        Map<String, String> revisions = getRevisionsMap();
> >+        Map<String, String> revisions = getLocalRevisions();
> >         // only consider if there are enough revisions
> >         if (revisions.size() > REVISIONS_SPLIT_OFF_SIZE) {
> >             // collect commits of this cluster node after the
> >@@ -690,6 +671,88 @@ public class NodeDocument extends Docume
> >         return super.transformAndSeal(map, key, level);
> >     }
> >
> >+    /**
> >+     * Returns previous revision ranges for this document. The revision
> >keys are
> >+     * sorted descending, newest first!
> >+     *
> >+     * @return the previous ranges for this document.
> >+     */
> >+    @Nonnull
> >+    SortedMap<Revision, Range> getPreviousRanges() {
> >+        @SuppressWarnings("unchecked")
> >+        SortedMap<Revision, Range> previous = (SortedMap<Revision,
> >Range>) get(PREVIOUS);
> >+        if (previous == null) {
> >+            previous = EMPTY_RANGE_MAP;
> >+        }
> >+        return previous;
> >+    }
> >+
> >+    /**
> >+     * Returns previous {@link NodeDocument}, which include the given
> >revision.
> >+     * If the <code>revision</code> is <code>null</code>,
then all
> >previous
> >+     * documents are returned.
> >+     *
> >+     * @param revision the revision to match or <code>null</code>.
> >+     * @return previous documents.
> >+     */
> >+    Iterable<NodeDocument> getPreviousDocs(final @Nullable Revision
> >revision) {
> >+        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.containsRevision(revision.toString());
> >+            }
> >+        });
> >+    }
> >+
> >+    /**
> >+     * Returns the local value map for the given key. Returns
> ><code>null</code>
> >+     * if no such value map exists.
> >+     *
> >+     * @param key the key.
> >+     * @return local value map.
> >+     */
> >+    @Nonnull
> >+    Map<String, String> getLocalMap(String key) {
> >+        @SuppressWarnings("unchecked")
> >+        Map<String, String> map = (Map<String, String>) get(key);
> >+        if (map == null) {
> >+            map = Collections.emptyMap();
> >+        }
> >+        return map;
> >+    }
> >+
> >+    /**
> >+     * @return the {@link #REVISIONS} stored on this document.
> >+     */
> >+    @Nonnull
> >+    Map<String, String> getLocalRevisions() {
> >+        return getLocalMap(REVISIONS);
> >+    }
> >+
> >     //-------------------------< UpdateOp modifiers
> >>---------------------------
> >
> >     public static void setModified(@Nonnull UpdateOp op,
> >@@ -745,15 +808,12 @@ public class NodeDocument extends Docume
> >             return this;
> >         }
> >         // check commit root
> >-        @SuppressWarnings("unchecked")
> >-        Map<String, Integer> commitRoot = (Map<String, Integer>)
> >get(COMMIT_ROOT);
> >+        Map<String, Integer> commitRoot = getCommitRoot();
> >         String commitRootPath = null;
> >-        if (commitRoot != null) {
> >-            Integer depth = commitRoot.get(rev.toString());
> >-            if (depth != null) {
> >-                String p = Utils.getPathFromId(getId());
> >-                commitRootPath = PathUtils.getAncestorPath(p,
> >PathUtils.getDepth(p) - depth);
> >-            }
> >+        Integer depth = commitRoot.get(rev.toString());
> >+        if (depth != null) {
> >+            String p = Utils.getPathFromId(getId());
> >+            commitRootPath = PathUtils.getAncestorPath(p,
> >PathUtils.getDepth(p) - depth);
> >         }
> >         if (commitRootPath == null) {
> >             // shouldn't happen, either node is commit root for a
> >revision
> >@@ -835,11 +895,11 @@ public class NodeDocument extends Docume
> >     @CheckForNull
> >     private String getCommitValue(Revision revision) {
> >         String r = revision.toString();
> >-        String value = getRevisionsMap().get(r);
> >+        String value = getLocalRevisions().get(r);
> >         if (value == null) {
> >             // check previous
> >             for (NodeDocument prev : getPreviousDocs(revision)) {
> >-                value = prev.getRevisionsMap().get(r);
> >+                value = prev.getLocalRevisions().get(r);
> >                 if (value != null) {
> >                     break;
> >                 }
> >@@ -907,193 +967,23 @@ public class NodeDocument extends Docume
> >         return value;
> >     }
> >
> >-    Map<String, String> getRevisions() {
> >-        final Map<String, String> map = getRevisionsMap();
> >-        if (!data.containsKey(PREVIOUS)) {
> >-            return map;
> >-        }
> >-        final Set<Map.Entry<String, String>> revisions
> >-                = new AbstractSet<Map.Entry<String, String>>() {
> >-
> >-            @Override
> >-            @Nonnull
> >-            public Iterator<Map.Entry<String, String>> iterator() {
> >-                return Iterators.concat(map.entrySet().iterator(),
> >-                        Iterators.concat(new
> >Iterator<Iterator<Map.Entry<String, String>>>() {
> >-                            private final Iterator<NodeDocument> previous
> >-                                    = getPreviousDocs(null).iterator();
> >-
> >-                            @Override
> >-                            public boolean hasNext() {
> >-                                return previous.hasNext();
> >-                            }
> >-
> >-                            @Override
> >-                            public Iterator<Map.Entry<String, String>>
> >next() {
> >-                                return
> >previous.next().getRevisions().entrySet().iterator();
> >-                            }
> >-
> >-                            @Override
> >-                            public void remove() {
> >-                                throw new
> >UnsupportedOperationException();
> >-                            }
> >-                        }));
> >-            }
> >-
> >-            @Override
> >-            public int size() {
> >-                int size = map.size();
> >-                for (NodeDocument prev : getPreviousDocs(null)) {
> >-                    size += prev.getRevisions().size();
> >-                }
> >-                return size;
> >-            }
> >-        };
> >-        return new AbstractMap<String, String>() {
> >-
> >-            private final Map<String, String> map = getRevisionsMap();
> >-
> >-            @Override
> >-            @Nonnull
> >-            public Set<Entry<String, String>> entrySet() {
> >-                return revisions;
> >-            }
> >-
> >-            @Override
> >-            public String get(Object key) {
> >-                // first check revisions map of this document
> >-                String value = map.get(key);
> >-                if (value != null) {
> >-                    return value;
> >-                }
> >-                Revision r = Revision.fromString(key.toString());
> >-                for (NodeDocument prev : getPreviousDocs(r)) {
> >-                    value = prev.getRevisions().get(key);
> >-                    if (value != null) {
> >-                        return value;
> >-                    }
> >-                }
> >-                // not found
> >-                return null;
> >-            }
> >-
> >-            @Override
> >-            public boolean containsKey(Object key) {
> >-                // can use get()
> >-                // the revisions map does not have null values
> >-                return get(key) != null;
> >-            }
> >-
> >-        };
> >-    }
> >-
> >     @Nonnull
> >-    Map<String, String> getRevisionsMap() {
> >-        @SuppressWarnings("unchecked")
> >-        Map<String, String> map = (Map<String, String>) get(REVISIONS);
> >-        if (map == null) {
> >-            map = Collections.emptyMap();
> >-        }
> >-        return map;
> >+    private Map<String, String> getRevisions() {
> >+        return ValueMap.create(this, REVISIONS);
> >     }
> >
> >-    /**
> >-     * Returns previous {@link NodeDocument}, which include the given
> >revision.
> >-     * If the <code>revision</code> is <code>null</code>,
then all
> >previous
> >-     * documents are returned.
> >-     *
> >-     * @param revision the revision to match or <code>null</code>.
> >-     * @return previous documents.
> >-     */
> >-    Iterable<NodeDocument> getPreviousDocs(@Nullable final Revision
> >revision) {
> >-        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.containsRevision(revision.toString());
> >-            }
> >-        });
> >+    @Nonnull
> >+    private Map<String, String> getDeleted() {
> >+        return ValueMap.create(this, DELETED);
> >     }
> >
> >-    /**
> >-     * Returns previous revision ranges for this document. The revision
> >keys are
> >-     * sorted descending, newest first!
> >-     *
> >-     * @return the previous ranges for this document.
> >-     */
> >     @Nonnull
> >-    private SortedMap<Revision, Range> getPreviousRanges() {
> >+    private Map<String, Integer> getCommitRoot() {
> >         @SuppressWarnings("unchecked")
> >-        SortedMap<Revision, Range> previous = (SortedMap<Revision,
> >Range>) get(PREVIOUS);
> >-        if (previous == null) {
> >-            previous = EMPTY_RANGE_MAP;
> >-        }
> >-        return previous;
> >-    }
> >-
> >-    /**
> >-     * A range of revisions.
> >-     */
> >-    private static final class Range {
> >-
> >-        final Revision high;
> >-        final Revision low;
> >-
> >-        /**
> >-         * A range of revisions, with both inclusive bounds.
> >-         *
> >-         * @param high the high bound.
> >-         * @param low the low bound.
> >-         */
> >-        Range(@Nonnull Revision high, @Nonnull Revision low) {
> >-            this.high = checkNotNull(high);
> >-            this.low = checkNotNull(low);
> >-            checkArgument(high.getClusterId() == low.getClusterId(),
> >-                    "Revisions from have the same clusterId");
> >-            checkArgument(high.compareRevisionTime(low) > 0,
> >-                    "High Revision must be later than low Revision");
> >-        }
> >-
> >-        /**
> >-         * Returns <code>true</code> if the given revision is within
> >this range.
> >-         *
> >-         * @param r the revision to check.
> >-         * @return <code>true</code> if within this range;
> ><code>false</code>
> >-         * otherwise.
> >-         */
> >-        boolean includes(Revision r) {
> >-            return high.compareRevisionTime(r) >= 0
> >-                    && low.compareRevisionTime(r) <= 0;
> >-        }
> >-
> >-        @Override
> >-        public String toString() {
> >-            return low.toString();
> >+        Map<String, Integer> commitRoot = (Map<String, Integer>)
> >get(COMMIT_ROOT);
> >+        if (commitRoot == null) {
> >+            commitRoot = Collections.emptyMap();
> >         }
> >-
> >+        return commitRoot;
> >     }
> >-
> > }
> >
> >Added:
> >jackrabbit/oak/trunk/oak-
> core/src/main/java/org/apache/jackrabbit/oak/plug
> >ins/mongomk/Range.java
> >URL:
> >http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-
> core/src/main/java/o
> >rg/apache/jackrabbit/oak/plugins/mongomk/Range.java?rev=1522553&vie
> w=auto
> >=========================================================
> =================
> >====
> >---
> >jackrabbit/oak/trunk/oak-
> core/src/main/java/org/apache/jackrabbit/oak/plug
> >ins/mongomk/Range.java (added)
> >+++
> >jackrabbit/oak/trunk/oak-
> core/src/main/java/org/apache/jackrabbit/oak/plug
> >ins/mongomk/Range.java Thu Sep 12 12:45:19 2013
> >@@ -0,0 +1,63 @@
> >+/*
> >+ * 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 javax.annotation.Nonnull;
> >+
> >+import static com.google.common.base.Preconditions.checkArgument;
> >+import static com.google.common.base.Preconditions.checkNotNull;
> >+
> >+/**
> >+* A revision range for {@link NodeDocument#PREVIOUS} documents.
> >+*/
> >+final class Range {
> >+
> >+    final Revision high;
> >+    final Revision low;
> >+
> >+    /**
> >+     * A range of revisions, with both inclusive bounds.
> >+     *
> >+     * @param high the high bound.
> >+     * @param low the low bound.
> >+     */
> >+    Range(@Nonnull Revision high, @Nonnull Revision low) {
> >+        this.high = checkNotNull(high);
> >+        this.low = checkNotNull(low);
> >+        checkArgument(high.getClusterId() == low.getClusterId(),
> >+                "Revisions from have the same clusterId");
> >+        checkArgument(high.compareRevisionTime(low) > 0,
> >+                "High Revision must be later than low Revision");
> >+    }
> >+
> >+    /**
> >+     * Returns <code>true</code> if the given revision is within this
> >range.
> >+     *
> >+     * @param r the revision to check.
> >+     * @return <code>true</code> if within this range; <code>false</code>
> >+     * otherwise.
> >+     */
> >+    boolean includes(Revision r) {
> >+        return high.compareRevisionTime(r) >= 0
> >+                && low.compareRevisionTime(r) <= 0;
> >+    }
> >+
> >+    @Override
> >+    public String toString() {
> >+        return low.toString();
> >+    }
> >+}
> >
> >Propchange:
> >jackrabbit/oak/trunk/oak-
> core/src/main/java/org/apache/jackrabbit/oak/plug
> >ins/mongomk/Range.java
> >--------------------------------------------------------------------------
> >----
> >    svn:eol-style = native
> >
> >Propchange:
> >jackrabbit/oak/trunk/oak-
> core/src/main/java/org/apache/jackrabbit/oak/plug
> >ins/mongomk/Range.java
> >--------------------------------------------------------------------------
> >----
> >    svn:keywords = Author Date Id Revision Rev URL
> >
> >Added:
> >jackrabbit/oak/trunk/oak-
> core/src/main/java/org/apache/jackrabbit/oak/plug
> >ins/mongomk/ValueMap.java
> >URL:
> >http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-
> core/src/main/java/o
> >rg/apache/jackrabbit/oak/plugins/mongomk/ValueMap.java?rev=1522553
> &view=au
> >to
> >=========================================================
> =================
> >====
> >---
> >jackrabbit/oak/trunk/oak-
> core/src/main/java/org/apache/jackrabbit/oak/plug
> >ins/mongomk/ValueMap.java (added)
> >+++
> >jackrabbit/oak/trunk/oak-
> core/src/main/java/org/apache/jackrabbit/oak/plug
> >ins/mongomk/ValueMap.java Thu Sep 12 12:45:19 2013
> >@@ -0,0 +1,113 @@
> >+/*
> >+ * Licensed to the Apache Software Foundation (ASF) under one or more
> >+ * contributor license agreements.  See the NOTICE file distributed with
> >+ * this work for additional information regarding copyright ownership.
> >+ * The ASF licenses this file to You under the Apache License, Version
> >2.0
> >+ * (the "License"); you may not use this file except in compliance with
> >+ * the License.  You may obtain a copy of the License at
> >+ *
> >+ *      http://www.apache.org/licenses/LICENSE-2.0
> >+ *
> >+ * Unless required by applicable law or agreed to in writing, software
> >+ * distributed under the License is distributed on an "AS IS" BASIS,
> >+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
> or
> >implied.
> >+ * See the License for the specific language governing permissions and
> >+ * limitations under the License.
> >+ */
> >+package org.apache.jackrabbit.oak.plugins.mongomk;
> >+
> >+import java.util.AbstractMap;
> >+import java.util.AbstractSet;
> >+import java.util.Iterator;
> >+import java.util.Map;
> >+import java.util.Set;
> >+
> >+import javax.annotation.Nonnull;
> >+
> >+import com.google.common.collect.Iterators;
> >+
> >+/**
> >+ * A value map contains the versioned values of a property. The key into
> >this
> >+ * map is the revision when the value was set.
> >+ */
> >+class ValueMap {
> >+
> >+    @Nonnull
> >+    static Map<String, String> create(final @Nonnull NodeDocument doc,
> >+                                      final @Nonnull String property) {
> >+        final Map<String, String> map = doc.getLocalMap(property);
> >+        if (doc.getPreviousRanges().isEmpty()) {
> >+            return map;
> >+        }
> >+        final Set<Map.Entry<String, String>> values
> >+                = new AbstractSet<Map.Entry<String, String>>() {
> >+
> >+            @Override
> >+            @Nonnull
> >+            public Iterator<Map.Entry<String, String>> iterator() {
> >+                return Iterators.concat(map.entrySet().iterator(),
> >Iterators.concat(new Iterator<Iterator<Map.Entry<String, String>>>()
{
> >+                    private final Iterator<NodeDocument> previous =
> >doc.getPreviousDocs(null).iterator();
> >+
> >+                    @Override
> >+                    public boolean hasNext() {
> >+                        return previous.hasNext();
> >+                    }
> >+
> >+                    @Override
> >+                    public Iterator<Map.Entry<String, String>> next()
{
> >+                        return
> >previous.next().getLocalMap(property).entrySet().iterator();
> >+                    }
> >+
> >+                    @Override
> >+                    public void remove() {
> >+                        throw new UnsupportedOperationException();
> >+                    }
> >+                }));
> >+            }
> >+
> >+            @Override
> >+            public int size() {
> >+                int size = map.size();
> >+                for (NodeDocument prev : doc.getPreviousDocs(null)) {
> >+                    size += prev.getLocalMap(property).size();
> >+                }
> >+                return size;
> >+            }
> >+        };
> >+        return new AbstractMap<String, String>() {
> >+
> >+            private final Map<String, String> map =
> >doc.getLocalMap(property);
> >+
> >+            @Override
> >+            @Nonnull
> >+            public Set<Entry<String, String>> entrySet() {
> >+                return values;
> >+            }
> >+
> >+            @Override
> >+            public String get(Object key) {
> >+                // first check values map of this document
> >+                String value = map.get(key);
> >+                if (value != null) {
> >+                    return value;
> >+                }
> >+                Revision r = Revision.fromString(key.toString());
> >+                for (NodeDocument prev : doc.getPreviousDocs(r)) {
> >+                    value = prev.getLocalMap(property).get(key);
> >+                    if (value != null) {
> >+                        return value;
> >+                    }
> >+                }
> >+                // not found
> >+                return null;
> >+            }
> >+
> >+            @Override
> >+            public boolean containsKey(Object key) {
> >+                // can use get()
> >+                // the values map does not have null values
> >+                return get(key) != null;
> >+            }
> >+        };
> >+    }
> >+}
> >
> >Propchange:
> >jackrabbit/oak/trunk/oak-
> core/src/main/java/org/apache/jackrabbit/oak/plug
> >ins/mongomk/ValueMap.java
> >--------------------------------------------------------------------------
> >----
> >    svn:eol-style = native
> >
> >Propchange:
> >jackrabbit/oak/trunk/oak-
> core/src/main/java/org/apache/jackrabbit/oak/plug
> >ins/mongomk/ValueMap.java
> >--------------------------------------------------------------------------
> >----
> >    svn:keywords = Author Date Id Revision Rev URL
> >
> >Modified:
> >jackrabbit/oak/trunk/oak-
> core/src/test/java/org/apache/jackrabbit/oak/plug
> >ins/mongomk/DocumentSplitTest.java
> >URL:
> >http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-
> core/src/test/java/o
> >rg/apache/jackrabbit/oak/plugins/mongomk/DocumentSplitTest.java?rev=
> 152255
> >3&r1=1522552&r2=1522553&view=diff
> >=========================================================
> =================
> >====
> >---
> >jackrabbit/oak/trunk/oak-
> core/src/test/java/org/apache/jackrabbit/oak/plug
> >ins/mongomk/DocumentSplitTest.java (original)
> >+++
> >jackrabbit/oak/trunk/oak-
> core/src/test/java/org/apache/jackrabbit/oak/plug
> >ins/mongomk/DocumentSplitTest.java Thu Sep 12 12:45:19 2013
> >@@ -39,7 +39,7 @@ public class DocumentSplitTest extends B
> >         Set<String> revisions = Sets.newHashSet();
> >         NodeDocument doc = store.find(Collection.NODES,
> >Utils.getIdFromPath("/"));
> >         assertNotNull(doc);
> >-        revisions.addAll(doc.getRevisionsMap().keySet());
> >+        revisions.addAll(doc.getLocalRevisions().keySet());
> >
> >         // MongoMK initializes with a root node with a single revision
> >         int numRevs = 1;
> >@@ -55,7 +55,7 @@ public class DocumentSplitTest extends B
> >         String head = mk.getHeadRevision();
> >         doc = store.find(Collection.NODES, Utils.getIdFromPath("/"));
> >         assertNotNull(doc);
> >-        Map<String, String> revs = doc.getRevisionsMap();
> >+        Map<String, String> revs = doc.getLocalRevisions();
> >         // one remaining in the local revisions map
> >         assertEquals(1, revs.size());
> >         for (String r : revisions) {
> >
> >


Mime
View raw message