use of org.apache.jackrabbit.oak.spi.state.ChildNodeEntry in project jackrabbit-oak by apache.
the class UniqueIndexNodeStoreChecker method check.
@Override
public boolean check(MountedNodeStore mountedStore, Tree tree, ErrorHolder errorHolder, Context context) {
context.track(mountedStore);
// gather index definitions owned by this mount
NodeState indexDefs = mountedStore.getNodeStore().getRoot().getChildNode(INDEX_DEFINITIONS_NAME);
for (ChildNodeEntry indexDef : indexDefs.getChildNodeEntries()) {
if (indexDef.getNodeState().hasProperty(UNIQUE_PROPERTY_NAME) && indexDef.getNodeState().getBoolean(UNIQUE_PROPERTY_NAME)) {
String mountIndexDefName = Multiplexers.getNodeForMount(mountedStore.getMount(), INDEX_CONTENT_NODE_NAME);
NodeState mountIndexDef = indexDef.getNodeState().getChildNode(mountIndexDefName);
if (mountIndexDef.exists()) {
context.add(indexDef, mountedStore.getMount(), indexDefs);
}
}
}
// execute checks
context.runChecks(context, errorHolder);
return false;
}
use of org.apache.jackrabbit.oak.spi.state.ChildNodeEntry in project jackrabbit-oak by apache.
the class UniqueIndexNodeStoreChecker method createContext.
@Override
public Context createContext(NodeStore globalStore, MountInfoProvider mip) {
Context ctx = new Context(mip);
// read definitions from oak:index, and pick all unique indexes
NodeState indexDefs = globalStore.getRoot().getChildNode(INDEX_DEFINITIONS_NAME);
for (ChildNodeEntry indexDef : indexDefs.getChildNodeEntries()) {
if (indexDef.getNodeState().hasProperty(UNIQUE_PROPERTY_NAME) && indexDef.getNodeState().getBoolean(UNIQUE_PROPERTY_NAME)) {
ctx.add(indexDef, mip.getDefaultMount(), indexDefs);
ctx.track(new MountedNodeStore(mip.getDefaultMount(), globalStore));
}
}
return ctx;
}
use of org.apache.jackrabbit.oak.spi.state.ChildNodeEntry in project jackrabbit-oak by apache.
the class VersionGCDeletionTest method queryWhileDocsAreRemoved.
// OAK-2420
@Test
public void queryWhileDocsAreRemoved() throws Exception {
final Thread currentThread = Thread.currentThread();
final Semaphore queries = new Semaphore(0);
final CountDownLatch ready = new CountDownLatch(1);
MemoryDocumentStore ms = new MemoryDocumentStore() {
@Nonnull
@Override
public <T extends Document> List<T> query(Collection<T> collection, String fromKey, String toKey, int limit) {
if (collection == Collection.NODES && Thread.currentThread() != currentThread) {
ready.countDown();
queries.acquireUninterruptibly();
}
return super.query(collection, fromKey, toKey, limit);
}
};
store = new DocumentMK.Builder().clock(clock).setDocumentStore(ms).setAsyncDelay(0).getNodeStore();
// create nodes
NodeBuilder builder = store.getRoot().builder();
NodeBuilder node = builder.child("node");
for (int i = 0; i < 200; i++) {
node.child("c-" + i);
}
merge(store, builder);
clock.waitUntil(clock.getTime() + HOURS.toMillis(1));
// remove nodes
builder = store.getRoot().builder();
node = builder.child("node");
for (int i = 0; i < 90; i++) {
node.getChildNode("c-" + i).remove();
}
merge(store, builder);
store.runBackgroundOperations();
clock.waitUntil(clock.getTime() + HOURS.toMillis(1));
List<String> expected = Lists.newArrayList();
// fill caches
NodeState n = store.getRoot().getChildNode("node");
for (ChildNodeEntry entry : n.getChildNodeEntries()) {
expected.add(entry.getName());
}
assertEquals(110, expected.size());
// invalidate the nodeChildren cache only
store.invalidateNodeChildrenCache();
Future<List<String>> f = newSingleThreadExecutor().submit(new Callable<List<String>>() {
@Override
public List<String> call() throws Exception {
List<String> names = Lists.newArrayList();
NodeState n = store.getRoot().getChildNode("node");
for (ChildNodeEntry entry : n.getChildNodeEntries()) {
names.add(entry.getName());
}
return names;
}
});
// run GC once the reader thread is collecting documents
ready.await();
VersionGarbageCollector gc = store.getVersionGarbageCollector();
VersionGCStats stats = gc.gc(30, MINUTES);
assertEquals(90, stats.deletedDocGCCount);
assertEquals(90, stats.deletedLeafDocGCCount);
queries.release(2);
List<String> names = f.get();
assertEquals(expected, names);
}
use of org.apache.jackrabbit.oak.spi.state.ChildNodeEntry in project jackrabbit-oak by apache.
the class VersionGarbageCollectorIT method gcWithConcurrentModification.
// OAK-2778
@Test
public void gcWithConcurrentModification() throws Exception {
Revision.setClock(clock);
DocumentStore ds = store.getDocumentStore();
// create test content
createTestNode("foo");
createTestNode("bar");
// remove again
NodeBuilder builder = store.getRoot().builder();
builder.getChildNode("foo").remove();
builder.getChildNode("bar").remove();
merge(store, builder);
// wait one hour
clock.waitUntil(clock.getTime() + HOURS.toMillis(1));
final BlockingQueue<NodeDocument> docs = Queues.newSynchronousQueue();
VersionGCSupport gcSupport = new VersionGCSupport(store.getDocumentStore()) {
@Override
public Iterable<NodeDocument> getPossiblyDeletedDocs(long fromModified, long toModified) {
return filter(super.getPossiblyDeletedDocs(fromModified, toModified), new Predicate<NodeDocument>() {
@Override
public boolean apply(NodeDocument input) {
try {
docs.put(input);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return true;
}
});
}
};
final VersionGarbageCollector gc = new VersionGarbageCollector(store, gcSupport);
// start GC -> will try to remove /foo and /bar
Future<VersionGCStats> f = execService.submit(new Callable<VersionGCStats>() {
@Override
public VersionGCStats call() throws Exception {
return gc.gc(30, MINUTES);
}
});
NodeDocument doc = docs.take();
String name = PathUtils.getName(doc.getPath());
// recreate node, which hasn't been removed yet
name = name.equals("foo") ? "bar" : "foo";
builder = store.getRoot().builder();
builder.child(name);
merge(store, builder);
// loop over child node entries -> will populate nodeChildrenCache
for (ChildNodeEntry cne : store.getRoot().getChildNodeEntries()) {
cne.getName();
}
// invalidate cached DocumentNodeState
DocumentNodeState state = (DocumentNodeState) store.getRoot().getChildNode(name);
store.invalidateNodeCache(state.getPath(), store.getRoot().getLastRevision());
while (!f.isDone()) {
docs.poll();
}
// read children again after GC finished
List<String> names = Lists.newArrayList();
for (ChildNodeEntry cne : store.getRoot().getChildNodeEntries()) {
names.add(cne.getName());
}
assertEquals(1, names.size());
doc = ds.find(NODES, Utils.getIdFromPath("/" + names.get(0)));
assertNotNull(doc);
assertEquals(0, Iterators.size(doc.getAllPreviousDocs()));
VersionGCStats stats = f.get();
assertEquals(1, stats.deletedDocGCCount);
assertEquals(2, stats.splitDocGCCount);
assertEquals(0, stats.deletedLeafDocGCCount);
}
use of org.apache.jackrabbit.oak.spi.state.ChildNodeEntry in project jackrabbit-oak by apache.
the class LastRevRecoveryRandomizedIT method compareAndTraverse.
private void compareAndTraverse(NodeState state, final String path, Map<String, NodeState> states) {
NodeState expected = states.remove(path);
if (expected == null) {
fail("unexpected node at " + path + " (seed=" + SEED + ")");
return;
}
comparePropertiesAgainstBaseState(state, expected, new DefaultNodeStateDiff() {
@Override
public boolean propertyAdded(PropertyState after) {
fail("unexpected property: " + path + "/" + after + " (seed=" + SEED + ")");
return super.propertyAdded(after);
}
@Override
public boolean propertyChanged(PropertyState before, PropertyState after) {
assertEquals("property mismatch on node " + path + " (seed=" + SEED + ")", before, after);
return super.propertyChanged(before, after);
}
@Override
public boolean propertyDeleted(PropertyState before) {
fail("missing property: " + path + "/" + before + " (seed=" + SEED + ")");
return super.propertyDeleted(before);
}
});
for (ChildNodeEntry entry : state.getChildNodeEntries()) {
String p = PathUtils.concat(path, entry.getName());
compareAndTraverse(entry.getNodeState(), p, states);
}
}
Aggregations