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 [2/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...
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java?rev=1723532&r1=1723531&r2=1723532&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java Thu Jan 7 12:46:35 2016
@@ -42,17 +42,14 @@ import java.lang.ref.WeakReference;
import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.Date;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.NavigableSet;
import java.util.Set;
-import java.util.SortedMap;
import java.util.TimeZone;
import java.util.concurrent.Callable;
-import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
@@ -68,6 +65,7 @@ import javax.annotation.Nullable;
import javax.management.NotCompliantMBeanException;
import com.google.common.base.Function;
+import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
@@ -83,7 +81,6 @@ import org.apache.jackrabbit.oak.commons
import org.apache.jackrabbit.oak.plugins.blob.BlobStoreBlob;
import org.apache.jackrabbit.oak.plugins.blob.MarkSweepGarbageCollector;
import org.apache.jackrabbit.oak.plugins.blob.ReferencedBlob;
-import org.apache.jackrabbit.oak.plugins.document.Checkpoints.Info;
import org.apache.jackrabbit.oak.plugins.document.cache.CacheInvalidationStats;
import org.apache.jackrabbit.oak.plugins.document.persistentCache.PersistentCache;
import org.apache.jackrabbit.oak.spi.blob.BlobStore;
@@ -95,7 +92,6 @@ import org.apache.jackrabbit.oak.api.Com
import org.apache.jackrabbit.oak.cache.CacheStats;
import org.apache.jackrabbit.oak.commons.PathUtils;
import org.apache.jackrabbit.oak.json.BlobSerializer;
-import org.apache.jackrabbit.oak.plugins.document.Branch.BranchCommit;
import org.apache.jackrabbit.oak.plugins.document.util.LeaseCheckDocumentStoreWrapper;
import org.apache.jackrabbit.oak.plugins.document.util.LoggingDocumentStoreWrapper;
import org.apache.jackrabbit.oak.plugins.document.util.StringValue;
@@ -135,13 +131,6 @@ public final class DocumentNodeStore
static final int NUM_CHILDREN_CACHE_LIMIT = Integer.getInteger("oak.documentMK.childrenCacheLimit", 16 * 1024);
/**
- * When trying to access revisions that are older than this many
- * milliseconds, a warning is logged. The default is one minute.
- */
- private static final int WARN_REVISION_AGE =
- Integer.getInteger("oak.documentMK.revisionAge", 60 * 1000);
-
- /**
* Feature flag to enable concurrent add/remove operations of hidden empty
* nodes. See OAK-2673.
*/
@@ -155,12 +144,6 @@ public final class DocumentNodeStore
Boolean.parseBoolean(System.getProperty("oak.fairBackgroundOperationLock", "true"));
/**
- * How long to remember the relative order of old revision of all cluster
- * nodes, in milliseconds. The default is one hour.
- */
- static final int REMEMBER_REVISION_ORDER_MILLIS = 60 * 60 * 1000;
-
- /**
* The document store (might be used by multiple node stores).
*/
protected final DocumentStore store;
@@ -214,24 +197,12 @@ public final class DocumentNodeStore
private final int clusterId;
/**
- * Map of inactive cluster nodes and when the cluster node was last seen
- * as inactive.
- * Key: clusterId, value: timeInMillis
+ * Map of known cluster nodes and the last known state updated
+ * by {@link #updateClusterState()}.
+ * Key: clusterId, value: ClusterNodeInfoDocument
*/
- private final ConcurrentMap<Integer, Long> inactiveClusterNodes
- = new ConcurrentHashMap<Integer, Long>();
-
- /**
- * Map of active cluster nodes and when the cluster node's lease ends.
- * Key: clusterId, value: leaseEndTimeInMillis
- */
- private final ConcurrentMap<Integer, Long> activeClusterNodes
- = new ConcurrentHashMap<Integer, Long>();
-
- /**
- * The comparator for revisions.
- */
- private final Revision.RevisionComparator revisionComparator;
+ private final ConcurrentMap<Integer, ClusterNodeInfoDocument> clusterNodes
+ = Maps.newConcurrentMap();
/**
* Unmerged branches of this DocumentNodeStore instance.
@@ -261,17 +232,9 @@ public final class DocumentNodeStore
private JournalEntry changes;
/**
- * The last known revision for each cluster instance.
- *
- * Key: the machine id, value: revision.
+ * The current root node state.
*/
- private final Map<Integer, Revision> lastKnownRevision =
- new ConcurrentHashMap<Integer, Revision>();
-
- /**
- * The last known head revision. This is the last-known revision.
- */
- private volatile Revision headRevision;
+ private volatile DocumentNodeState root;
private Thread backgroundReadThread;
@@ -444,8 +407,7 @@ public final class DocumentNodeStore
}
this.store = s;
this.clusterId = cid;
- this.revisionComparator = new Revision.RevisionComparator(clusterId);
- this.branches = new UnmergedBranches(getRevisionComparator());
+ this.branches = new UnmergedBranches();
this.asyncDelay = builder.getAsyncDelay();
this.versionGarbageCollector = new VersionGarbageCollector(
this, builder.createVersionGCSupport());
@@ -454,7 +416,8 @@ public final class DocumentNodeStore
this.lastRevRecoveryAgent = new LastRevRecoveryAgent(this,
builder.createMissingLastRevSeeker());
this.disableBranches = builder.isDisableBranches();
- this.missing = new DocumentNodeState(this, "MISSING", new Revision(0, 0, 0)) {
+ this.missing = new DocumentNodeState(this, "MISSING",
+ new RevisionVector(new Revision(0, 0, 0))) {
@Override
public int getMemory() {
return 8;
@@ -482,14 +445,16 @@ public final class DocumentNodeStore
NodeDocument rootDoc = store.find(NODES, Utils.getIdFromPath("/"));
if (rootDoc == null) {
// root node is missing: repository is not initialized
- Revision head = newRevision();
- Commit commit = new Commit(this, head, null, null);
+ Revision commitRev = newRevision();
+ Commit commit = new Commit(this, commitRev, null, null);
+ RevisionVector head = new RevisionVector(commitRev);
DocumentNodeState n = new DocumentNodeState(this, "/", head);
commit.addNode(n);
commit.applyToDocumentStore();
// use dummy Revision as before
- commit.applyToCache(new Revision(0, 0, clusterId), false);
- setHeadRevision(commit.getRevision());
+ RevisionVector before = new RevisionVector(new Revision(0, 0, clusterId));
+ commit.applyToCache(before, false);
+ setRoot(head);
// make sure _lastRev is written back to store
backgroundWrite();
rootDoc = store.find(NODES, Utils.getIdFromPath("/"));
@@ -499,10 +464,10 @@ public final class DocumentNodeStore
}
} else {
checkLastRevRecovery();
- initializeHeadRevision(rootDoc);
+ initializeRootState(rootDoc);
// check if _lastRev for our clusterId exists
if (!rootDoc.getLastRev().containsKey(clusterId)) {
- unsavedLastRevisions.put("/", headRevision);
+ unsavedLastRevisions.put("/", getRoot().getRevision().getRevision(clusterId));
backgroundWrite();
}
}
@@ -510,15 +475,13 @@ public final class DocumentNodeStore
// Renew the lease because it may have been stale
renewClusterIdLease();
- getRevisionComparator().add(headRevision, Revision.newRevision(0));
-
// initialize branchCommits
branches.init(store, this);
dispatcher = new ChangeDispatcher(getRoot());
commitQueue = new CommitQueue(this);
String threadNamePostfix = "(" + clusterId + ")";
- batchCommitQueue = new BatchCommitQueue(store, revisionComparator);
+ batchCommitQueue = new BatchCommitQueue(store);
backgroundReadThread = new Thread(
new BackgroundReadOperation(this, isDisposed),
"DocumentNodeStore background read thread " + threadNamePostfix);
@@ -617,14 +580,9 @@ public final class DocumentNodeStore
return clusterNodeInfo.toString().replaceAll("[\r\n\t]", " ").trim();
}
- Revision setHeadRevision(@Nonnull Revision newHead) {
+ void setRoot(@Nonnull RevisionVector newHead) {
checkArgument(!newHead.isBranch());
- Revision previous = headRevision;
- if (!checkNotNull(newHead).equals(previous)) {
- // head changed
- headRevision = newHead;
- }
- return previous;
+ root = getRoot(newHead);
}
@Nonnull
@@ -647,10 +605,10 @@ public final class DocumentNodeStore
* @return a new commit.
*/
@Nonnull
- Commit newCommit(@Nullable Revision base,
+ Commit newCommit(@Nullable RevisionVector base,
@Nullable DocumentNodeStoreBranch branch) {
if (base == null) {
- base = headRevision;
+ base = getHeadRevision();
}
if (base.isBranch()) {
return newBranchCommit(base, branch);
@@ -670,9 +628,9 @@ public final class DocumentNodeStore
* @return a new merge commit.
*/
@Nonnull
- MergeCommit newMergeCommit(@Nullable Revision base, int numBranchCommits) {
+ MergeCommit newMergeCommit(@Nullable RevisionVector base, int numBranchCommits) {
if (base == null) {
- base = headRevision;
+ base = getHeadRevision();
}
backgroundOperationLock.readLock().lock();
boolean success = false;
@@ -689,30 +647,34 @@ public final class DocumentNodeStore
return c;
}
- void done(final @Nonnull Commit c, boolean isBranch, final @Nullable CommitInfo info) {
+ RevisionVector done(final @Nonnull Commit c, boolean isBranch, final @Nullable CommitInfo info) {
if (commitQueue.contains(c.getRevision())) {
try {
+ final RevisionVector[] newHead = new RevisionVector[1];
commitQueue.done(c.getRevision(), new CommitQueue.Callback() {
@Override
public void headOfQueue(@Nonnull Revision revision) {
// remember before revision
- Revision before = getHeadRevision();
+ RevisionVector before = getHeadRevision();
// apply changes to cache based on before revision
c.applyToCache(before, false);
// track modified paths
changes.modified(c.getModifiedPaths());
// update head revision
- setHeadRevision(c.getRevision());
+ newHead[0] = before.update(c.getRevision());
+ setRoot(newHead[0]);
commitQueue.headRevisionChanged();
dispatcher.contentChanged(getRoot(), info);
}
});
+ return newHead[0];
} finally {
backgroundOperationLock.readLock().unlock();
}
} else {
// branch commit
c.applyToCache(c.getBaseRevision(), isBranch);
+ return c.getBaseRevision().update(c.getRevision().asBranchRevision());
}
}
@@ -780,7 +742,7 @@ public final class DocumentNodeStore
nodeChildrenCache.invalidateAll();
}
- void invalidateNodeCache(String path, Revision revision){
+ void invalidateNodeCache(String path, RevisionVector revision){
nodeCache.invalidate(new PathRev(path, revision));
}
@@ -793,17 +755,6 @@ public final class DocumentNodeStore
}
/**
- * Checks that revision x is newer than another revision.
- *
- * @param x the revision to check
- * @param previous the presumed earlier revision
- * @return true if x is newer
- */
- boolean isRevisionNewer(@Nonnull Revision x, @Nonnull Revision previous) {
- return getRevisionComparator().compare(x, previous) > 0;
- }
-
- /**
* Enqueue the document with the given id as a split candidate.
*
* @param id the id of the document to check if it needs to be split.
@@ -821,7 +772,7 @@ public final class DocumentNodeStore
}
void markAsDeleted(DocumentNodeState node, Commit commit, boolean subTreeAlso) {
- commit.removeNode(node.getPath());
+ commit.removeNode(node.getPath(), node);
if (subTreeAlso) {
// recurse down the tree
@@ -842,8 +793,10 @@ public final class DocumentNodeStore
* given revision.
*/
@CheckForNull
- DocumentNodeState getNode(@Nonnull final String path, @Nonnull final Revision rev) {
- checkRevisionAge(checkNotNull(rev), checkNotNull(path));
+ DocumentNodeState getNode(@Nonnull final String path,
+ @Nonnull final RevisionVector rev) {
+ checkNotNull(rev);
+ checkNotNull(path);
final long start = PERFLOG.start();
try {
PathRev key = new PathRev(path, rev);
@@ -880,7 +833,7 @@ public final class DocumentNodeStore
return DocumentNodeState.NO_CHILDREN;
}
final String path = checkNotNull(parent).getPath();
- final Revision readRevision = parent.getLastRevision();
+ final RevisionVector readRevision = parent.getLastRevision();
try {
PathRev key = childNodeCacheKey(path, readRevision, name);
DocumentNodeState.Children children = nodeChildrenCache.get(key, new Callable<DocumentNodeState.Children>() {
@@ -925,8 +878,8 @@ public final class DocumentNodeStore
String name, int limit) {
String queriedName = name;
String path = parent.getPath();
- Revision rev = parent.getLastRevision();
- LOG.trace("Reading children for [{}] ast rev [{}]", path, rev);
+ RevisionVector rev = parent.getLastRevision();
+ LOG.trace("Reading children for [{}] at rev [{}]", path, rev);
Iterable<NodeDocument> docs;
DocumentNodeState.Children c = new DocumentNodeState.Children();
// add one to the requested limit for the raw limit
@@ -1082,7 +1035,7 @@ public final class DocumentNodeStore
return Collections.emptyList();
}
- final Revision readRevision = parent.getLastRevision();
+ final RevisionVector readRevision = parent.getLastRevision();
return transform(getChildren(parent, name, limit).children, new Function<String, DocumentNodeState>() {
@Override
public DocumentNodeState apply(String input) {
@@ -1097,7 +1050,7 @@ public final class DocumentNodeStore
}
@CheckForNull
- DocumentNodeState readNode(String path, Revision readRevision) {
+ DocumentNodeState readNode(String path, RevisionVector readRevision) {
final long start = PERFLOG.start();
String id = Utils.getIdFromPath(path);
Revision lastRevision = getPendingModifications().get(path);
@@ -1124,7 +1077,7 @@ public final class DocumentNodeStore
* @param changed the list of changed child nodes.
*
*/
- void applyChanges(Revision rev, String path,
+ void applyChanges(RevisionVector rev, String path,
boolean isNew, List<String> added,
List<String> removed, List<String> changed,
DiffCache.Entry cacheEntry) {
@@ -1245,7 +1198,7 @@ public final class DocumentNodeStore
* @return the root node state at the given revision.
*/
@Nonnull
- DocumentNodeState getRoot(@Nonnull Revision revision) {
+ DocumentNodeState getRoot(@Nonnull RevisionVector revision) {
DocumentNodeState root = getNode("/", revision);
if (root == null) {
throw new IllegalStateException(
@@ -1264,7 +1217,8 @@ public final class DocumentNodeStore
}
@Nonnull
- Revision rebase(@Nonnull Revision branchHead, @Nonnull Revision base) {
+ RevisionVector rebase(@Nonnull RevisionVector branchHead,
+ @Nonnull RevisionVector base) {
checkNotNull(branchHead);
checkNotNull(base);
if (disableBranches) {
@@ -1274,33 +1228,33 @@ public final class DocumentNodeStore
Branch b = getBranches().getBranch(branchHead);
if (b == null) {
// empty branch
- return base.asBranchRevision();
+ return base.asBranchRevision(getClusterId());
}
- if (b.getBase(branchHead).equals(base)) {
+ if (b.getBase(branchHead.getBranchRevision()).equals(base)) {
return branchHead;
}
// add a pseudo commit to make sure current head of branch
// has a higher revision than base of branch
Revision head = newRevision().asBranchRevision();
b.rebase(head, base);
- return head;
+ return base.update(head);
}
@Nonnull
- Revision reset(@Nonnull Revision branchHead,
- @Nonnull Revision ancestor,
- @Nullable DocumentNodeStoreBranch branch) {
+ RevisionVector reset(@Nonnull RevisionVector branchHead,
+ @Nonnull RevisionVector ancestor,
+ @Nullable DocumentNodeStoreBranch branch) {
checkNotNull(branchHead);
checkNotNull(ancestor);
Branch b = getBranches().getBranch(branchHead);
if (b == null) {
throw new DocumentStoreException("Empty branch cannot be reset");
}
- if (!b.getCommits().last().equals(branchHead)) {
+ if (!b.getCommits().last().equals(branchHead.getRevision(getClusterId()))) {
throw new DocumentStoreException(branchHead + " is not the head " +
"of a branch");
}
- if (!b.containsCommit(ancestor)) {
+ if (!b.containsCommit(ancestor.getBranchRevision())) {
throw new DocumentStoreException(ancestor + " is not " +
"an ancestor revision of " + branchHead);
}
@@ -1311,15 +1265,17 @@ public final class DocumentNodeStore
boolean success = false;
Commit commit = newCommit(branchHead, branch);
try {
- Iterator<Revision> it = b.getCommits().tailSet(ancestor).iterator();
+ Iterator<Revision> it = b.getCommits().tailSet(ancestor.getBranchRevision()).iterator();
// first revision is the ancestor (tailSet is inclusive)
// do not undo changes for this revision
- Revision base = it.next();
+ it.next();
Map<String, UpdateOp> operations = Maps.newHashMap();
- while (it.hasNext()) {
+ if (it.hasNext()) {
Revision reset = it.next();
- getRoot(reset).compareAgainstBaseState(getRoot(base),
- new ResetDiff(reset.asTrunkRevision(), operations));
+ // TODO: correct?
+ getRoot(b.getCommit(reset).getBase().update(reset))
+ .compareAgainstBaseState(getRoot(ancestor),
+ new ResetDiff(reset.asTrunkRevision(), operations));
UpdateOp rootOp = operations.get("/");
if (rootOp == null) {
rootOp = new UpdateOp(Utils.getIdFromPath("/"), false);
@@ -1333,7 +1289,7 @@ public final class DocumentNodeStore
if (store.findAndUpdate(Collection.NODES, operations.get("/")) != null) {
// clean up in-memory branch data
// first revision is the ancestor (tailSet is inclusive)
- List<Revision> revs = Lists.newArrayList(b.getCommits().tailSet(ancestor));
+ List<Revision> revs = Lists.newArrayList(b.getCommits().tailSet(ancestor.getBranchRevision()));
for (Revision r : revs.subList(1, revs.size())) {
b.removeCommit(r);
}
@@ -1358,14 +1314,16 @@ public final class DocumentNodeStore
}
@Nonnull
- Revision merge(@Nonnull Revision branchHead, @Nullable CommitInfo info)
+ RevisionVector merge(@Nonnull RevisionVector branchHead,
+ @Nullable CommitInfo info)
throws CommitFailedException {
Branch b = getBranches().getBranch(branchHead);
- Revision base = branchHead;
+ RevisionVector base = branchHead;
if (b != null) {
- base = b.getBase(branchHead);
+ base = b.getBase(branchHead.getBranchRevision());
}
int numBranchCommits = b != null ? b.getCommits().size() : 1;
+ RevisionVector newHead;
boolean success = false;
MergeCommit commit = newMergeCommit(base, numBranchCommits);
try {
@@ -1387,22 +1345,21 @@ public final class DocumentNodeStore
getBranches().remove(b);
} else {
NodeDocument root = Utils.getRootDocument(store);
- Revision conflictRev = root.getMostRecentConflictFor(b.getCommits(), this);
+ Set<Revision> conflictRevs = root.getConflictsFor(b.getCommits());
String msg = "Conflicting concurrent change. Update operation failed: " + op;
- throw new ConflictException(msg, conflictRev).asCommitFailedException();
+ throw new ConflictException(msg, conflictRevs).asCommitFailedException();
}
} else {
// no commits in this branch -> do nothing
}
+ newHead = done(commit, false, info);
success = true;
} finally {
if (!success) {
canceled(commit);
- } else {
- done(commit, false, info);
}
}
- return commit.getRevision();
+ return newHead;
}
/**
@@ -1494,7 +1451,7 @@ public final class DocumentNodeStore
@Nonnull
@Override
public DocumentNodeState getRoot() {
- return getRoot(headRevision);
+ return root;
}
@Nonnull
@@ -1518,6 +1475,7 @@ public final class DocumentNodeStore
}
@Override
+ @Nonnull
public BlobStoreBlob createBlob(InputStream inputStream) throws IOException {
return new BlobStoreBlob(blobStore, blobStore.writeBlob(inputStream));
}
@@ -1530,7 +1488,7 @@ public final class DocumentNodeStore
* @return the blob.
*/
@Override
- public Blob getBlob(String reference) {
+ public Blob getBlob(@Nonnull String reference) {
String blobId = blobStore.getBlobId(reference);
if(blobId != null){
return new BlobStoreBlob(blobStore, blobId);
@@ -1578,19 +1536,13 @@ public final class DocumentNodeStore
@CheckForNull
@Override
public NodeState retrieve(@Nonnull String checkpoint) {
- Revision r;
- try {
- r = Revision.fromString(checkpoint);
- } catch (IllegalArgumentException e) {
- LOG.warn("Malformed checkpoint reference: {}", checkpoint);
- return null;
- }
- SortedMap<Revision, Info> checkpoints = this.checkpoints.getCheckpoints();
- if (checkpoints != null && checkpoints.containsKey(r)) {
- return getRoot(r);
- } else {
+ RevisionVector rv = getCheckpoints().retrieve(checkpoint);
+ if (rv == null) {
return null;
}
+ // make sure all changes up to checkpoint are visible
+ suspendUntilAll(Sets.newHashSet(rv));
+ return getRoot(rv);
}
@Override
@@ -1612,18 +1564,13 @@ public final class DocumentNodeStore
}
@Override
- public Revision.RevisionComparator getRevisionComparator() {
- return revisionComparator;
- }
-
- @Override
public int getClusterId() {
return clusterId;
}
@Nonnull
- public Revision getHeadRevision() {
- return headRevision;
+ public RevisionVector getHeadRevision() {
+ return root.getRevision();
}
@Nonnull
@@ -1729,49 +1676,53 @@ public final class DocumentNodeStore
}
/**
- * Updates the state about cluster nodes in {@link #activeClusterNodes}
- * and {@link #inactiveClusterNodes}.
+ * Updates the state about cluster nodes in {@link #clusterNodes}.
+ *
* @return true if the cluster state has changed, false if the cluster state
* remained unchanged
*/
boolean updateClusterState() {
boolean hasChanged = false;
- long now = clock.getTime();
- Set<Integer> inactive = Sets.newHashSet();
+ Set<Integer> clusterIds = Sets.newHashSet();
for (ClusterNodeInfoDocument doc : ClusterNodeInfoDocument.all(store)) {
int cId = doc.getClusterId();
- if (cId != this.clusterId && !doc.isActive()) {
- inactive.add(cId);
- } else {
- hasChanged |= activeClusterNodes.put(cId, doc.getLeaseEndTime())==null;
+ clusterIds.add(cId);
+ ClusterNodeInfoDocument old = clusterNodes.get(cId);
+ // do not replace document for inactive cluster node
+ // in order to keep the created timestamp of the document
+ // for the time when the cluster node was first seen inactive
+ if (old != null && !old.isActive() && !doc.isActive()) {
+ continue;
+ }
+ clusterNodes.put(cId, doc);
+ if (old == null || old.isActive() != doc.isActive()) {
+ hasChanged = true;
}
}
- hasChanged |= activeClusterNodes.keySet().removeAll(inactive);
- hasChanged |= inactiveClusterNodes.keySet().retainAll(inactive);
- for (Integer clusterId : inactive) {
- hasChanged |= inactiveClusterNodes.putIfAbsent(clusterId, now)==null;
- }
+ hasChanged |= clusterNodes.keySet().retainAll(clusterIds);
return hasChanged;
}
/**
- * Returns the cluster nodes currently known to be inactive.
- *
- * @return a map with the cluster id as key and the time in millis when it
- * was first seen inactive.
- */
- Map<Integer, Long> getInactiveClusterNodes() {
- return new HashMap<Integer, Long>(inactiveClusterNodes);
- }
-
- /**
- * Returns the cluster nodes currently known as active.
- *
- * @return a map with the cluster id as key and the time in millis when the
- * lease ends.
+ * @return the minimum revisions of foreign cluster nodes since they were
+ * started. The revision is derived from the start time of the
+ * cluster node.
*/
- Map<Integer, Long> getActiveClusterNodes() {
- return new HashMap<Integer, Long>(activeClusterNodes);
+ @Nonnull
+ RevisionVector getMinExternalRevisions() {
+ return new RevisionVector(transform(filter(clusterNodes.values(),
+ new Predicate<ClusterNodeInfoDocument>() {
+ @Override
+ public boolean apply(ClusterNodeInfoDocument input) {
+ return input.getClusterId() != getClusterId();
+ }
+ }),
+ new Function<ClusterNodeInfoDocument, Revision>() {
+ @Override
+ public Revision apply(ClusterNodeInfoDocument input) {
+ return new Revision(input.getStartTime(), 0, input.getClusterId());
+ }
+ }));
}
/**
@@ -1787,17 +1738,12 @@ public final class DocumentNodeStore
}
alignWithExternalRevisions(doc);
- Revision.RevisionComparator revisionComparator = getRevisionComparator();
- // the (old) head occurred first
- Revision headSeen = Revision.newRevision(0);
- // then we saw this new revision (from another cluster node)
- Revision otherSeen = Revision.newRevision(0);
-
StringSort externalSort = JournalEntry.newSorter();
Map<Integer, Revision> lastRevMap = doc.getLastRev();
try {
- Map<Revision, Revision> externalChanges = Maps.newHashMap();
+ RevisionVector headRevision = getHeadRevision();
+ Set<Revision> externalChanges = Sets.newHashSet();
for (Map.Entry<Integer, Revision> e : lastRevMap.entrySet()) {
int machineId = e.getKey();
if (machineId == clusterId) {
@@ -1805,20 +1751,18 @@ public final class DocumentNodeStore
continue;
}
Revision r = e.getValue();
- Revision last = lastKnownRevision.get(machineId);
- if (last == null || r.compareRevisionTime(last) > 0) {
- lastKnownRevision.put(machineId, r);
+ Revision last = headRevision.getRevision(machineId);
+ if (last == null) {
+ // make sure we see all changes when a cluster node joins
+ last = new Revision(0, 0, machineId);
+ }
+ if (r.compareRevisionTime(last) > 0) {
// OAK-2345
// only consider as external change if
- // - the revision changed for the machineId
- // or
- // - the revision is within the time frame we remember revisions
- if (last != null
- || r.getTimestamp() > revisionPurgeMillis()) {
- externalChanges.put(r, otherSeen);
- }
+ // the revision changed for the machineId
+ externalChanges.add(r);
// collect external changes
- if (last != null && externalSort != null) {
+ if (externalSort != null) {
// add changes for this particular clusterId to the externalSort
try {
fillExternalChanges(externalSort, last, r, store);
@@ -1871,30 +1815,24 @@ public final class DocumentNodeStore
stats.cacheInvalidationTime = clock.getTime() - time;
time = clock.getTime();
- // make sure update to revision comparator is atomic
- // and no local commit is in progress
+ // make sure no local commit is in progress
backgroundOperationLock.writeLock().lock();
try {
stats.lock = clock.getTime() - time;
- // the latest revisions of the current cluster node
- // happened before the latest revisions of other cluster nodes
- revisionComparator.add(newRevision(), headSeen);
- // then we saw other revisions
- for (Map.Entry<Revision, Revision> e : externalChanges.entrySet()) {
- revisionComparator.add(e.getKey(), e.getValue());
+ RevisionVector oldHead = getHeadRevision();
+ RevisionVector newHead = oldHead;
+ for (Revision r : externalChanges) {
+ newHead = newHead.update(r);
}
-
- Revision oldHead = headRevision;
- // the new head revision is after other revisions
- setHeadRevision(newRevision());
+ setRoot(newHead);
commitQueue.headRevisionChanged();
time = clock.getTime();
if (externalSort != null) {
// then there were external changes and reading them
// was successful -> apply them to the diff cache
try {
- JournalEntry.applyTo(externalSort, diffCache, oldHead, headRevision);
+ JournalEntry.applyTo(externalSort, diffCache, oldHead, newHead);
} catch (Exception e1) {
LOG.error("backgroundRead: Exception while processing external changes from journal: {}", e1, e1);
}
@@ -1907,13 +1845,10 @@ public final class DocumentNodeStore
backgroundOperationLock.writeLock().unlock();
}
stats.dispatchChanges = clock.getTime() - time;
- time = clock.getTime();
}
} finally {
IOUtils.closeQuietly(externalSort);
}
- revisionComparator.purge(revisionPurgeMillis());
- stats.purge = clock.getTime() - time;
return stats;
}
@@ -1925,7 +1860,6 @@ public final class DocumentNodeStore
long populateDiffCache;
long lock;
long dispatchChanges;
- long purge;
@Override
public String toString() {
@@ -1940,21 +1874,10 @@ public final class DocumentNodeStore
", diff: " + populateDiffCache +
", lock:" + lock +
", dispatch:" + dispatchChanges +
- ", purge:" + purge +
'}';
}
}
- /**
- * Returns the time in milliseconds when revisions can be purged from the
- * revision comparator.
- *
- * @return time in milliseconds.
- */
- private static long revisionPurgeMillis() {
- return Revision.getCurrentTimestamp() - REMEMBER_REVISION_ORDER_MILLIS;
- }
-
private void cleanOrphanedBranches() {
Branch b;
while ((b = branches.pollOrphanedBranch()) != null) {
@@ -1975,7 +1898,7 @@ public final class DocumentNodeStore
if (root == null) {
return;
}
- Revision head = getHeadRevision();
+ RevisionVector head = getHeadRevision();
Map<Revision, String> map = root.getLocalMap(NodeDocument.COLLISIONS);
UpdateOp op = new UpdateOp(id, false);
for (Revision r : map.keySet()) {
@@ -1985,7 +1908,7 @@ public final class DocumentNodeStore
// head. That is, the collision cannot be related to commit
// which is progress.
if (branches.getBranchCommit(r) == null
- && isRevisionNewer(head, r)) {
+ && !head.isRevisionNewer(r)) {
NodeDocument.removeCollision(op, r);
}
}
@@ -1997,7 +1920,7 @@ public final class DocumentNodeStore
}
private void backgroundSplit() {
- Revision head = getHeadRevision();
+ RevisionVector head = getHeadRevision();
for (Iterator<String> it = splitCandidates.keySet().iterator(); it.hasNext();) {
String id = it.next();
NodeDocument doc = store.find(Collection.NODES, id);
@@ -2046,30 +1969,18 @@ public final class DocumentNodeStore
//-----------------------------< internal >---------------------------------
/**
- * Performs an initial read of the _lastRevs on the root document,
- * initializes the {@link #revisionComparator} and sets the head revision.
+ * Performs an initial read of the _lastRevs on the root document and sets
+ * the root state.
*
* @param rootDoc the current root document.
*/
- private void initializeHeadRevision(NodeDocument rootDoc) {
- checkState(headRevision == null);
+ private void initializeRootState(NodeDocument rootDoc) {
+ checkState(root == null);
alignWithExternalRevisions(rootDoc);
- Map<Integer, Revision> lastRevMap = rootDoc.getLastRev();
- Revision seenAt = Revision.newRevision(0);
- long purgeMillis = revisionPurgeMillis();
- for (Map.Entry<Integer, Revision> entry : lastRevMap.entrySet()) {
- Revision r = entry.getValue();
- if (r.getTimestamp() > purgeMillis) {
- revisionComparator.add(r, seenAt);
- }
- if (entry.getKey() == clusterId) {
- continue;
- }
- lastKnownRevision.put(entry.getKey(), entry.getValue());
- }
- revisionComparator.purge(purgeMillis);
- setHeadRevision(newRevision());
+ RevisionVector headRevision = new RevisionVector(
+ rootDoc.getLastRev().values()).update(newRevision());
+ setRoot(headRevision);
}
/**
@@ -2108,7 +2019,7 @@ public final class DocumentNodeStore
}
@Nonnull
- private Commit newTrunkCommit(@Nonnull Revision base) {
+ private Commit newTrunkCommit(@Nonnull RevisionVector base) {
checkArgument(!checkNotNull(base).isBranch(),
"base must not be a branch revision: " + base);
@@ -2128,7 +2039,7 @@ public final class DocumentNodeStore
}
@Nonnull
- private Commit newBranchCommit(@Nonnull Revision base,
+ private Commit newBranchCommit(@Nonnull RevisionVector base,
@Nullable DocumentNodeStoreBranch branch) {
checkArgument(checkNotNull(base).isBranch(),
"base must be a branch revision: " + base);
@@ -2200,7 +2111,8 @@ public final class DocumentNodeStore
* and that list does not have the given child node. A <code>false</code> indicates that node <i>might</i>
* exist
*/
- private boolean checkNodeNotExistsFromChildrenCache(String path, Revision rev) {
+ private boolean checkNodeNotExistsFromChildrenCache(String path,
+ RevisionVector rev) {
if (PathUtils.denotesRoot(path)) {
return false;
}
@@ -2247,8 +2159,8 @@ public final class DocumentNodeStore
final long getChildrenDoneIn = debug ? now() : 0;
String diffAlgo;
- Revision fromRev = from.getLastRevision();
- Revision toRev = to.getLastRevision();
+ RevisionVector fromRev = from.getLastRevision();
+ RevisionVector toRev = to.getLastRevision();
if (!fromChildren.hasMore && !toChildren.hasMore) {
diffAlgo = "diffFewChildren";
diffFewChildren(w, from.getPath(), fromChildren,
@@ -2279,10 +2191,11 @@ public final class DocumentNodeStore
return diff;
}
- private void diffManyChildren(JsopWriter w, String path, Revision fromRev, Revision toRev) {
- long minTimestamp = Math.min(
- revisionComparator.getMinimumTimestamp(fromRev, inactiveClusterNodes),
- revisionComparator.getMinimumTimestamp(toRev, inactiveClusterNodes));
+ private void diffManyChildren(JsopWriter w, String path,
+ RevisionVector fromRev,
+ RevisionVector toRev) {
+ long minTimestamp = Utils.getMinTimestampForDiff(
+ fromRev, toRev, getMinExternalRevisions());
long minValue = NodeDocument.getModifiedInSecs(minTimestamp);
String fromKey = Utils.getKeyLowerLimit(path);
String toKey = Utils.getKeyUpperLimit(path);
@@ -2299,9 +2212,10 @@ public final class DocumentNodeStore
// also consider nodes with not yet stored modifications (OAK-1107)
Revision minRev = new Revision(minTimestamp, 0, getClusterId());
addPathsForDiff(path, paths, getPendingModifications().getPaths(minRev));
- for (Revision r : new Revision[]{fromRev, toRev}) {
- if (r.isBranch()) {
- Branch b = branches.getBranch(r);
+ for (RevisionVector rv : new RevisionVector[]{fromRev, toRev}) {
+ if (rv.isBranch()) {
+ Revision r = rv.getBranchRevision();
+ Branch b = branches.getBranch(rv);
if (b != null) {
addPathsForDiff(path, paths, b.getModifiedPathsUntil(r));
}
@@ -2319,8 +2233,8 @@ public final class DocumentNodeStore
if (toNode != null) {
// exists in both revisions
// check if different
- Revision a = fromNode.getLastRevision();
- Revision b = toNode.getLastRevision();
+ RevisionVector a = fromNode.getLastRevision();
+ RevisionVector b = toNode.getLastRevision();
if (a == null && b == null) {
// ok
} else if (a == null || b == null || !a.equals(b)) {
@@ -2357,7 +2271,11 @@ public final class DocumentNodeStore
}
}
- private void diffFewChildren(JsopWriter w, String parentPath, DocumentNodeState.Children fromChildren, Revision fromRev, DocumentNodeState.Children toChildren, Revision toRev) {
+ private void diffFewChildren(JsopWriter w, String parentPath,
+ DocumentNodeState.Children fromChildren,
+ RevisionVector fromRev,
+ DocumentNodeState.Children toChildren,
+ RevisionVector toRev) {
Set<String> childrenSet = Sets.newHashSet(toChildren.children);
for (String n : fromChildren.children) {
if (!childrenSet.contains(n)) {
@@ -2386,7 +2304,7 @@ public final class DocumentNodeStore
}
private static PathRev childNodeCacheKey(@Nonnull String path,
- @Nonnull Revision readRevision,
+ @Nonnull RevisionVector readRevision,
@Nullable String name) {
String p = (name == null ? "" : name) + path;
return new PathRev(p, readRevision);
@@ -2417,7 +2335,8 @@ public final class DocumentNodeStore
// of this commit i.e. transient nodes. If its required it would need to be looked
// into
- DocumentNodeState newNode = new DocumentNodeState(this, targetPath, commit.getRevision());
+ RevisionVector destRevision = commit.getBaseRevision().update(commit.getRevision());
+ DocumentNodeState newNode = new DocumentNodeState(this, targetPath, destRevision);
source.copyTo(newNode);
commit.addNode(newNode);
@@ -2431,15 +2350,6 @@ public final class DocumentNodeStore
}
}
- private void checkRevisionAge(Revision r, String path) {
- if (LOG.isDebugEnabled()) {
- if ("/".equals(path) && headRevision.getTimestamp() - r.getTimestamp() > WARN_REVISION_AGE) {
- LOG.debug("Requesting an old revision for path " + path + ", " +
- ((headRevision.getTimestamp() - r.getTimestamp()) / 1000) + " seconds old");
- }
- }
- }
-
/**
* Creates and returns a MarkSweepGarbageCollector if the current BlobStore
* supports garbage collection
@@ -2502,12 +2412,12 @@ public final class DocumentNodeStore
@Override
public String getRevisionComparatorState() {
- return revisionComparator.toString();
+ return "";
}
@Override
public String getHead(){
- return headRevision.toString();
+ return getRoot().getRevision().toString();
}
@Override
@@ -2522,33 +2432,50 @@ public final class DocumentNodeStore
@Override
public String[] getInactiveClusterNodes() {
- return toArray(transform(inactiveClusterNodes.entrySet(),
- new Function<Map.Entry<Integer, Long>, String>() {
+ return toArray(transform(filter(clusterNodes.values(),
+ new Predicate<ClusterNodeInfoDocument>() {
+ @Override
+ public boolean apply(ClusterNodeInfoDocument input) {
+ return !input.isActive();
+ }
+ }),
+ new Function<ClusterNodeInfoDocument, String>() {
@Override
- public String apply(Map.Entry<Integer, Long> input) {
- return input.toString();
+ public String apply(ClusterNodeInfoDocument input) {
+ return input.getClusterId() + "=" + input.getCreated();
}
}), String.class);
}
@Override
public String[] getActiveClusterNodes() {
- return toArray(transform(activeClusterNodes.entrySet(),
- new Function<Map.Entry<Integer, Long>, String>() {
+ return toArray(transform(filter(clusterNodes.values(),
+ new Predicate<ClusterNodeInfoDocument>() {
@Override
- public String apply(Map.Entry<Integer, Long> input) {
- return input.toString();
+ public boolean apply(ClusterNodeInfoDocument input) {
+ return input.isActive();
+ }
+ }),
+ new Function<ClusterNodeInfoDocument, String>() {
+ @Override
+ public String apply(ClusterNodeInfoDocument input) {
+ return input.getClusterId() + "=" + input.getLeaseEndTime();
}
}), String.class);
}
@Override
public String[] getLastKnownRevisions() {
- return toArray(transform(lastKnownRevision.entrySet(),
- new Function<Map.Entry<Integer, Revision>, String>() {
+ return toArray(transform(filter(getHeadRevision(), new Predicate<Revision>() {
+ @Override
+ public boolean apply(Revision input) {
+ return input.getClusterId() != getClusterId();
+ }
+ }),
+ new Function<Revision, String>() {
@Override
- public String apply(Map.Entry<Integer, Revision> input) {
- return input.toString();
+ public String apply(Revision input) {
+ return input.getClusterId() + "=" + input.toString();
}
}), String.class);
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreBranch.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreBranch.java?rev=1723532&r1=1723531&r2=1723532&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreBranch.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreBranch.java Thu Jan 7 12:46:35 2016
@@ -34,6 +34,8 @@ import java.util.concurrent.locks.ReadWr
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
+import com.google.common.base.Function;
+import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
@@ -279,7 +281,7 @@ class DocumentNodeStoreBranch implements
CommitInfo info) {
boolean success = false;
Commit c = store.newCommit(base.getRevision(), this);
- Revision rev;
+ RevisionVector rev;
try {
op.with(c);
if (c.isEmpty()) {
@@ -287,12 +289,11 @@ class DocumentNodeStoreBranch implements
// finally clause cancel the commit
return base;
}
- rev = c.apply();
+ c.apply();
+ rev = store.done(c, base.getRevision().isBranch(), info);
success = true;
} finally {
- if (success) {
- store.done(c, base.getRevision().isBranch(), info);
- } else {
+ if (!success) {
store.canceled(c);
}
}
@@ -546,7 +547,7 @@ class DocumentNodeStoreBranch implements
* @return the branch state.
*/
final DocumentNodeState createBranch(DocumentNodeState state) {
- return store.getRoot(state.getRevision().asBranchRevision());
+ return store.getRoot(state.getRevision().asBranchRevision(store.getClusterId()));
}
@Override
@@ -641,8 +642,15 @@ class DocumentNodeStoreBranch implements
return;
}
NodeDocument doc = Utils.getRootDocument(store.getDocumentStore());
- Set<Revision> collisions = doc.getLocalMap(COLLISIONS).keySet();
- Set<Revision> conflicts = Sets.intersection(collisions, b.getCommits());
+ Set<Revision> collisions = Sets.newHashSet(doc.getLocalMap(COLLISIONS).keySet());
+ Set<Revision> commits = Sets.newHashSet(Iterables.transform(b.getCommits(),
+ new Function<Revision, Revision>() {
+ @Override
+ public Revision apply(Revision input) {
+ return input.asTrunkRevision();
+ }
+ }));
+ Set<Revision> conflicts = Sets.intersection(collisions, commits);
if (!conflicts.isEmpty()) {
throw new CommitFailedException(STATE, 2,
"Conflicting concurrent change on branch commits " + conflicts);
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreMBean.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreMBean.java?rev=1723532&r1=1723531&r2=1723532&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreMBean.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStoreMBean.java Thu Jan 7 12:46:35 2016
@@ -25,6 +25,7 @@ import org.apache.jackrabbit.oak.commons
public interface DocumentNodeStoreMBean {
String TYPE = "DocumentNodeStore";
+ @Deprecated
String getRevisionComparatorState();
String getHead();
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/JournalEntry.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/JournalEntry.java?rev=1723532&r1=1723531&r2=1723532&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/JournalEntry.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/JournalEntry.java Thu Jan 7 12:46:35 2016
@@ -93,8 +93,8 @@ public final class JournalEntry extends
static void applyTo(@Nonnull StringSort externalSort,
@Nonnull DiffCache diffCache,
- @Nonnull Revision from,
- @Nonnull Revision to) throws IOException {
+ @Nonnull RevisionVector from,
+ @Nonnull RevisionVector to) throws IOException {
LOG.debug("applyTo: starting for {} to {}", from, to);
// note that it is not de-duplicated yet
LOG.debug("applyTo: sorting done.");
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/LastRevs.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/LastRevs.java?rev=1723532&r1=1723531&r2=1723532&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/LastRevs.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/LastRevs.java Thu Jan 7 12:46:35 2016
@@ -17,6 +17,7 @@
package org.apache.jackrabbit.oak.plugins.document;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.Map;
import javax.annotation.CheckForNull;
@@ -28,17 +29,19 @@ import org.apache.jackrabbit.oak.plugins
/**
* Helper class to track when a node was last modified.
*/
-final class LastRevs {
+final class LastRevs implements Iterable<Revision> {
private final Map<Integer, Revision> revs;
- private final Revision readRevision;
+ private final RevisionVector readRevision;
private final Branch branch;
private Revision branchRev;
- LastRevs(Map<Integer, Revision> revs, Revision readRevision, Branch branch) {
+ LastRevs(Map<Integer, Revision> revs,
+ RevisionVector readRevision,
+ Branch branch) {
this.revs = new HashMap<Integer, Revision>(revs);
this.readRevision = readRevision;
this.branch = branch;
@@ -60,7 +63,7 @@ final class LastRevs {
}
rev = rev.asBranchRevision();
if (branch != null && branch.containsCommit(rev)
- && readRevision.compareRevisionTime(rev) >= 0) {
+ && readRevision.getBranchRevision().compareRevisionTime(rev) >= 0) {
branchRev = Utils.max(branchRev, rev);
}
}
@@ -70,8 +73,8 @@ final class LastRevs {
return branchRev;
}
- @Nonnull
- Map<Integer, Revision> get() {
- return revs;
+ @Override
+ public Iterator<Revision> iterator() {
+ return revs.values().iterator();
}
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/LocalDiffCache.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/LocalDiffCache.java?rev=1723532&r1=1723531&r2=1723532&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/LocalDiffCache.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/LocalDiffCache.java Thu Jan 7 12:46:35 2016
@@ -54,8 +54,8 @@ public class LocalDiffCache extends Diff
}
@Override
- public String getChanges(@Nonnull Revision from,
- @Nonnull Revision to,
+ public String getChanges(@Nonnull RevisionVector from,
+ @Nonnull RevisionVector to,
@Nonnull String path,
@Nullable Loader loader) {
RevisionsKey key = new RevisionsKey(from, to);
@@ -72,8 +72,8 @@ public class LocalDiffCache extends Diff
@Nonnull
@Override
- public Entry newEntry(final @Nonnull Revision from,
- final @Nonnull Revision to,
+ public Entry newEntry(final @Nonnull RevisionVector from,
+ final @Nonnull RevisionVector to,
boolean local /*ignored*/) {
return new Entry() {
private final Map<String, String> changesPerPath = Maps.newHashMap();
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/MemoryDiffCache.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/MemoryDiffCache.java?rev=1723532&r1=1723531&r2=1723532&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/MemoryDiffCache.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/MemoryDiffCache.java Thu Jan 7 12:46:35 2016
@@ -56,8 +56,8 @@ public class MemoryDiffCache extends Dif
@CheckForNull
@Override
- public String getChanges(@Nonnull final Revision from,
- @Nonnull final Revision to,
+ public String getChanges(@Nonnull final RevisionVector from,
+ @Nonnull final RevisionVector to,
@Nonnull final String path,
@Nullable final Loader loader) {
PathRev key = diffCacheKey(path, from, to);
@@ -89,8 +89,8 @@ public class MemoryDiffCache extends Dif
@Nonnull
@Override
- public Entry newEntry(@Nonnull Revision from,
- @Nonnull Revision to,
+ public Entry newEntry(@Nonnull RevisionVector from,
+ @Nonnull RevisionVector to,
boolean local /*ignored*/) {
return new MemoryEntry(from, to);
}
@@ -103,10 +103,10 @@ public class MemoryDiffCache extends Dif
protected class MemoryEntry implements Entry {
- private final Revision from;
- private final Revision to;
+ private final RevisionVector from;
+ private final RevisionVector to;
- protected MemoryEntry(Revision from, Revision to) {
+ protected MemoryEntry(RevisionVector from, RevisionVector to) {
this.from = checkNotNull(from);
this.to = checkNotNull(to);
}
@@ -124,8 +124,8 @@ public class MemoryDiffCache extends Dif
}
private static PathRev diffCacheKey(@Nonnull String path,
- @Nonnull Revision from,
- @Nonnull Revision to) {
+ @Nonnull RevisionVector from,
+ @Nonnull RevisionVector to) {
return new PathRev(from + path, to);
}
@@ -142,15 +142,15 @@ public class MemoryDiffCache extends Dif
* @return {@code true} if there are cache entries that indicate the node
* at the given path was modified between the two revisions.
*/
- private boolean isUnchanged(@Nonnull final Revision from,
- @Nonnull final Revision to,
+ private boolean isUnchanged(@Nonnull final RevisionVector from,
+ @Nonnull final RevisionVector to,
@Nonnull final String path) {
return !denotesRoot(path)
&& isChildUnchanged(from, to, getParentPath(path), getName(path));
}
- private boolean isChildUnchanged(@Nonnull final Revision from,
- @Nonnull final Revision to,
+ private boolean isChildUnchanged(@Nonnull final RevisionVector from,
+ @Nonnull final RevisionVector to,
@Nonnull final String parent,
@Nonnull final String name) {
PathRev parentKey = diffCacheKey(parent, from, to);
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/MergeCommit.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/MergeCommit.java?rev=1723532&r1=1723531&r2=1723532&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/MergeCommit.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/MergeCommit.java Thu Jan 7 12:46:35 2016
@@ -33,7 +33,7 @@ class MergeCommit extends Commit {
private final Set<Revision> branchCommits = Sets.newHashSet();
MergeCommit(DocumentNodeStore nodeStore,
- Revision baseRevision,
+ RevisionVector baseRevision,
SortedSet<Revision> revisions) {
super(nodeStore, revisions.last(), baseRevision, null);
this.mergeRevs = revisions;
@@ -52,7 +52,7 @@ class MergeCommit extends Commit {
}
@Override
- public void applyToCache(Revision before, boolean isBranchCommit) {
+ public void applyToCache(RevisionVector before, boolean isBranchCommit) {
// do nothing for a merge commit, only notify node
// store about merged revisions
nodeStore.revisionsMerged(branchCommits);