You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by mr...@apache.org on 2016/01/07 13:46:36 UTC
svn commit: r1723532 [1/5] - in /jackrabbit/oak/trunk:
oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/
oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/util/
oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/d...
Author: mreutegg
Date: Thu Jan 7 12:46:35 2016
New Revision: 1723532
URL: http://svn.apache.org/viewvc?rev=1723532&view=rev
Log:
OAK-3646: Inconsistent read of hierarchy
Added:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/RevisionVector.java (with props)
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStateTest.java (with props)
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/RevisionVectorTest.java (with props)
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/BatchCommitQueue.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/Branch.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/Checkpoints.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/ClusterNodeInfo.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/ClusterNodeInfoDocument.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/Commit.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/CommitDiff.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/CommitQueue.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DiffCache.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentCheckpointMBean.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentMK.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeState.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreBranch.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreMBean.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/JournalEntry.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/LastRevs.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/LocalDiffCache.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/MemoryDiffCache.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/MergeCommit.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/NodeDocument.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/PathRev.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/Revision.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/RevisionContext.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/SplitOperations.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/StableRevisionComparator.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/TieredDiffCache.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/UnmergedBranches.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/VersionGarbageCollector.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/util/RevisionsKey.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/util/Utils.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/AmnesiaDiffCache.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/BranchTest.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/CheckpointsTest.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/ClusterRevisionComparisonTest.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/ClusterTest.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/CommitQueueTest.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/CommitTest.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/CountingTieredDiffCache.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreTest.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentSplitTest.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DummyRevisionContext.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/JournalEntryTest.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/JournalTest.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/LastRevRecoveryAgentTest.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/LastRevRecoveryTest.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/MeasureMemory.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/MongoDocumentStoreTest.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/NodeDocumentTest.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/OrphanedBranchTest.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/RevisionTest.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/SimpleTest.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/UnmergedBranchTest.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/mongo/CollisionMarkerTest.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/persistentCache/BroadcastTest.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/persistentCache/CacheTest.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/util/RevisionsKeyTest.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/util/UtilsTest.java
jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreHelper.java
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/BatchCommitQueue.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/BatchCommitQueue.java?rev=1723532&r1=1723531&r2=1723532&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/BatchCommitQueue.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/BatchCommitQueue.java Thu Jan 7 12:46:35 2016
@@ -16,7 +16,6 @@
*/
package org.apache.jackrabbit.oak.plugins.document;
-import java.util.Comparator;
import java.util.Map;
import java.util.concurrent.Callable;
@@ -49,12 +48,8 @@ final class BatchCommitQueue {
private final DocumentStore store;
- private final Comparator<Revision> comparator;
-
- BatchCommitQueue(@Nonnull DocumentStore store,
- @Nonnull Comparator<Revision> comparator) {
+ BatchCommitQueue(@Nonnull DocumentStore store) {
this.store = checkNotNull(store);
- this.comparator = checkNotNull(comparator);
}
Callable<NodeDocument> updateDocument(UpdateOp op) {
@@ -103,8 +98,4 @@ final class BatchCommitQueue {
DocumentStore getStore() {
return store;
}
-
- Comparator<Revision> getComparator() {
- return comparator;
- }
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/Branch.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/Branch.java?rev=1723532&r1=1723531&r2=1723532&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/Branch.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/Branch.java Thu Jan 7 12:46:35 2016
@@ -53,7 +53,7 @@ class Branch {
/**
* The initial base revision of this branch.
*/
- private final Revision base;
+ private final RevisionVector base;
/**
* The branch reference.
@@ -76,7 +76,7 @@ class Branch {
* @throws IllegalArgumentException if base is a branch revision.
*/
Branch(@Nonnull SortedSet<Revision> commits,
- @Nonnull Revision base,
+ @Nonnull RevisionVector base,
@Nonnull ReferenceQueue<Object> queue,
@Nullable Object guard) {
checkArgument(!checkNotNull(base).isBranch(), "base is not a trunk revision: %s", base);
@@ -97,7 +97,7 @@ class Branch {
* @return the initial base of this branch.
*/
@Nonnull
- Revision getBase() {
+ RevisionVector getBase() {
return base;
}
@@ -110,7 +110,7 @@ class Branch {
* this branch.
*/
@Nonnull
- Revision getBase(@Nonnull Revision r) {
+ RevisionVector getBase(@Nonnull Revision r) {
BranchCommit c = commits.get(checkNotNull(r).asBranchRevision());
if (c == null) {
throw new IllegalArgumentException(
@@ -127,11 +127,11 @@ class Branch {
* @throws IllegalArgumentException if head is a trunk revision or base is a
* branch revision.
*/
- void rebase(@Nonnull Revision head, @Nonnull Revision base) {
+ void rebase(@Nonnull Revision head, @Nonnull RevisionVector base) {
checkArgument(checkNotNull(head).isBranch(), "Not a branch revision: %s", head);
checkArgument(!checkNotNull(base).isBranch(), "Not a trunk revision: %s", base);
Revision last = commits.lastKey();
- checkArgument(commits.comparator().compare(head, last) > 0);
+ checkArgument(head.compareRevisionTime(last) > 0);
commits.put(head, new RebaseCommit(base, head, commits));
}
@@ -294,15 +294,15 @@ class Branch {
*/
abstract static class BranchCommit implements LastRevTracker {
- protected final Revision base;
+ protected final RevisionVector base;
protected final Revision commit;
- BranchCommit(Revision base, Revision commit) {
+ BranchCommit(RevisionVector base, Revision commit) {
this.base = base;
this.commit = commit;
}
- Revision getBase() {
+ RevisionVector getBase() {
return base;
}
@@ -322,7 +322,7 @@ class Branch {
private final Set<String> modifications = Sets.newHashSet();
- BranchCommitImpl(Revision base, Revision commit) {
+ BranchCommitImpl(RevisionVector base, Revision commit) {
super(base, commit);
}
@@ -365,7 +365,7 @@ class Branch {
private final NavigableMap<Revision, BranchCommit> previous;
- RebaseCommit(Revision base, Revision commit,
+ RebaseCommit(RevisionVector base, Revision commit,
NavigableMap<Revision, BranchCommit> previous) {
super(base, commit);
this.previous = squash(previous);
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/Checkpoints.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/Checkpoints.java?rev=1723532&r1=1723531&r2=1723532&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/Checkpoints.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/Checkpoints.java Thu Jan 7 12:46:35 2016
@@ -27,6 +27,7 @@ import java.util.concurrent.atomic.Atomi
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
import org.apache.jackrabbit.oak.commons.json.JsopBuilder;
import org.apache.jackrabbit.oak.commons.json.JsopReader;
@@ -37,12 +38,17 @@ import org.slf4j.LoggerFactory;
import com.google.common.collect.Maps;
+import static com.google.common.base.Preconditions.checkNotNull;
+
/**
* Checkpoints provide details around which revision are to be kept. These
* are stored in Settings collection.
*/
class Checkpoints {
+
+ private static final Logger LOG = LoggerFactory.getLogger(Checkpoints.class);
+
private static final String ID = "checkpoint";
/**
@@ -76,10 +82,11 @@ class Checkpoints {
public Revision create(long lifetimeInMillis, Map<String, String> info) {
// create a unique dummy commit we can use as checkpoint revision
Revision r = nodeStore.commitQueue.createRevision();
+ final RevisionVector[] rv = new RevisionVector[1];
nodeStore.commitQueue.done(r, new CommitQueue.Callback() {
@Override
public void headOfQueue(@Nonnull Revision revision) {
- // do nothing
+ rv[0] = nodeStore.getHeadRevision();
}
});
createCounter.getAndIncrement();
@@ -88,7 +95,7 @@ class Checkpoints {
long endTime = BigInteger.valueOf(nodeStore.getClock().getTime())
.add(BigInteger.valueOf(lifetimeInMillis))
.min(BigInteger.valueOf(Long.MAX_VALUE)).longValue();
- op.setMapEntry(PROP_CHECKPOINT, r, new Info(endTime, info).toString());
+ op.setMapEntry(PROP_CHECKPOINT, r, new Info(endTime, rv[0], info).toString());
store.createOrUpdate(Collection.SETTINGS, op);
return r;
}
@@ -113,7 +120,7 @@ class Checkpoints {
//Get uncached doc
SortedMap<Revision, Info> checkpoints = getCheckpoints();
- if(checkpoints == null){
+ if(checkpoints.isEmpty()){
log.debug("No checkpoint registered so far");
return null;
}
@@ -142,24 +149,53 @@ class Checkpoints {
}
@SuppressWarnings("unchecked")
- @CheckForNull
+ @Nonnull
SortedMap<Revision, Info> getCheckpoints() {
Document cdoc = store.find(Collection.SETTINGS, ID, 0);
- SortedMap<Revision, String> data =
- (SortedMap<Revision, String>) cdoc.get(PROP_CHECKPOINT);
- if (data == null) {
+ SortedMap<Revision, String> data = null;
+ if (cdoc != null) {
+ data = (SortedMap<Revision, String>) cdoc.get(PROP_CHECKPOINT);
+ }
+ SortedMap<Revision, Info> checkpoints = Maps.newTreeMap(StableRevisionComparator.REVERSE);
+ if (data != null) {
+ for (Map.Entry<Revision, String> entry : data.entrySet()) {
+ checkpoints.put(entry.getKey(), Info.fromString(entry.getValue()));
+ }
+ }
+ return checkpoints;
+ }
+
+ /**
+ * Retrieves the head revision for the given {@code checkpoint}.
+ *
+ * @param checkpoint the checkpoint reference.
+ * @return the head revision associated with the checkpoint or {@code null}
+ * if there is no such checkpoint.
+ * @throws IllegalArgumentException if the checkpoint is malformed.
+ */
+ @CheckForNull
+ RevisionVector retrieve(@Nonnull String checkpoint)
+ throws IllegalArgumentException {
+ Revision r;
+ try {
+ r = Revision.fromString(checkNotNull(checkpoint));
+ } catch (IllegalArgumentException e) {
+ LOG.warn("Malformed checkpoint reference: {}", checkpoint);
return null;
}
- SortedMap<Revision, Info> checkpoints = Maps.newTreeMap(data.comparator());
- for (Map.Entry<Revision, String> entry : data.entrySet()) {
- checkpoints.put(entry.getKey(), Info.fromString(entry.getValue()));
+ Info info = getCheckpoints().get(r);
+ if (info == null) {
+ return null;
}
- return checkpoints;
+ RevisionVector rv = info.getCheckpoint();
+ if (rv == null) {
+ rv = expand(r);
+ }
+ return rv;
}
- int size(){
- SortedMap<Revision, Info> checkpoints = getCheckpoints();
- return checkpoints == null ? 0 : checkpoints.size();
+ int size() {
+ return getCheckpoints().size();
}
/**
@@ -182,21 +218,47 @@ class Checkpoints {
}
}
+ private RevisionVector expand(Revision checkpoint) {
+ LOG.warn("Expanding {} single revision checkpoint into a " +
+ "RevisionVector. Please make sure all cluster nodes run " +
+ "with the same Oak version.", checkpoint);
+ // best effort conversion
+ Map<Integer, Revision> revs = Maps.newHashMap();
+ RevisionVector head = nodeStore.getHeadRevision();
+ for (Revision r : head) {
+ int cId = r.getClusterId();
+ if (cId == checkpoint.getClusterId()) {
+ revs.put(cId, r);
+ } else {
+ revs.put(cId, new Revision(checkpoint.getTimestamp(), 0, cId));
+ }
+ }
+ return head.pmin(new RevisionVector(revs.values()));
+ }
+
static final class Info {
private static final String EXPIRES = "expires";
+ private static final String REVISION_VECTOR = "rv";
+
private final long expiryTime;
+ private final RevisionVector checkpoint;
+
private final Map<String, String> info;
- private Info(long expiryTime, Map<String, String> info) {
+ private Info(long expiryTime,
+ @Nullable RevisionVector checkpoint,
+ @Nonnull Map<String, String> info) {
this.expiryTime = expiryTime;
+ this.checkpoint = checkpoint;
this.info = Collections.unmodifiableMap(info);
}
static Info fromString(String info) {
long expiryTime;
+ RevisionVector rv = null;
Map<String, String> map;
if (info.startsWith("{")) {
map = Maps.newHashMap();
@@ -212,7 +274,19 @@ class Checkpoints {
while (reader.matches(',')) {
key = reader.readString();
reader.read(':');
- map.put(key, reader.readString());
+ String value = reader.readString();
+ // second entry is potentially checkpoint revision vector
+ if (rv == null && map.isEmpty() && REVISION_VECTOR.equals(key)) {
+ // try to read checkpoint
+ try {
+ rv = RevisionVector.fromString(value);
+ } catch (IllegalArgumentException e) {
+ // not a revision vector, read as regular info entry
+ map.put(key, value);
+ }
+ } else {
+ map.put(key, value);
+ }
}
reader.read('}');
reader.read(JsopReader.END);
@@ -221,7 +295,7 @@ class Checkpoints {
map = Collections.emptyMap();
expiryTime = Long.parseLong(info);
}
- return new Info(expiryTime, map);
+ return new Info(expiryTime, rv, map);
}
Map<String, String> get() {
@@ -232,11 +306,26 @@ class Checkpoints {
return expiryTime;
}
+ /**
+ * The revision vector associated with this checkpoint or {@code null}
+ * if this checkpoint was created with a version of Oak, which did not
+ * yet support revision vectors.
+ *
+ * @return the revision vector checkpoint or {@code null}.
+ */
+ @CheckForNull
+ RevisionVector getCheckpoint() {
+ return checkpoint;
+ }
+
@Override
public String toString() {
JsopWriter writer = new JsopBuilder();
writer.object();
writer.key(EXPIRES).value(Long.toString(expiryTime));
+ if (checkpoint != null) {
+ writer.key(REVISION_VECTOR).value(checkpoint.toString());
+ }
for (Map.Entry<String, String> entry : info.entrySet()) {
writer.key(entry.getKey()).value(entry.getValue());
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/ClusterNodeInfo.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/ClusterNodeInfo.java?rev=1723532&r1=1723531&r2=1723532&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/ClusterNodeInfo.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/ClusterNodeInfo.java Thu Jan 7 12:46:35 2016
@@ -71,6 +71,11 @@ public class ClusterNodeInfo {
public static final String LEASE_END_KEY = "leaseEnd";
/**
+ * The start time.
+ */
+ public static final String START_TIME_KEY = "startTime";
+
+ /**
* The key for the root-revision of the last background write (of unsaved
* modifications) - that is: the last root-revision written by the instance
* in case of a clear shutdown or via recovery of another instance in case
@@ -385,6 +390,7 @@ public class ClusterNodeInfo {
} else {
update.set(LEASE_END_KEY, clusterNode.leaseEndTime);
}
+ update.set(START_TIME_KEY, clusterNode.startTime);
update.set(INFO_KEY, clusterNode.toString());
update.set(STATE, clusterNode.state.name());
update.set(REV_RECOVERY_LOCK, clusterNode.revRecoveryLock.name());
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/ClusterNodeInfoDocument.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/ClusterNodeInfoDocument.java?rev=1723532&r1=1723531&r2=1723532&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/ClusterNodeInfoDocument.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/ClusterNodeInfoDocument.java Thu Jan 7 12:46:35 2016
@@ -39,10 +39,34 @@ public class ClusterNodeInfoDocument ext
*/
private static final String MAX_ID_VALUE = "a";
+ /**
+ * The timestamp when this document was created.
+ */
+ private final long created = Revision.getCurrentTimestamp();
+
+ /**
+ * @return the timestamp when this document was created.
+ */
+ public long getCreated() {
+ return created;
+ }
+
public long getLeaseEndTime(){
return checkNotNull((Long) get(ClusterNodeInfo.LEASE_END_KEY), "Lease End Time not set");
}
+ /**
+ * @return the time when this cluster node was started or {@code -1} if not
+ * available.
+ */
+ public long getStartTime() {
+ Long startTime = (Long) get(ClusterNodeInfo.START_TIME_KEY);
+ if (startTime == null) {
+ startTime = -1L;
+ }
+ return startTime;
+ }
+
public boolean isActive(){
return getState() == ClusterNodeState.ACTIVE;
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/Commit.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/Commit.java?rev=1723532&r1=1723531&r2=1723532&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/Commit.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/Commit.java Thu Jan 7 12:46:35 2016
@@ -31,10 +31,13 @@ import javax.annotation.Nullable;
import com.google.common.base.Function;
import com.google.common.collect.Sets;
+
+import org.apache.jackrabbit.oak.api.PropertyState;
import org.apache.jackrabbit.oak.commons.json.JsopStream;
import org.apache.jackrabbit.oak.commons.json.JsopWriter;
import org.apache.jackrabbit.oak.plugins.document.util.Utils;
import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -47,7 +50,6 @@ import static org.apache.jackrabbit.oak.
import static org.apache.jackrabbit.oak.plugins.document.Collection.NODES;
import static org.apache.jackrabbit.oak.plugins.document.NodeDocument.COLLISIONS;
import static org.apache.jackrabbit.oak.plugins.document.NodeDocument.SPLIT_CANDIDATE_THRESHOLD;
-import static org.apache.jackrabbit.oak.plugins.document.util.Utils.isRevisionNewer;
/**
* A higher level object representing a commit.
@@ -58,7 +60,7 @@ public class Commit {
protected final DocumentNodeStore nodeStore;
private final DocumentNodeStoreBranch branch;
- private final Revision baseRevision;
+ private final RevisionVector baseRevision;
private final Revision revision;
private final HashMap<String, UpdateOp> operations = new LinkedHashMap<String, UpdateOp>();
private final JsopWriter diff = new JsopStream();
@@ -90,7 +92,7 @@ public class Commit {
*/
Commit(@Nonnull DocumentNodeStore nodeStore,
@Nonnull Revision revision,
- @Nullable Revision baseRevision,
+ @Nullable RevisionVector baseRevision,
@Nullable DocumentNodeStoreBranch branch) {
this.nodeStore = checkNotNull(nodeStore);
this.revision = checkNotNull(revision);
@@ -129,7 +131,7 @@ public class Commit {
* @return the base revision of this commit or <code>null</code>.
*/
@CheckForNull
- Revision getBaseRevision() {
+ RevisionVector getBaseRevision() {
return baseRevision;
}
@@ -167,7 +169,7 @@ public class Commit {
LOG.error(msg);
throw new DocumentStoreException(msg);
}
- operations.put(path, n.asOperation(true));
+ operations.put(path, n.asOperation(revision));
addedNodes.add(path);
}
@@ -178,13 +180,11 @@ public class Commit {
/**
* Applies this commit to the store.
*
- * @return the commit revision.
* @throws DocumentStoreException if the commit cannot be applied.
*/
- @Nonnull
- Revision apply() throws DocumentStoreException {
+ void apply() throws DocumentStoreException {
boolean success = false;
- Revision baseRev = getBaseRevision();
+ RevisionVector baseRev = getBaseRevision();
boolean isBranch = baseRev != null && baseRev.isBranch();
Revision rev = getRevision();
if (isBranch && !nodeStore.isDisableBranches()) {
@@ -218,10 +218,6 @@ public class Commit {
} else {
applyInternal();
}
- if (isBranch) {
- rev = rev.asBranchRevision();
- }
- return rev;
}
/**
@@ -235,7 +231,7 @@ public class Commit {
}
}
- private void prepare(Revision baseRevision) {
+ private void prepare(RevisionVector baseRevision) {
if (!operations.isEmpty()) {
updateParentChildStatus();
updateBinaryStatus();
@@ -271,7 +267,7 @@ public class Commit {
* @param baseBranchRevision the base revision of this commit. Currently only
* used for branch commits.
*/
- private void applyToDocumentStore(Revision baseBranchRevision) {
+ private void applyToDocumentStore(RevisionVector baseBranchRevision) {
// the value in _revisions.<revision> property of the commit root node
// regular commits use "c", which makes the commit visible to
// other readers. branch commits use the base revision to indicate
@@ -402,8 +398,8 @@ public class Commit {
dse = new DocumentStoreException(msg);
} else {
dse = new ConflictException(msg,
- commitRootDoc.getMostRecentConflictFor(
- Collections.singleton(revision), nodeStore));
+ commitRootDoc.getConflictsFor(
+ Collections.singleton(revision)));
}
throw dse;
} else {
@@ -513,7 +509,7 @@ public class Commit {
if (baseRevision != null) {
Revision newestRev = null;
if (before != null) {
- Revision base = baseRevision;
+ RevisionVector base = baseRevision;
if (nodeStore.isDisableBranches()) {
base = base.asTrunkRevision();
}
@@ -536,7 +532,7 @@ public class Commit {
conflictMessage = "The node " +
op.getId() + " was already added in revision\n" +
formatConflictRevision(newestRev);
- } else if (nodeStore.isRevisionNewer(newestRev, baseRevision)
+ } else if (baseRevision.isRevisionNewer(newestRev)
&& (op.isDelete() || isConflicting(before, op))) {
conflictMessage = "The node " +
op.getId() + " was changed in revision\n" +
@@ -576,9 +572,7 @@ public class Commit {
conflictMessage += ", before\n" + revision;
if (LOG.isDebugEnabled()) {
LOG.debug(conflictMessage + "; document:\n" +
- (before == null ? "" : before.format()) +
- ",\nrevision order:\n" +
- nodeStore.getRevisionComparator());
+ (before == null ? "" : before.format()));
}
throw new ConflictException(conflictMessage, conflictRevision);
}
@@ -586,7 +580,7 @@ public class Commit {
}
private String formatConflictRevision(Revision r) {
- if (isRevisionNewer(nodeStore, r, nodeStore.getHeadRevision())) {
+ if (nodeStore.getHeadRevision().isRevisionNewer(r)) {
return r + " (not yet visible)";
} else {
return r.toString();
@@ -612,7 +606,7 @@ public class Commit {
// or document did not exist before
return false;
}
- return doc.isConflicting(op, baseRevision, revision, nodeStore,
+ return doc.isConflicting(op, baseRevision, revision,
nodeStore.getEnableConcurrentAddRemove());
}
@@ -644,7 +638,8 @@ public class Commit {
return null;
}
if (b == null) {
- b = nodeStore.getBranches().getBranch(revision);
+ b = nodeStore.getBranches().getBranch(
+ new RevisionVector(revision.asBranchRevision()));
}
return b;
}
@@ -655,7 +650,7 @@ public class Commit {
* @param before the revision right before this commit.
* @param isBranchCommit whether this is a commit to a branch
*/
- public void applyToCache(Revision before, boolean isBranchCommit) {
+ public void applyToCache(RevisionVector before, boolean isBranchCommit) {
HashMap<String, ArrayList<String>> nodesWithChangedChildren = new HashMap<String, ArrayList<String>>();
for (String p : modifiedNodes) {
if (denotesRoot(p)) {
@@ -669,7 +664,8 @@ public class Commit {
}
list.add(p);
}
- DiffCache.Entry cacheEntry = nodeStore.getDiffCache().newEntry(before, revision, true);
+ RevisionVector after = before.update(revision);
+ DiffCache.Entry cacheEntry = nodeStore.getDiffCache().newEntry(before, after, true);
LastRevTracker tracker = nodeStore.createTracker(revision, isBranchCommit);
List<String> added = new ArrayList<String>();
List<String> removed = new ArrayList<String>();
@@ -696,7 +692,7 @@ public class Commit {
// track intermediate node and root
tracker.track(path);
}
- nodeStore.applyChanges(revision, path, isNew,
+ nodeStore.applyChanges(after, path, isNew,
added, removed, changed, cacheEntry);
}
cacheEntry.done();
@@ -733,11 +729,14 @@ public class Commit {
diff.tag('-').value(path).newline();
}
- public void removeNode(String path) {
+ public void removeNode(String path, NodeState state) {
removedNodes.add(path);
UpdateOp op = getUpdateOperationForNode(path);
op.setDelete(true);
NodeDocument.setDeleted(op, revision, true);
+ for (PropertyState p : state.getProperties()) {
+ updateProperty(path, p.getName(), null);
+ }
}
private static final Function<UpdateOp.Key, String> KEY_TO_NAME =
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/CommitDiff.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/CommitDiff.java?rev=1723532&r1=1723531&r2=1723532&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/CommitDiff.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/CommitDiff.java Thu Jan 7 12:46:35 2016
@@ -83,7 +83,8 @@ class CommitDiff implements NodeStateDif
@Override
public boolean childNodeAdded(String name, NodeState after) {
String p = PathUtils.concat(path, name);
- commit.addNode(new DocumentNodeState(store, p, commit.getRevision()));
+ commit.addNode(new DocumentNodeState(store, p,
+ new RevisionVector(commit.getRevision())));
return after.compareAgainstBaseState(EMPTY_NODE,
new CommitDiff(store, commit, p, builder, blobs));
}
@@ -100,7 +101,7 @@ class CommitDiff implements NodeStateDif
@Override
public boolean childNodeDeleted(String name, NodeState before) {
String p = PathUtils.concat(path, name);
- commit.removeNode(p);
+ commit.removeNode(p, before);
return MISSING_NODE.compareAgainstBaseState(before,
new CommitDiff(store, commit, p, builder, blobs));
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/CommitQueue.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/CommitQueue.java?rev=1723532&r1=1723531&r2=1723532&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/CommitQueue.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/CommitQueue.java Thu Jan 7 12:46:35 2016
@@ -19,7 +19,6 @@ package org.apache.jackrabbit.oak.plugin
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
-import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
@@ -116,14 +115,13 @@ final class CommitQueue {
* @param conflictRevisions the revisions to become visible.
*/
void suspendUntilAll(@Nonnull Set<Revision> conflictRevisions) {
- Comparator<Revision> comparator = context.getRevisionComparator();
Semaphore s;
int addedRevisions;
synchronized (suspendedCommits) {
- Revision headRevision = context.getHeadRevision();
+ RevisionVector headRevision = context.getHeadRevision();
Set<Revision> afterHead = new HashSet<Revision>(conflictRevisions.size());
for (Revision r : conflictRevisions) {
- if (comparator.compare(r, headRevision) > 0) {
+ if (headRevision.isRevisionNewer(r)) {
afterHead.add(r);
}
}
@@ -182,11 +180,11 @@ final class CommitQueue {
if (suspendedCommits.isEmpty()) {
return;
}
- Revision headRevision = context.getHeadRevision();
+ RevisionVector headRevision = context.getHeadRevision();
Iterator<SuspendedCommit> it = suspendedCommits.values().iterator();
while (it.hasNext()) {
SuspendedCommit suspended = it.next();
- if (suspended.removeRevisionsYoungerThan(headRevision) && suspended.revisions.isEmpty()) {
+ if (suspended.removeRevisionsVisibleFrom(headRevision) && suspended.revisions.isEmpty()) {
it.remove();
}
}
@@ -308,12 +306,11 @@ final class CommitQueue {
this.revisions = revisions;
}
- private boolean removeRevisionsYoungerThan(Revision revision) {
- Comparator<Revision> comparator = context.getRevisionComparator();
+ private boolean removeRevisionsVisibleFrom(RevisionVector revision) {
Iterator<Revision> it = revisions.iterator();
boolean removed = false;
while (it.hasNext()) {
- if (comparator.compare(it.next(), revision) <= 0) {
+ if (!revision.isRevisionNewer(it.next())) {
it.remove();
semaphore.release();
removed = true;
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DiffCache.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DiffCache.java?rev=1723532&r1=1723531&r2=1723532&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DiffCache.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DiffCache.java Thu Jan 7 12:46:35 2016
@@ -49,8 +49,8 @@ abstract class DiffCache {
* @return the diff or {@code null} if unknown and no loader was passed.
*/
@CheckForNull
- abstract String getChanges(@Nonnull Revision from,
- @Nonnull Revision to,
+ abstract String getChanges(@Nonnull RevisionVector from,
+ @Nonnull RevisionVector to,
@Nonnull String path,
@Nullable Loader loader);
@@ -65,8 +65,8 @@ abstract class DiffCache {
* @return the cache entry.
*/
@Nonnull
- abstract Entry newEntry(@Nonnull Revision from,
- @Nonnull Revision to,
+ abstract Entry newEntry(@Nonnull RevisionVector from,
+ @Nonnull RevisionVector to,
boolean local);
/**
@@ -77,7 +77,7 @@ abstract class DiffCache {
/**
* Parses the jsop diff returned by
- * {@link #getChanges(Revision, Revision, String, Loader)} and reports the
+ * {@link #getChanges(RevisionVector, RevisionVector, String, Loader)} and reports the
* changes by calling the appropriate methods on {@link Diff}.
*
* @param jsop the jsop diff to parse.
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentCheckpointMBean.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentCheckpointMBean.java?rev=1723532&r1=1723531&r2=1723532&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentCheckpointMBean.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentCheckpointMBean.java Thu Jan 7 12:46:35 2016
@@ -44,9 +44,6 @@ public class DocumentCheckpointMBean ext
@Override
protected void collectCheckpoints(TabularDataSupport tab) throws OpenDataException {
Map<Revision, Info> checkpoints = store.getCheckpoints().getCheckpoints();
- if (checkpoints == null) {
- checkpoints = Collections.emptyMap();
- }
for (Entry<Revision, Info> checkpoint : checkpoints.entrySet()) {
String id = checkpoint.getKey().toString();
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentMK.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentMK.java?rev=1723532&r1=1723531&r2=1723532&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentMK.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentMK.java Thu Jan 7 12:46:35 2016
@@ -183,8 +183,8 @@ public class DocumentMK {
if (path == null || path.equals("")) {
path = "/";
}
- Revision fromRev = Revision.fromString(fromRevisionId);
- Revision toRev = Revision.fromString(toRevisionId);
+ RevisionVector fromRev = RevisionVector.fromString(fromRevisionId);
+ RevisionVector toRev = RevisionVector.fromString(toRevisionId);
final DocumentNodeState before = nodeStore.getNode(path, fromRev);
final DocumentNodeState after = nodeStore.getNode(path, toRev);
if (before == null || after == null) {
@@ -206,7 +206,7 @@ public class DocumentMK {
throw new DocumentStoreException("Path is not absolute: " + path);
}
revisionId = revisionId != null ? revisionId : nodeStore.getHeadRevision().toString();
- Revision rev = Revision.fromString(revisionId);
+ RevisionVector rev = RevisionVector.fromString(revisionId);
DocumentNodeState n;
try {
n = nodeStore.getNode(path, rev);
@@ -223,7 +223,7 @@ public class DocumentMK {
throw new DocumentStoreException("Only depth 0 is supported, depth is " + depth);
}
revisionId = revisionId != null ? revisionId : nodeStore.getHeadRevision().toString();
- Revision rev = Revision.fromString(revisionId);
+ RevisionVector rev = RevisionVector.fromString(revisionId);
try {
DocumentNodeState n = nodeStore.getNode(path, rev);
if (n == null) {
@@ -267,22 +267,21 @@ public class DocumentMK {
public String commit(String rootPath, String jsonDiff, String baseRevId,
String message) throws DocumentStoreException {
boolean success = false;
- boolean isBranch = false;
- Revision rev;
- Commit commit = nodeStore.newCommit(baseRevId != null ? Revision.fromString(baseRevId) : null, null);
+ boolean isBranch;
+ RevisionVector rev;
+ Commit commit = nodeStore.newCommit(baseRevId != null ? RevisionVector.fromString(baseRevId) : null, null);
try {
- Revision baseRev = commit.getBaseRevision();
+ RevisionVector baseRev = commit.getBaseRevision();
isBranch = baseRev != null && baseRev.isBranch();
parseJsonDiff(commit, jsonDiff, rootPath);
- rev = commit.apply();
+ commit.apply();
+ rev = nodeStore.done(commit, isBranch, null);
success = true;
} catch (DocumentStoreException e) {
throw new DocumentStoreException(e);
} finally {
if (!success) {
nodeStore.canceled(commit);
- } else {
- nodeStore.done(commit, isBranch, null);
}
}
return rev.toString();
@@ -291,15 +290,15 @@ public class DocumentMK {
public String branch(@Nullable String trunkRevisionId) throws DocumentStoreException {
// nothing is written when the branch is created, the returned
// revision simply acts as a reference to the branch base revision
- Revision revision = trunkRevisionId != null
- ? Revision.fromString(trunkRevisionId) : nodeStore.getHeadRevision();
- return revision.asBranchRevision().toString();
+ RevisionVector revision = trunkRevisionId != null
+ ? RevisionVector.fromString(trunkRevisionId) : nodeStore.getHeadRevision();
+ return revision.asBranchRevision(nodeStore.getClusterId()).toString();
}
public String merge(String branchRevisionId, String message)
throws DocumentStoreException {
// TODO improve implementation if needed
- Revision revision = Revision.fromString(branchRevisionId);
+ RevisionVector revision = RevisionVector.fromString(branchRevisionId);
if (!revision.isBranch()) {
throw new DocumentStoreException("Not a branch: " + branchRevisionId);
}
@@ -316,9 +315,9 @@ public class DocumentMK {
public String rebase(@Nonnull String branchRevisionId,
@Nullable String newBaseRevisionId)
throws DocumentStoreException {
- Revision r = Revision.fromString(branchRevisionId);
- Revision base = newBaseRevisionId != null ?
- Revision.fromString(newBaseRevisionId) :
+ RevisionVector r = RevisionVector.fromString(branchRevisionId);
+ RevisionVector base = newBaseRevisionId != null ?
+ RevisionVector.fromString(newBaseRevisionId) :
nodeStore.getHeadRevision();
return nodeStore.rebase(r, base).toString();
}
@@ -327,11 +326,11 @@ public class DocumentMK {
public String reset(@Nonnull String branchRevisionId,
@Nonnull String ancestorRevisionId)
throws DocumentStoreException {
- Revision branch = Revision.fromString(branchRevisionId);
+ RevisionVector branch = RevisionVector.fromString(branchRevisionId);
if (!branch.isBranch()) {
throw new DocumentStoreException("Not a branch revision: " + branchRevisionId);
}
- Revision ancestor = Revision.fromString(ancestorRevisionId);
+ RevisionVector ancestor = RevisionVector.fromString(ancestorRevisionId);
if (!ancestor.isBranch()) {
throw new DocumentStoreException("Not a branch revision: " + ancestorRevisionId);
}
@@ -377,7 +376,7 @@ public class DocumentMK {
//------------------------------< internal >--------------------------------
private void parseJsonDiff(Commit commit, String json, String rootPath) {
- Revision baseRev = commit.getBaseRevision();
+ RevisionVector baseRev = commit.getBaseRevision();
String baseRevId = baseRev != null ? baseRev.toString() : null;
Set<String> added = Sets.newHashSet();
JsopReader t = new JsopTokenizer(json);
@@ -399,7 +398,7 @@ public class DocumentMK {
if (toRemove == null) {
throw new DocumentStoreException("Node not found: " + path + " in revision " + baseRevId);
}
- commit.removeNode(path);
+ commit.removeNode(path, toRemove);
nodeStore.markAsDeleted(toRemove, commit, true);
commit.removeNodeDiff(path);
break;
@@ -460,7 +459,8 @@ public class DocumentMK {
}
private void parseAddNode(Commit commit, JsopReader t, String path) {
- DocumentNodeState n = new DocumentNodeState(nodeStore, path, commit.getRevision());
+ DocumentNodeState n = new DocumentNodeState(nodeStore, path,
+ new RevisionVector(commit.getRevision()));
if (!t.matches('}')) {
do {
String key = t.readString();
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeState.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeState.java?rev=1723532&r1=1723531&r2=1723532&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeState.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeState.java Thu Jan 7 12:46:35 2016
@@ -81,9 +81,9 @@ public class DocumentNodeState extends A
static final int MAX_FETCH_SIZE = INITIAL_FETCH_SIZE << 4;
final String path;
- final Revision rev;
- Revision lastRevision;
- final Revision rootRevision;
+ final RevisionVector readRevision;
+ RevisionVector lastRevision;
+ final RevisionVector rootRevision;
final boolean fromExternalChange;
final Map<String, PropertyState> properties;
final boolean hasChildren;
@@ -92,29 +92,29 @@ public class DocumentNodeState extends A
DocumentNodeState(@Nonnull DocumentNodeStore store,
@Nonnull String path,
- @Nonnull Revision rev) {
- this(store, path, rev, false);
+ @Nonnull RevisionVector readRevision) {
+ this(store, path, readRevision, false);
}
DocumentNodeState(@Nonnull DocumentNodeStore store, @Nonnull String path,
- @Nonnull Revision rev, boolean hasChildren) {
- this(store, path, rev, new HashMap<String, PropertyState>(),
+ @Nonnull RevisionVector readRevision, boolean hasChildren) {
+ this(store, path, readRevision, new HashMap<String, PropertyState>(),
hasChildren, null, null, false);
}
private DocumentNodeState(@Nonnull DocumentNodeStore store,
@Nonnull String path,
- @Nonnull Revision rev,
+ @Nonnull RevisionVector readRevision,
@Nonnull Map<String, PropertyState> properties,
boolean hasChildren,
- @Nullable Revision lastRevision,
- @Nullable Revision rootRevision,
+ @Nullable RevisionVector lastRevision,
+ @Nullable RevisionVector rootRevision,
boolean fromExternalChange) {
this.store = checkNotNull(store);
this.path = checkNotNull(path);
- this.rev = checkNotNull(rev);
+ this.readRevision = checkNotNull(readRevision);
this.lastRevision = lastRevision;
- this.rootRevision = rootRevision != null ? rootRevision : rev;
+ this.rootRevision = rootRevision != null ? rootRevision : readRevision;
this.fromExternalChange = fromExternalChange;
this.hasChildren = hasChildren;
this.properties = checkNotNull(properties);
@@ -133,12 +133,12 @@ public class DocumentNodeState extends A
* @return a copy of this node state with the given root revision and
* external change flag.
*/
- private DocumentNodeState withRootRevision(@Nonnull Revision root,
+ private DocumentNodeState withRootRevision(@Nonnull RevisionVector root,
boolean externalChange) {
if (rootRevision.equals(root) && fromExternalChange == externalChange) {
return this;
} else {
- return new DocumentNodeState(store, path, rev, properties,
+ return new DocumentNodeState(store, path, readRevision, properties,
hasChildren, lastRevision, root, externalChange);
}
}
@@ -149,7 +149,7 @@ public class DocumentNodeState extends A
*/
@Nonnull
DocumentNodeState fromExternalChange() {
- return new DocumentNodeState(store, path, rev, properties, hasChildren,
+ return new DocumentNodeState(store, path, readRevision, properties, hasChildren,
lastRevision, rootRevision, true);
}
@@ -162,8 +162,8 @@ public class DocumentNodeState extends A
}
@Nonnull
- Revision getRevision() {
- return rev;
+ RevisionVector getRevision() {
+ return readRevision;
}
/**
@@ -178,7 +178,7 @@ public class DocumentNodeState extends A
* same value as returned by {@link #getRevision()}.
*/
@Nonnull
- Revision getRootRevision() {
+ RevisionVector getRootRevision() {
return rootRevision;
}
@@ -295,9 +295,9 @@ public class DocumentNodeState extends A
@Override
public NodeBuilder builder() {
if ("/".equals(getPath())) {
- if (rev.isBranch()) {
+ if (readRevision.isBranch()) {
// check if this node state is head of a branch
- Branch b = store.getBranches().getBranch(rev);
+ Branch b = store.getBranches().getBranch(readRevision);
if (b == null) {
if (store.isDisableBranches()) {
if (DocumentNodeStoreBranch.getCurrentBranch() != null) {
@@ -306,10 +306,10 @@ public class DocumentNodeState extends A
return new MemoryNodeBuilder(this);
}
} else {
- throw new IllegalStateException("No branch for revision: " + rev);
+ throw new IllegalStateException("No branch for revision: " + readRevision);
}
}
- if (b.isHead(rev)
+ if (b.isHead(readRevision.getBranchRevision())
&& DocumentNodeStoreBranch.getCurrentBranch() != null) {
return new DocumentRootBuilder(this, store);
} else {
@@ -346,9 +346,9 @@ public class DocumentNodeState extends A
perfLogger
.end(start,
1,
- "compareAgainstBaseState, path={}, rev={}, lastRevision={}, base.path={}, base.rev={}, base.lastRevision={}",
- path, rev, lastRevision,
- mBase.path, mBase.rev,
+ "compareAgainstBaseState, path={}, readRevision={}, lastRevision={}, base.path={}, base.readRevision={}, base.lastRevision={}",
+ path, readRevision, lastRevision,
+ mBase.path, mBase.readRevision,
mBase.lastRevision);
}
}
@@ -400,26 +400,28 @@ public class DocumentNodeState extends A
public String toString() {
StringBuilder buff = new StringBuilder();
buff.append("{ path: '").append(path).append("', ");
- buff.append("rev: '").append(rev).append("', ");
+ buff.append("readRevision: '").append(readRevision).append("', ");
buff.append("properties: '").append(properties.values()).append("' }");
return buff.toString();
}
/**
- * Create an add node operation for this node.
+ * Create an add operation for this node at the given revision.
+ *
+ * @param revision the revision this node is created.
*/
- UpdateOp asOperation(boolean isNew) {
+ UpdateOp asOperation(@Nonnull Revision revision) {
String id = Utils.getIdFromPath(path);
- UpdateOp op = new UpdateOp(id, isNew);
+ UpdateOp op = new UpdateOp(id, true);
op.set(Document.ID, id);
if (Utils.isLongPath(path)) {
op.set(NodeDocument.PATH, path);
}
- NodeDocument.setModified(op, rev);
- NodeDocument.setDeleted(op, rev, false);
+ NodeDocument.setModified(op, revision);
+ NodeDocument.setDeleted(op, revision, false);
for (String p : properties.keySet()) {
String key = Utils.escapePropertyName(p);
- op.setMapEntry(key, rev, getPropertyAsString(p));
+ op.setMapEntry(key, revision, getPropertyAsString(p));
}
return op;
}
@@ -441,17 +443,21 @@ public class DocumentNodeState extends A
}
}
- void setLastRevision(Revision lastRevision) {
+ void setLastRevision(RevisionVector lastRevision) {
this.lastRevision = lastRevision;
}
- Revision getLastRevision() {
+ RevisionVector getLastRevision() {
return lastRevision;
}
@Override
public int getMemory() {
- int size = 164 + estimateMemoryUsage(path);
+ int size = 40 // shallow
+ + readRevision.getMemory()
+ + (lastRevision != null ? lastRevision.getMemory() : 0)
+ + rootRevision.getMemory()
+ + estimateMemoryUsage(path);
// rough approximation for properties
for (Map.Entry<String, PropertyState> entry : properties.entrySet()) {
// name
@@ -461,10 +467,11 @@ public class DocumentNodeState extends A
&& propState.getType() != Type.BINARIES) {
for (int i = 0; i < propState.count(); i++) {
// size() returns length of string
- // overhead:
+ // shallow memory:
// - 8 bytes per reference in values list
// - 48 bytes per string
- size += 56 + propState.size(i) * 2;
+ // double useage per property because of parsed PropertyState
+ size += (56 + propState.size(i) * 2) * 2;
}
} else {
// calculate size based on blobId value
@@ -481,14 +488,14 @@ public class DocumentNodeState extends A
/**
* Returns {@code true} if this state has the same revision as the
- * {@code other} state. This method first compares the read {@link #rev}
+ * {@code other} state. This method first compares the {@link #readRevision}
* and then the {@link #lastRevision}.
*
* @param other the other state to compare with.
* @return {@code true} if the revisions are equal, {@code false} otherwise.
*/
private boolean revisionEquals(DocumentNodeState other) {
- return this.rev.equals(other.rev)
+ return this.readRevision.equals(other.readRevision)
|| this.lastRevision.equals(other.lastRevision);
}
@@ -529,12 +536,12 @@ public class DocumentNodeState extends A
public String asString() {
JsopWriter json = new JsopBuilder();
json.key("path").value(path);
- json.key("rev").value(rev.toString());
+ json.key("rev").value(readRevision.toString());
if (lastRevision != null) {
json.key("lastRev").value(lastRevision.toString());
}
if (hasChildren) {
- json.key("hasChildren").value(hasChildren);
+ json.key("hasChildren").value(true);
}
if (properties.size() > 0) {
json.key("prop").object();
@@ -549,8 +556,8 @@ public class DocumentNodeState extends A
public static DocumentNodeState fromString(DocumentNodeStore store, String s) {
JsopTokenizer json = new JsopTokenizer(s);
String path = null;
- Revision rev = null;
- Revision lastRev = null;
+ RevisionVector rev = null;
+ RevisionVector lastRev = null;
boolean hasChildren = false;
DocumentNodeState state = null;
HashMap<String, String> map = new HashMap<String, String>();
@@ -560,9 +567,9 @@ public class DocumentNodeState extends A
if ("path".equals(k)) {
path = json.readString();
} else if ("rev".equals(k)) {
- rev = Revision.fromString(json.readString());
+ rev = RevisionVector.fromString(json.readString());
} else if ("lastRev".equals(k)) {
- lastRev = Revision.fromString(json.readString());
+ lastRev = RevisionVector.fromString(json.readString());
} else if ("hasChildren".equals(k)) {
hasChildren = json.read() == JsopReader.TRUE;
} else if ("prop".equals(k)) {