You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by th...@apache.org on 2012/02/06 14:51:10 UTC
svn commit: r1241011 - in /jackrabbit/sandbox/microkernel/src:
main/java/org/apache/jackrabbit/mk/mem/
main/java/org/apache/jackrabbit/mk/util/
test/java/org/apache/jackrabbit/mk/util/
Author: thomasm
Date: Mon Feb 6 13:51:10 2012
New Revision: 1241011
URL: http://svn.apache.org/viewvc?rev=1241011&view=rev
Log:
Use nanoseconds resolution internally
Removed:
jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/util/NonDescendingClock.java
jackrabbit/sandbox/microkernel/src/test/java/org/apache/jackrabbit/mk/util/NonDescendingClockTest.java
Modified:
jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/mem/MemoryKernelImpl.java
jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/mem/Revision.java
jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/util/AscendingClock.java
jackrabbit/sandbox/microkernel/src/test/java/org/apache/jackrabbit/mk/util/AscendingClockTest.java
Modified: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/mem/MemoryKernelImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/mem/MemoryKernelImpl.java?rev=1241011&r1=1241010&r2=1241011&view=diff
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/mem/MemoryKernelImpl.java (original)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/mem/MemoryKernelImpl.java Mon Feb 6 13:51:10 2012
@@ -26,10 +26,10 @@ import org.apache.jackrabbit.mk.json.Jso
import org.apache.jackrabbit.mk.json.JsopTokenizer;
import org.apache.jackrabbit.mk.json.JsopWriter;
import org.apache.jackrabbit.mk.server.Server;
+import org.apache.jackrabbit.mk.util.AscendingClock;
import org.apache.jackrabbit.mk.util.Cache;
import org.apache.jackrabbit.mk.util.CommitGate;
import org.apache.jackrabbit.mk.util.ExceptionFactory;
-import org.apache.jackrabbit.mk.util.NonDescendingClock;
import org.apache.jackrabbit.mk.util.PathUtils;
import org.apache.jackrabbit.mk.wrapper.WrapperBase;
@@ -44,12 +44,12 @@ import java.util.HashMap;
Node structure:
/head/rev = 100
-/head/time = millis
+/head/nanos = nanos
/head/commit/diff = [+ "/test"{}]
/head/commit/msg = "hello ..."
/head/config/ (optional)
/head/data/
-/99/head/time = millis
+/99/head/nanos = nanos
/99/98/head
/99/98/97/head
/99/90/head
@@ -69,7 +69,7 @@ public class MemoryKernelImpl extends Wr
private final String name;
private final AbstractBlobStore ds;
- private final NonDescendingClock clock = new NonDescendingClock(System.currentTimeMillis());
+ private final AscendingClock clock = new AscendingClock(System.currentTimeMillis());
private final CommitGate gate = new CommitGate();
private final Cache<Long, Revision> revisionCache = Cache.newInstance(null, 1024 * 1024);
@@ -340,7 +340,7 @@ public class MemoryKernelImpl extends Wr
}
}
head = head.setChild("data", data, rev);
- Revision revNode = new Revision(rev, clock.time(), diff.toString(), message);
+ Revision revNode = new Revision(rev, clock.nanoTime(), diff.toString(), message);
revisionCache.put(rev, revNode);
head = revNode.store(head, new NodeImpl(nodeMap, rev));
root = root.setChild("head", head, rev);
@@ -379,9 +379,10 @@ public class MemoryKernelImpl extends Wr
public JsopReader getRevisionsStream(long since, int maxEntries) {
NodeImpl node = getRoot();
+ long sinceNanos = since * 1000000;
ArrayList<Revision> revisions = new ArrayList<Revision>();
Revision r = Revision.get(node.getNode("head"));
- if (since < r.getTime() && maxEntries > 0) {
+ if (sinceNanos < r.getNanos() && maxEntries > 0) {
revisions.add(r);
while (revisions.size() < maxEntries) {
String newest = null;
@@ -407,7 +408,7 @@ public class MemoryKernelImpl extends Wr
JsopStream buff = new JsopStream().array();
Collections.sort(revisions);
for (Revision rev : revisions) {
- if (rev.getTime() > since) {
+ if (rev.getNanos() > sinceNanos) {
buff.encodedValue(rev.toString());
}
}
Modified: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/mem/Revision.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/mem/Revision.java?rev=1241011&r1=1241010&r2=1241011&view=diff
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/mem/Revision.java (original)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/mem/Revision.java Mon Feb 6 13:51:10 2012
@@ -28,20 +28,20 @@ public class Revision implements Compara
private NodeImpl node;
private final long id;
- private final long time;
+ private final long nanos;
private String diff;
private String msg;
- Revision(long id, long time, String diff, String msg) {
+ Revision(long id, long nanos, String diff, String msg) {
this.id = id;
- this.time = time;
+ this.nanos = nanos;
this.diff = diff;
this.msg = msg == null ? "" : msg;
}
- Revision(long id, long time, NodeImpl node) {
+ private Revision(long id, long nanos, NodeImpl node) {
this.id = id;
- this.time = time;
+ this.nanos = nanos;
this.node = node;
}
@@ -51,16 +51,16 @@ public class Revision implements Compara
return null;
}
long id = parseId(JsopTokenizer.decodeQuoted(rev));
- long time = Long.parseLong(node.getProperty("time"));
- return new Revision(id, time, node);
+ long nanos = Long.parseLong(node.getProperty("nanos"));
+ return new Revision(id, nanos, node);
}
long getId() {
return id;
}
- long getTime() {
- return time;
+ long getNanos() {
+ return nanos;
}
private String getDiff() {
@@ -104,7 +104,7 @@ public class Revision implements Compara
public String toString() {
return new JsopBuilder().object().
key("id").value(formatId(id)).
- key("ts").value(time).
+ key("ts").value(nanos / 1000000).
endObject().toString();
}
@@ -118,7 +118,7 @@ public class Revision implements Compara
NodeImpl store(NodeImpl head, NodeImpl commit) {
head = head.cloneAndSetProperty("rev", JsopBuilder.encode(formatId(id)), id);
- head = head.cloneAndSetProperty("time", Long.toString(time), id);
+ head = head.cloneAndSetProperty("nanos", Long.toString(nanos), id);
if (diff.indexOf(";\n") >= 0) {
commit.setProperty("diff", JsopBuilder.encode(diff));
} else {
@@ -133,7 +133,7 @@ public class Revision implements Compara
void appendJournal(JsopWriter buff) {
buff.object().
key("id").value(Revision.formatId(id)).
- key("ts").value(time).
+ key("ts").value(nanos / 1000000).
key("msg").value(getMsg()).
key("changes").value(getDiff()).
endObject().newline();
Modified: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/util/AscendingClock.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/util/AscendingClock.java?rev=1241011&r1=1241010&r2=1241011&view=diff
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/util/AscendingClock.java (original)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/util/AscendingClock.java Mon Feb 6 13:51:10 2012
@@ -17,13 +17,30 @@
package org.apache.jackrabbit.mk.util;
/**
- * A clock that normally returns the current system time, but is guaranteed to
- * return ascending values (even if the system time is changed), and never the
- * same value twice. Worst case, it returns incrementing values.
+ * A clock that normally returns the current system time since 1970, and is
+ * guaranteed to return ascending values. It returns ascending values even if
+ * the system time is changed, and never the same value twice. Worst case, it
+ * returns incrementing values. Unique nanosecond values are returned for system
+ * times between the years 1970 and 2554.
*/
public class AscendingClock {
- private long last;
+ /**
+ * The offset between System.nanoTime() (which returns elapsed time) and the
+ * absolute current system time in nanoseconds since 1970 UTC.
+ */
+ private long nanoOffset;
+
+ /**
+ * The last millisecond value returned.
+ */
+ private long lastMillis;
+
+ /**
+ * The last nanosecond value returned.
+ */
+ private long lastNanos;
+
/**
* Create a new clock.
@@ -31,8 +48,38 @@ public class AscendingClock {
* @param last the time (the next returned value will be at least one
* bigger)
*/
- public AscendingClock(long last) {
- this.last = last;
+ public AscendingClock(long lastMillis) {
+ this.lastMillis = lastMillis;
+ this.lastNanos = lastMillis * 1000000;
+ resetNanoOffset();
+ }
+
+ /**
+ * Get the current time, ensuring that the value is always larger than the
+ * last returned time, even if the system time was changed. Worst case, this
+ * method will return the last returned value plus one.
+ *
+ * @return the time in nanoseconds since 1970-01-01 (UTC)
+ */
+ public synchronized long nanoTime() {
+ long nanos = System.nanoTime();
+ long now = nanoOffset + nanos;
+ if (nanos > lastNanos + 1000000000) {
+ // re-sync every second, in case
+ // the system time was changed
+ resetNanoOffset();
+ now = nanoOffset + nanos;
+ }
+ if (now > lastNanos) {
+ lastNanos = now;
+ } else {
+ now = ++lastNanos;
+ }
+ return now;
+ }
+
+ private void resetNanoOffset() {
+ nanoOffset = System.currentTimeMillis() * 1000000 - System.nanoTime();
}
/**
@@ -44,12 +91,12 @@ public class AscendingClock {
*/
public synchronized long time() {
long now = System.currentTimeMillis();
- if (now > last) {
- last = now;
+ if (now > lastMillis) {
+ lastMillis = now;
} else {
- last++;
+ now = ++lastMillis;
}
- return last;
+ return now;
}
}
Modified: jackrabbit/sandbox/microkernel/src/test/java/org/apache/jackrabbit/mk/util/AscendingClockTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/test/java/org/apache/jackrabbit/mk/util/AscendingClockTest.java?rev=1241011&r1=1241010&r2=1241011&view=diff
==============================================================================
--- jackrabbit/sandbox/microkernel/src/test/java/org/apache/jackrabbit/mk/util/AscendingClockTest.java (original)
+++ jackrabbit/sandbox/microkernel/src/test/java/org/apache/jackrabbit/mk/util/AscendingClockTest.java Mon Feb 6 13:51:10 2012
@@ -20,7 +20,7 @@ import junit.framework.TestCase;
public class AscendingClockTest extends TestCase {
- public void test() throws InterruptedException {
+ public void testMillis() throws InterruptedException {
long start, last;
last = start = System.currentTimeMillis() + 10000;
AscendingClock c = new AscendingClock(start);
@@ -31,4 +31,16 @@ public class AscendingClockTest extends
}
}
+ public void testNanos() throws InterruptedException {
+ long start, last;
+ last = start = System.currentTimeMillis() + 10000;
+ AscendingClock c = new AscendingClock(start);
+ assertTrue(c.nanoTime() > last * 1000000);
+ for (int i = 0; i < 10000; i++) {
+ long t = c.nanoTime();
+ assertTrue(t > last);
+ last = t;
+ }
+ }
+
}