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 dp...@apache.org on 2012/04/23 11:09:56 UTC
svn commit: r1329139 - in /jackrabbit/oak/trunk/oak-mk/src:
main/java/org/apache/jackrabbit/mk/model/
main/java/org/apache/jackrabbit/mk/persistence/
main/java/org/apache/jackrabbit/mk/store/
test/java/org/apache/jackrabbit/mk/persistence/ test/java/or...
Author: dpfister
Date: Mon Apr 23 09:09:55 2012
New Revision: 1329139
URL: http://svn.apache.org/viewvc?rev=1329139&view=rev
Log:
GC for revisions
- fix dangling parent commit
Modified:
jackrabbit/oak/trunk/oak-mk/src/main/java/org/apache/jackrabbit/mk/model/Id.java
jackrabbit/oak/trunk/oak-mk/src/main/java/org/apache/jackrabbit/mk/persistence/GCPersistence.java
jackrabbit/oak/trunk/oak-mk/src/main/java/org/apache/jackrabbit/mk/persistence/H2Persistence.java
jackrabbit/oak/trunk/oak-mk/src/main/java/org/apache/jackrabbit/mk/persistence/InMemPersistence.java
jackrabbit/oak/trunk/oak-mk/src/main/java/org/apache/jackrabbit/mk/store/DefaultRevisionStore.java
jackrabbit/oak/trunk/oak-mk/src/test/java/org/apache/jackrabbit/mk/persistence/GCPersistenceTest.java
jackrabbit/oak/trunk/oak-mk/src/test/java/org/apache/jackrabbit/mk/store/DefaultRevisionStoreTest.java
Modified: jackrabbit/oak/trunk/oak-mk/src/main/java/org/apache/jackrabbit/mk/model/Id.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-mk/src/main/java/org/apache/jackrabbit/mk/model/Id.java?rev=1329139&r1=1329138&r2=1329139&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-mk/src/main/java/org/apache/jackrabbit/mk/model/Id.java (original)
+++ jackrabbit/oak/trunk/oak-mk/src/main/java/org/apache/jackrabbit/mk/model/Id.java Mon Apr 23 09:09:55 2012
@@ -68,6 +68,22 @@ public class Id implements Comparable<Id
return new Id(StringUtils.convertHexToBytes(s));
}
+ /**
+ * Creates an {@code Id} instance from a long.
+ *
+ * @param l a long
+ * @return an {@code Id} instance
+ */
+ public static Id fromLong(long value) {
+ byte[] raw = new byte[8];
+
+ for (int i = raw.length - 1; i >= 0 && value != 0; i--) {
+ raw[i] = (byte) (value & 0xff);
+ value >>>= 8;
+ }
+ return new Id(raw);
+ }
+
@Override
public int hashCode() {
// the hashCode is intentionally not stored
Modified: jackrabbit/oak/trunk/oak-mk/src/main/java/org/apache/jackrabbit/mk/persistence/GCPersistence.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-mk/src/main/java/org/apache/jackrabbit/mk/persistence/GCPersistence.java?rev=1329139&r1=1329138&r2=1329139&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-mk/src/main/java/org/apache/jackrabbit/mk/persistence/GCPersistence.java (original)
+++ jackrabbit/oak/trunk/oak-mk/src/main/java/org/apache/jackrabbit/mk/persistence/GCPersistence.java Mon Apr 23 09:09:55 2012
@@ -16,6 +16,7 @@
*/
package org.apache.jackrabbit.mk.persistence;
+import org.apache.jackrabbit.mk.model.Commit;
import org.apache.jackrabbit.mk.model.Id;
/**
@@ -45,6 +46,20 @@ public interface GCPersistence extends P
boolean markCommit(Id id) throws Exception;
/**
+ * Replace a commit. Introduced to replace dangling parent commits where
+ * a parent commit might be collected.
+ *
+ * @param id
+ * commit id
+ * @param
+ * @return {@code true} if the commit was not marked before;
+ * {@code false} otherwise
+ *
+ * @throws Exception if an error occurs
+ */
+ void replaceCommit(Id id, Commit commit) throws Exception;
+
+ /**
* Mark a node.
*
* @param id
Modified: jackrabbit/oak/trunk/oak-mk/src/main/java/org/apache/jackrabbit/mk/persistence/H2Persistence.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-mk/src/main/java/org/apache/jackrabbit/mk/persistence/H2Persistence.java?rev=1329139&r1=1329138&r2=1329139&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-mk/src/main/java/org/apache/jackrabbit/mk/persistence/H2Persistence.java (original)
+++ jackrabbit/oak/trunk/oak-mk/src/main/java/org/apache/jackrabbit/mk/persistence/H2Persistence.java Mon Apr 23 09:09:55 2012
@@ -261,6 +261,29 @@ public class H2Persistence implements GC
}
@Override
+ public void replaceCommit(Id id, Commit commit) throws Exception {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ commit.serialize(new BinaryBinding(out));
+ byte[] bytes = out.toByteArray();
+
+ Connection con = cp.getConnection();
+ try {
+ PreparedStatement stmt = con
+ .prepareStatement(
+ "update REVS set DATA = ?, TIME = CURRENT_TIMESTAMP() where ID = ?");
+ try {
+ stmt.setBytes(1, bytes);
+ stmt.setBytes(2, id.getBytes());
+ stmt.executeUpdate();
+ } finally {
+ stmt.close();
+ }
+ } finally {
+ con.close();
+ }
+ }
+
+ @Override
public boolean markNode(Id id) throws Exception {
return touch(id, gcStart);
}
Modified: jackrabbit/oak/trunk/oak-mk/src/main/java/org/apache/jackrabbit/mk/persistence/InMemPersistence.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-mk/src/main/java/org/apache/jackrabbit/mk/persistence/InMemPersistence.java?rev=1329139&r1=1329138&r2=1329139&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-mk/src/main/java/org/apache/jackrabbit/mk/persistence/InMemPersistence.java (original)
+++ jackrabbit/oak/trunk/oak-mk/src/main/java/org/apache/jackrabbit/mk/persistence/InMemPersistence.java Mon Apr 23 09:09:55 2012
@@ -155,6 +155,16 @@ public class InMemPersistence implements
return markObject(id);
}
+ @Override
+ public void replaceCommit(Id id, Commit commit) throws Exception {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ commit.serialize(new BinaryBinding(out));
+ byte[] bytes = out.toByteArray();
+
+ objects.put(id, bytes);
+ marked.put(id, bytes);
+ }
+
private boolean markObject(Id id) throws NotFoundException {
byte[] data = objects.get(id);
if (data != null) {
Modified: jackrabbit/oak/trunk/oak-mk/src/main/java/org/apache/jackrabbit/mk/store/DefaultRevisionStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-mk/src/main/java/org/apache/jackrabbit/mk/store/DefaultRevisionStore.java?rev=1329139&r1=1329138&r2=1329139&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-mk/src/main/java/org/apache/jackrabbit/mk/store/DefaultRevisionStore.java (original)
+++ jackrabbit/oak/trunk/oak-mk/src/main/java/org/apache/jackrabbit/mk/store/DefaultRevisionStore.java Mon Apr 23 09:09:55 2012
@@ -58,7 +58,7 @@ public class DefaultRevisionStore extend
private AtomicLong commitCounter;
private final ReentrantReadWriteLock headLock = new ReentrantReadWriteLock();
private final Persistence pm;
- private final GCPersistence gcpm;
+ protected final GCPersistence gcpm;
/* avoid synthetic accessor */ int initialCacheSize;
/* avoid synthetic accessor */ Map<Id, Object> cache;
@@ -100,7 +100,7 @@ public class DefaultRevisionStore extend
head = pm.readHead();
if (head == null || head.getBytes().length == 0) {
// assume virgin repository
- byte[] rawHead = longToBytes(commitCounter.incrementAndGet());
+ byte[] rawHead = Id.fromLong(commitCounter.incrementAndGet()).getBytes();
head = new Id(rawHead);
Id rootNodeId = pm.writeNode(new MutableNode(this, "/"));
@@ -153,22 +153,6 @@ public class DefaultRevisionStore extend
return (val != null) ? Integer.parseInt(val) : DEFAULT_CACHE_SIZE;
}
- /**
- * Convert a long value into a fixed-size byte array of size 8.
- *
- * @param value value
- * @return byte array
- */
- private static byte[] longToBytes(long value) {
- byte[] result = new byte[8];
-
- for (int i = result.length - 1; i >= 0 && value != 0; i--) {
- result[i] = (byte) (value & 0xff);
- value >>>= 8;
- }
- return result;
- }
-
//--------------------------------------------------------< RevisionStore >
public Id putNode(MutableNode node) throws Exception {
@@ -314,7 +298,7 @@ public class DefaultRevisionStore extend
Id id = commit.getId();
if (id == null) {
- id = new Id(longToBytes(commitCounter.incrementAndGet()));
+ id = Id.fromLong(commitCounter.incrementAndGet());
}
pm.writeCommit(id, commit);
@@ -436,10 +420,16 @@ public class DefaultRevisionStore extend
if (id == null) {
break;
}
- commit = getCommit(id);
- if (commit.getCommitTS() < tsLimit) {
+ StoredCommit parentCommit = getCommit(id);
+ if (parentCommit.getCommitTS() < tsLimit) {
break;
}
+ commit = parentCommit;
+ }
+ if (commit.getParentId() != null) {
+ MutableCommit firstCommit = new MutableCommit(commit);
+ firstCommit.setParentId(null);
+ gcpm.replaceCommit(firstCommit.getId(), firstCommit);
}
}
Modified: jackrabbit/oak/trunk/oak-mk/src/test/java/org/apache/jackrabbit/mk/persistence/GCPersistenceTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-mk/src/test/java/org/apache/jackrabbit/mk/persistence/GCPersistenceTest.java?rev=1329139&r1=1329138&r2=1329139&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-mk/src/test/java/org/apache/jackrabbit/mk/persistence/GCPersistenceTest.java (original)
+++ jackrabbit/oak/trunk/oak-mk/src/test/java/org/apache/jackrabbit/mk/persistence/GCPersistenceTest.java Mon Apr 23 09:09:55 2012
@@ -16,6 +16,7 @@
*/
package org.apache.jackrabbit.mk.persistence;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -25,6 +26,7 @@ import java.util.Arrays;
import java.util.Collection;
import org.apache.jackrabbit.mk.model.Id;
+import org.apache.jackrabbit.mk.model.MutableCommit;
import org.apache.jackrabbit.mk.model.MutableNode;
import org.apache.jackrabbit.mk.model.StoredNode;
import org.apache.jackrabbit.mk.store.NotFoundException;
@@ -121,5 +123,25 @@ public class GCPersistenceTest {
pm.sweep();
pm.readNode(new StoredNode(id, null));
}
+
+ @Test
+ public void testReplaceCommit() throws Exception {
+ MutableCommit c1 = new MutableCommit();
+ c1.setRootNodeId(Id.fromLong(0));
+ pm.writeCommit(Id.fromLong(1), c1);
+
+ MutableCommit c2 = new MutableCommit();
+ c2.setParentId(c1.getId());
+ c2.setRootNodeId(Id.fromLong(0));
+ pm.writeCommit(Id.fromLong(2), c2);
+
+ pm.start();
+ c2 = new MutableCommit();
+ c2.setRootNodeId(Id.fromLong(0));
+ pm.replaceCommit(Id.fromLong(2), c2);
+ pm.sweep();
+
+ assertEquals(null, pm.readCommit(Id.fromLong(2)).getParentId());
+ }
}
Modified: jackrabbit/oak/trunk/oak-mk/src/test/java/org/apache/jackrabbit/mk/store/DefaultRevisionStoreTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-mk/src/test/java/org/apache/jackrabbit/mk/store/DefaultRevisionStoreTest.java?rev=1329139&r1=1329138&r2=1329139&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-mk/src/test/java/org/apache/jackrabbit/mk/store/DefaultRevisionStoreTest.java (original)
+++ jackrabbit/oak/trunk/oak-mk/src/test/java/org/apache/jackrabbit/mk/store/DefaultRevisionStoreTest.java Mon Apr 23 09:09:55 2012
@@ -22,6 +22,9 @@ import org.apache.jackrabbit.mk.api.Micr
import org.apache.jackrabbit.mk.blobs.MemoryBlobStore;
import org.apache.jackrabbit.mk.core.MicroKernelImpl;
import org.apache.jackrabbit.mk.core.Repository;
+import org.apache.jackrabbit.mk.json.fast.Jsop;
+import org.apache.jackrabbit.mk.json.fast.JsopArray;
+import org.apache.jackrabbit.mk.model.MutableCommit;
import org.apache.jackrabbit.mk.persistence.InMemPersistence;
import org.junit.After;
import org.junit.Before;
@@ -40,7 +43,12 @@ public class DefaultRevisionStoreTest {
rs = new DefaultRevisionStore(new InMemPersistence()) {
@Override
protected void doMark() throws Exception {
+ // Keep head commit only
markCommit(getHeadCommit());
+
+ MutableCommit headCommit = new MutableCommit(getHeadCommit());
+ headCommit.setParentId(null);
+ gcpm.replaceCommit(headCommit.getId(), headCommit);
}
};
rs.initialize();
@@ -63,10 +71,13 @@ public class DefaultRevisionStoreTest {
String headRevision = mk.getHeadRevision();
String contents = mk.getNodes("/", headRevision);
-
+
rs.gc();
assertEquals(headRevision, mk.getHeadRevision());
assertEquals(contents, mk.getNodes("/", headRevision));
+
+ String history = mk.getRevisionHistory(Long.MIN_VALUE, Integer.MIN_VALUE);
+ assertEquals(1, ((JsopArray) Jsop.parse(history)).size());
}
}