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 ju...@apache.org on 2013/03/13 09:21:53 UTC
svn commit: r1455835 - in
/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment:
MongoJournal.java MongoStore.java
Author: jukka
Date: Wed Mar 13 08:21:52 2013
New Revision: 1455835
URL: http://svn.apache.org/r1455835
Log:
OAK-593: Segment-based MK
More careful use of MongoDB write concerns and read preferences
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MongoJournal.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MongoStore.java
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MongoJournal.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MongoJournal.java?rev=1455835&r1=1455834&r2=1455835&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MongoJournal.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MongoJournal.java Wed Mar 13 08:21:52 2013
@@ -20,6 +20,8 @@ import static com.google.common.base.Pre
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.collect.ImmutableMap.of;
+import static com.mongodb.ReadPreference.nearest;
+import static com.mongodb.ReadPreference.primaryPreferred;
import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
import org.apache.jackrabbit.oak.spi.state.NodeState;
@@ -28,6 +30,8 @@ import com.mongodb.BasicDBObject;
import com.mongodb.BasicDBObjectBuilder;
import com.mongodb.DBCollection;
import com.mongodb.DBObject;
+import com.mongodb.WriteConcern;
+import com.mongodb.WriteResult;
class MongoJournal implements Journal {
@@ -35,30 +39,43 @@ class MongoJournal implements Journal {
private final DBCollection journals;
+ private final WriteConcern concern;
+
private final String name;
- MongoJournal(SegmentStore store, DBCollection journals, NodeState root) {
+ MongoJournal(
+ SegmentStore store, DBCollection journals,
+ WriteConcern concern, NodeState root) {
this.store = checkNotNull(store);
this.journals = checkNotNull(journals);
+ this.concern = checkNotNull(concern);
this.name = "root";
- DBObject state = journals.findOne(new BasicDBObject("_id", "root"));
+ DBObject id = new BasicDBObject("_id", "root");
+ DBObject fields = new BasicDBObject("head", 1);
+ DBObject state = journals.findOne(id, fields, primaryPreferred());
if (state == null) {
SegmentWriter writer = new SegmentWriter(store);
- RecordId id = writer.writeNode(root).getRecordId();
+ RecordId head = writer.writeNode(root).getRecordId();
writer.flush();
- state = new BasicDBObject(of("_id", "root", "head", id.toString()));
- journals.insert(state);
+ state = new BasicDBObject(of(
+ "_id", "root",
+ "head", head.toString()));
+ journals.insert(state, concern);
}
}
- MongoJournal(SegmentStore store, DBCollection journals, String name) {
+ MongoJournal(
+ SegmentStore store, DBCollection journals,
+ WriteConcern concern, String name) {
this.store = checkNotNull(store);
this.journals = checkNotNull(journals);
+ this.concern = checkNotNull(concern);
this.name = checkNotNull(name);
checkArgument(!"root".equals(name));
- DBObject state = journals.findOne(new BasicDBObject("_id", name));
+ DBObject id = new BasicDBObject("_id", name);
+ DBObject state = journals.findOne(id, null, primaryPreferred());
if (state == null) {
Journal root = store.getJournal("root");
String head = root.getHead().toString();
@@ -67,20 +84,25 @@ class MongoJournal implements Journal {
"parent", "root",
"base", head,
"head", head));
- journals.insert(state);
+ journals.insert(state, concern);
}
}
@Override
public RecordId getHead() {
- DBObject state = journals.findOne(new BasicDBObject("_id", name));
+ DBObject id = new BasicDBObject("_id", name);
+ DBObject state = journals.findOne(id, null, nearest());
+ if (state == null) {
+ state = journals.findOne(id, null, primaryPreferred());
+ }
checkState(state != null);
return RecordId.fromString(state.get("head").toString());
}
@Override
public synchronized boolean setHead(RecordId base, RecordId head) {
- DBObject state = journals.findOne(new BasicDBObject("_id", name));
+ DBObject id = new BasicDBObject("_id", name);
+ DBObject state = journals.findOne(id, null, primaryPreferred());
checkState(state != null);
if (!base.toString().equals(state.get("head"))) {
return false;
@@ -97,12 +119,15 @@ class MongoJournal implements Journal {
builder.add("head", head.toString());
DBObject nextState = builder.get();
- return journals.findAndModify(state, nextState) != null;
+ WriteResult result =
+ journals.update(state, nextState, false, false, concern);
+ return result.getN() != 0;
}
@Override
- public void merge() {
- DBObject state = journals.findOne(new BasicDBObject("_id", name));
+ public synchronized void merge() {
+ DBObject id = new BasicDBObject("_id", name);
+ DBObject state = journals.findOne(id, null, primaryPreferred());
checkState(state != null);
if (state.containsField("parent")) {
@@ -134,7 +159,8 @@ class MongoJournal implements Journal {
builder.add("parent", state.get("parent"));
builder.add("base", base.toString());
builder.add("head", head.toString());
- journals.update(state, builder.get());
+ // TODO: concurrent updates?
+ journals.update(state, builder.get(), false, false, concern);
}
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MongoStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MongoStore.java?rev=1455835&r1=1455834&r2=1455835&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MongoStore.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MongoStore.java Wed Mar 13 08:21:52 2013
@@ -16,6 +16,9 @@
*/
package org.apache.jackrabbit.oak.plugins.segment;
+import static com.google.common.collect.ImmutableMap.of;
+import static com.mongodb.ReadPreference.nearest;
+import static com.mongodb.ReadPreference.primary;
import static org.apache.jackrabbit.oak.plugins.memory.MemoryNodeState.EMPTY_NODE;
import java.util.List;
@@ -28,9 +31,12 @@ import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBObject;
import com.mongodb.Mongo;
+import com.mongodb.WriteConcern;
public class MongoStore implements SegmentStore {
+ private final WriteConcern concern = WriteConcern.SAFE; // TODO: MAJORITY?
+
private final DBCollection segments;
private final DBCollection journals;
@@ -56,9 +62,9 @@ public class MongoStore implements Segme
@Override
public Journal getJournal(String name) {
if ("root".equals(name)) {
- return new MongoJournal(this, journals, EMPTY_NODE);
+ return new MongoJournal(this, journals, concern, EMPTY_NODE);
} else {
- return new MongoJournal(this, journals, name);
+ return new MongoJournal(this, journals, concern, name);
}
}
@@ -93,11 +99,16 @@ public class MongoStore implements Segme
}
private Segment findSegment(UUID segmentId) {
- DBObject segment = segments.findOne(
- new BasicDBObject("_id", segmentId.toString()));
+ DBObject id = new BasicDBObject("_id", segmentId.toString());
+ DBObject fields = new BasicDBObject(of("data", 1, "uuids", 1));
+
+ DBObject segment = segments.findOne(id, fields, nearest());
if (segment == null) {
- throw new IllegalStateException(
- "Segment " + segmentId + " not found");
+ segment = segments.findOne(id, fields, primary());
+ if (segment == null) {
+ throw new IllegalStateException(
+ "Segment " + segmentId + " not found");
+ }
}
byte[] data = (byte[]) segment.get("data");
@@ -119,7 +130,7 @@ public class MongoStore implements Segme
segment.put("_id", segmentId.toString());
segment.put("data", data);
segment.put("uuids", list);
- segments.insert(segment);
+ segments.insert(segment, concern);
}
@Override