use of org.apache.jackrabbit.oak.plugins.document.UpdateOp.Operation in project jackrabbit-oak by apache.
the class DocumentSplitTest method removeGarbage.
// OAK-3081
@Test
public void removeGarbage() throws Exception {
final DocumentStore store = mk.getDocumentStore();
final DocumentNodeStore ns = mk.getNodeStore();
final List<Exception> exceptions = Lists.newArrayList();
final List<RevisionVector> revisions = Lists.newArrayList();
Thread t = new Thread(new Runnable() {
@Override
public void run() {
try {
for (int i = 0; i < 200; i++) {
NodeBuilder builder = ns.getRoot().builder();
builder.child("foo").child("node").child("node").child("node").child("node");
builder.child("bar").child("node").child("node").child("node").child("node");
merge(ns, builder);
revisions.add(ns.getHeadRevision());
builder = ns.getRoot().builder();
builder.child("foo").child("node").remove();
builder.child("bar").child("node").remove();
merge(ns, builder);
revisions.add(ns.getHeadRevision());
}
} catch (CommitFailedException e) {
exceptions.add(e);
}
}
});
t.start();
// Use a revision context, which wraps the DocumentNodeStore and
// randomly delays calls to get the head revision
RevisionContext rc = new TestRevisionContext(ns);
while (t.isAlive()) {
for (String id : ns.getSplitCandidates()) {
RevisionVector head = ns.getHeadRevision();
NodeDocument doc = store.find(NODES, id);
List<UpdateOp> ops = SplitOperations.forDocument(doc, rc, head, NO_BINARY, NUM_REVS_THRESHOLD);
Set<Revision> removed = Sets.newHashSet();
Set<Revision> added = Sets.newHashSet();
for (UpdateOp op : ops) {
for (Map.Entry<Key, Operation> e : op.getChanges().entrySet()) {
if (!"_deleted".equals(e.getKey().getName())) {
continue;
}
Revision r = e.getKey().getRevision();
if (e.getValue().type == Operation.Type.REMOVE_MAP_ENTRY) {
removed.add(r);
} else if (e.getValue().type == Operation.Type.SET_MAP_ENTRY) {
added.add(r);
}
}
}
removed.removeAll(added);
assertTrue("SplitOperations must not remove committed changes: " + removed, removed.isEmpty());
}
// perform the actual cleanup
ns.runBackgroundOperations();
}
// the _deleted map must contain all revisions
for (NodeDocument doc : Utils.getAllDocuments(store)) {
if (doc.isSplitDocument() || Utils.getDepthFromId(doc.getId()) < 2) {
continue;
}
Set<Revision> revs = Sets.newHashSet();
for (RevisionVector rv : revisions) {
Iterables.addAll(revs, rv);
}
revs.removeAll(doc.getValueMap("_deleted").keySet());
assertTrue("Missing _deleted entries on " + doc.getId() + ": " + revs, revs.isEmpty());
}
}
use of org.apache.jackrabbit.oak.plugins.document.UpdateOp.Operation in project jackrabbit-oak by apache.
the class DocumentNodeStoreTest method nonBlockingReset.
// OAK-2620
@Test
public void nonBlockingReset() throws Exception {
final List<String> failure = Lists.newArrayList();
final AtomicReference<ReentrantReadWriteLock> mergeLock = new AtomicReference<ReentrantReadWriteLock>();
MemoryDocumentStore store = new MemoryDocumentStore() {
@Override
public <T extends Document> T findAndUpdate(Collection<T> collection, UpdateOp update) {
for (Map.Entry<Key, Operation> entry : update.getChanges().entrySet()) {
if (entry.getKey().getName().equals(NodeDocument.COLLISIONS)) {
ReentrantReadWriteLock rwLock = mergeLock.get();
if (rwLock.getReadHoldCount() > 0 || rwLock.getWriteHoldCount() > 0) {
failure.add("Branch reset still holds merge lock");
break;
}
}
}
return super.findAndUpdate(collection, update);
}
};
DocumentNodeStore ds = builderProvider.newBuilder().setDocumentStore(store).setAsyncDelay(0).getNodeStore();
// do not retry merges
ds.setMaxBackOffMillis(0);
DocumentNodeState root = ds.getRoot();
final DocumentNodeStoreBranch b = ds.createBranch(root);
// branch state is now Unmodified
assertTrue(b.getMergeLock() instanceof ReentrantReadWriteLock);
mergeLock.set((ReentrantReadWriteLock) b.getMergeLock());
NodeBuilder builder = root.builder();
builder.child("foo");
b.setRoot(builder.getNodeState());
// branch state is now InMemory
builder.child("bar");
b.setRoot(builder.getNodeState());
try {
b.merge(new CommitHook() {
@Nonnull
@Override
public NodeState processCommit(NodeState before, NodeState after, CommitInfo info) throws CommitFailedException {
NodeBuilder foo = after.builder().child("foo");
for (int i = 0; i <= DocumentMK.UPDATE_LIMIT; i++) {
foo.setProperty("prop", i);
}
throw new CommitFailedException("Fail", 0, "");
}
}, CommitInfo.EMPTY);
} catch (CommitFailedException e) {
// expected
}
for (String s : failure) {
fail(s);
}
}
use of org.apache.jackrabbit.oak.plugins.document.UpdateOp.Operation in project jackrabbit-oak by apache.
the class NodeDocumentSweeperTest method sweepUncommittedBeforeHead.
@Test
public void sweepUncommittedBeforeHead() throws Exception {
Revision uncommitted = ns.newRevision();
NodeBuilder b = ns.getRoot().builder();
b.child("test");
merge(ns, b);
ns.runBackgroundUpdateOperations();
UpdateOp op = new UpdateOp(getIdFromPath("/test"), false);
op.setMapEntry("foo", uncommitted, "value");
setCommitRoot(op, uncommitted, 0);
setModified(op, uncommitted);
assertNotNull(store.findAndUpdate(NODES, op));
List<UpdateOp> ops = Lists.newArrayList();
Revision nextSweepStart = sweep(ops);
assertEquals(ns.getHeadRevision().getRevision(ns.getClusterId()), nextSweepStart);
assertEquals(1, ops.size());
op = ops.get(0);
Map<Key, Operation> changes = op.getChanges();
assertEquals(2, changes.size());
Operation o = changes.get(new Key(COMMIT_ROOT, uncommitted));
assertNotNull(o);
assertEquals(REMOVE_MAP_ENTRY, o.type);
o = changes.get(new Key("foo", uncommitted));
assertNotNull(o);
assertEquals(REMOVE_MAP_ENTRY, o.type);
}
use of org.apache.jackrabbit.oak.plugins.document.UpdateOp.Operation in project jackrabbit-oak by apache.
the class NodeDocumentSweeperTest method updatePre18Branch.
@Test
public void updatePre18Branch() throws Exception {
String branchRev = mk.branch(null);
branchRev = mk.commit("/", "+\"foo\":{}", branchRev, null);
mk.merge(branchRev, null);
ns.runBackgroundUpdateOperations();
// simulate a pre 1.8 branch commit by removing the branch commit entry
NodeDocument doc = store.find(NODES, getIdFromPath("/foo"));
assertNotNull(doc);
assertEquals(1, doc.getLocalBranchCommits().size());
UpdateOp op = new UpdateOp(doc.getId(), false);
for (Revision r : doc.getLocalBranchCommits()) {
NodeDocument.removeBranchCommit(op, r);
}
assertNotNull(store.findAndUpdate(NODES, op));
List<UpdateOp> ops = Lists.newArrayList();
Revision nextSweepStart = sweep(ops);
assertEquals(ns.getHeadRevision().getRevision(ns.getClusterId()), nextSweepStart);
assertEquals(1, ops.size());
op = ops.get(0);
Map<Key, Operation> changes = op.getChanges();
assertEquals(1, changes.size());
Key k = changes.keySet().iterator().next();
assertEquals("_bc", k.getName());
assertEquals(SET_MAP_ENTRY, changes.get(k).type);
}
Aggregations