use of org.apache.jackrabbit.oak.plugins.document.Revision in project jackrabbit-oak by apache.
the class RDBDocumentSerializer method applyUpdate.
private <T extends Document> void applyUpdate(T doc, List updateString, List<Object> op) {
String opcode = op.get(0).toString();
String key = op.get(1).toString();
Revision rev = null;
Object value = null;
if (op.size() == 3) {
value = op.get(2);
} else {
rev = Revision.fromString(op.get(2).toString());
value = op.get(3);
}
Object old = doc.get(key);
if ("=".equals(opcode)) {
if (rev == null) {
doc.put(key, value);
} else {
@SuppressWarnings("unchecked") Map<Revision, Object> m = (Map<Revision, Object>) old;
if (m == null) {
m = new TreeMap<Revision, Object>(comparator);
doc.put(key, m);
}
m.put(rev, value);
}
} else if ("*".equals(opcode)) {
if (rev == null) {
doc.remove(key);
} else {
@SuppressWarnings("unchecked") Map<Revision, Object> m = (Map<Revision, Object>) old;
if (m != null) {
m.remove(rev);
}
}
} else if ("+".equals(opcode)) {
if (rev == null) {
Long x = (Long) value;
if (old == null) {
old = 0L;
}
doc.put(key, ((Long) old) + x);
} else {
throw new DocumentStoreException("unexpected operation " + op + " in: " + updateString);
}
} else if ("M".equals(opcode)) {
if (rev == null) {
Comparable newValue = (Comparable) value;
if (old == null || newValue.compareTo(old) > 0) {
doc.put(key, value);
}
} else {
throw new DocumentStoreException("unexpected operation " + op + " in: " + updateString);
}
} else {
throw new DocumentStoreException("unexpected operation " + op + " in: " + updateString);
}
}
use of org.apache.jackrabbit.oak.plugins.document.Revision in project jackrabbit-oak by apache.
the class Utils method getMinTimestampForDiff.
/**
* Returns the minimum timestamp to use for a query for child documents that
* have been modified between {@code fromRev} and {@code toRev}.
*
* @param fromRev the from revision.
* @param toRev the to revision.
* @param minRevisions the minimum revisions of foreign cluster nodes. These
* are derived from the startTime of a cluster node.
* @return the minimum timestamp.
*/
public static long getMinTimestampForDiff(@Nonnull RevisionVector fromRev, @Nonnull RevisionVector toRev, @Nonnull RevisionVector minRevisions) {
// make sure we have minimum revisions for all known cluster nodes
fromRev = fromRev.pmax(minRevisions);
toRev = toRev.pmax(minRevisions);
// keep only revision entries that changed
RevisionVector from = fromRev.difference(toRev);
RevisionVector to = toRev.difference(fromRev);
// now calculate minimum timestamp
long min = Long.MAX_VALUE;
for (Revision r : from) {
min = Math.min(r.getTimestamp(), min);
}
for (Revision r : to) {
min = Math.min(r.getTimestamp(), min);
}
return min;
}
use of org.apache.jackrabbit.oak.plugins.document.Revision in project jackrabbit-oak by apache.
the class Utils method alignWithExternalRevisions.
/**
* Makes sure the current time is after the most recent external revision
* timestamp in the _lastRev map of the given root document. If necessary
* the current thread waits until {@code clock} is after the external
* revision timestamp.
*
* @param rootDoc the root document.
* @param clock the clock.
* @param clusterId the local clusterId.
* @throws InterruptedException if the current thread is interrupted while
* waiting. The interrupted status on the current thread is cleared
* when this exception is thrown.
*/
public static void alignWithExternalRevisions(@Nonnull NodeDocument rootDoc, @Nonnull Clock clock, int clusterId) throws InterruptedException {
Map<Integer, Revision> lastRevMap = checkNotNull(rootDoc).getLastRev();
long externalTime = Utils.getMaxExternalTimestamp(lastRevMap.values(), clusterId);
long localTime = clock.getTime();
if (localTime < externalTime) {
LOG.warn("Detected clock differences. Local time is '{}', " + "while most recent external time is '{}'. " + "Current _lastRev entries: {}", new Date(localTime), new Date(externalTime), lastRevMap.values());
double delay = ((double) externalTime - localTime) / 1000d;
String fmt = "Background read will be delayed by %.1f seconds. " + "Please check system time on cluster nodes.";
String msg = String.format(fmt, delay);
LOG.warn(msg);
while (localTime + 60000 < externalTime) {
clock.waitUntil(localTime + 60000);
localTime = clock.getTime();
delay = ((double) externalTime - localTime) / 1000d;
LOG.warn(String.format(fmt, delay));
}
clock.waitUntil(externalTime + 1);
} else if (localTime == externalTime) {
// make sure local time is past external time
// but only log at debug
LOG.debug("Local and external time are equal. Waiting until local" + "time is more recent than external reported time.");
clock.waitUntil(externalTime + 1);
}
}
use of org.apache.jackrabbit.oak.plugins.document.Revision in project jackrabbit-oak by apache.
the class RDBDocumentSerializer method asString.
/**
* Serializes the changes in the {@link UpdateOp} into a JSON array; each
* entry is another JSON array holding operation, key, revision, and value.
*/
public String asString(UpdateOp update) {
StringBuilder sb = new StringBuilder("[");
boolean needComma = false;
for (Map.Entry<Key, Operation> change : update.getChanges().entrySet()) {
Operation op = change.getValue();
Key key = change.getKey();
// exclude properties that are serialized into special columns
if (columnProperties.contains(key.getName()) && null == key.getRevision())
continue;
if (needComma) {
sb.append(",");
}
sb.append("[");
if (op.type == UpdateOp.Operation.Type.INCREMENT) {
sb.append("\"+\",");
} else if (op.type == UpdateOp.Operation.Type.SET || op.type == UpdateOp.Operation.Type.SET_MAP_ENTRY) {
sb.append("\"=\",");
} else if (op.type == UpdateOp.Operation.Type.MAX) {
sb.append("\"M\",");
} else if (op.type == UpdateOp.Operation.Type.REMOVE || op.type == UpdateOp.Operation.Type.REMOVE_MAP_ENTRY) {
sb.append("\"*\",");
} else {
throw new DocumentStoreException("Can't serialize " + update.toString() + " for JSON append");
}
appendJsonString(sb, key.getName());
sb.append(",");
Revision rev = key.getRevision();
if (rev != null) {
appendJsonString(sb, rev.toString());
sb.append(",");
}
appendJsonValue(sb, op.value);
sb.append("]");
needComma = true;
}
return sb.append("]").toString();
}
use of org.apache.jackrabbit.oak.plugins.document.Revision in project jackrabbit-oak by apache.
the class ReplicaSetInfo method getSecondariesSafeTimestamp.
/**
* Find the oldest revision which hasn't been replicated from primary to
* secondary yet and return its timestamp. If all revisions has been already
* replicated, return the date of the measurement.
*
* @return the point in time to which the secondary instances has been synchronized
*/
private long getSecondariesSafeTimestamp(Timestamped<RevisionVector> primary, Iterable<Timestamped<RevisionVector>> secondaries) {
final RevisionVector priRev = primary.getValue();
Long oldestNotReplicated = null;
for (Timestamped<RevisionVector> v : secondaries) {
RevisionVector secRev = v.getValue();
if (secRev.equals(priRev)) {
continue;
}
for (Revision pr : priRev) {
Revision sr = secRev.getRevision(pr.getClusterId());
if (pr.equals(sr)) {
continue;
}
if (oldestNotReplicated == null || oldestNotReplicated > pr.getTimestamp()) {
oldestNotReplicated = pr.getTimestamp();
}
}
}
if (oldestNotReplicated == null) {
long minOpTimestamp = primary.getOperationTimestamp();
for (Timestamped<RevisionVector> v : secondaries) {
if (v.getOperationTimestamp() < minOpTimestamp) {
minOpTimestamp = v.getOperationTimestamp();
}
}
return minOpTimestamp;
} else {
return oldestNotReplicated;
}
}
Aggregations