use of org.apache.jackrabbit.oak.commons.sort.StringSort in project jackrabbit-oak by apache.
the class ExternalChange method process.
/**
* Processes external changes if there are any.
*
* @return statistics about the background read operation.
*/
BackgroundReadStats process() {
Clock clock = store.getClock();
int clusterId = store.getClusterId();
long time = clock.getTime();
String id = Utils.getIdFromPath("/");
NodeDocument doc = store.getDocumentStore().find(NODES, id, store.getAsyncDelay());
if (doc == null) {
return stats;
}
try {
alignWithExternalRevisions(doc, clock, clusterId);
} catch (InterruptedException e) {
throw new RuntimeException("Background read interrupted", e);
}
StringSort externalSort = newSorter();
StringSort invalidate = newSorter();
Map<Integer, Revision> lastRevMap = doc.getLastRev();
try {
changeSetBuilder = new ChangeSetBuilder(store.getChangeSetMaxItems(), store.getChangeSetMaxDepth());
RevisionVector headRevision = store.getHeadRevision();
Set<Revision> externalChanges = newHashSet();
for (Map.Entry<Integer, Revision> e : lastRevMap.entrySet()) {
int machineId = e.getKey();
if (machineId == clusterId) {
// ignore own lastRev
continue;
}
Revision r = e.getValue();
Revision last = headRevision.getRevision(machineId);
if (last == null) {
// make sure we see all changes when a cluster node joins
last = new Revision(0, 0, machineId);
}
if (r.compareRevisionTime(last) > 0) {
// OAK-2345
// only consider as external change if
// the revision changed for the machineId
externalChanges.add(r);
// collect external changes
if (externalSort != null) {
// add changes for this particular clusterId to the externalSort
try {
fillExternalChanges(externalSort, invalidate, PathUtils.ROOT_PATH, last, r, store.getDocumentStore(), changeSetBuilder, journalPropertyHandler);
} catch (Exception e1) {
LOG.error("backgroundRead: Exception while reading external changes from journal: " + e1, e1);
closeQuietly(externalSort);
closeQuietly(invalidate);
externalSort = null;
invalidate = null;
}
}
}
}
stats.readHead = clock.getTime() - time;
time = clock.getTime();
// invalidate cache
if (cacheInvalidationNeeded(externalSort, invalidate)) {
// invalidate caches
if (externalSort == null) {
// if no externalSort available, then invalidate everything
invalidateCache();
} else {
stats.numExternalChanges = externalSort.getSize();
try {
sortAndInvalidate(externalSort);
sortAndInvalidate(invalidate);
} catch (Exception ioe) {
LOG.error("backgroundRead: got IOException during external sorting/cache invalidation (as a result, invalidating entire cache): " + ioe, ioe);
invalidateCache();
}
}
stats.cacheInvalidationTime = clock.getTime() - time;
}
// update head
if (!externalChanges.isEmpty()) {
updateHead(externalChanges, doc.getSweepRevisions(), externalSort);
}
} finally {
closeQuietly(externalSort);
closeQuietly(invalidate);
}
return stats;
}
use of org.apache.jackrabbit.oak.commons.sort.StringSort in project jackrabbit-oak by apache.
the class JournalDiffLoader method call.
@Override
public String call() {
String path = node.getPath();
RevisionVector afterRev = node.getRootRevision();
RevisionVector beforeRev = base.getRootRevision();
stats = new Stats(path, beforeRev, afterRev);
StringSort changes = JournalEntry.newSorter();
try {
readTrunkChanges(path, beforeRev, afterRev, changes);
readBranchChanges(path, beforeRev, changes);
readBranchChanges(path, afterRev, changes);
changes.sort();
DiffCache df = ns.getDiffCache();
WrappedDiffCache wrappedCache = new WrappedDiffCache(node.getPath(), df, stats);
JournalEntry.applyTo(changes, wrappedCache, path, beforeRev, afterRev);
return wrappedCache.changes;
} catch (IOException e) {
throw DocumentStoreException.convert(e);
} finally {
Utils.closeIfCloseable(changes);
logStats();
}
}
use of org.apache.jackrabbit.oak.commons.sort.StringSort in project jackrabbit-oak by apache.
the class JournalEntryTest method concurrentModification.
// OAK-4682
@Test
public void concurrentModification() throws Exception {
DocumentNodeStore store = new DocumentMK.Builder().getNodeStore();
try {
final JournalEntry entry = store.getCurrentJournalEntry();
Thread t = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 100000; i++) {
entry.modified("/node-" + i);
}
}
});
t.start();
StringSort sort = JournalEntry.newSorter();
try {
entry.addTo(sort, PathUtils.ROOT_PATH);
} finally {
sort.close();
}
t.join();
} finally {
store.dispose();
}
}
use of org.apache.jackrabbit.oak.commons.sort.StringSort in project jackrabbit-oak by apache.
the class JournalEntryTest method useParentDiff.
//OAK-3494
@Test
public void useParentDiff() throws Exception {
DiffCache cache = new MemoryDiffCache(new DocumentMK.Builder());
RevisionVector from = new RevisionVector(new Revision(1, 0, 1));
RevisionVector to = new RevisionVector(new Revision(2, 0, 1));
RevisionVector unjournalled = new RevisionVector(new Revision(3, 0, 1));
//Put one entry for (from, to, "/a/b")->["c1", "c2"] manually
DiffCache.Entry entry = cache.newEntry(from, to, false);
entry.append("/a/b", "^\"c1\":{}^\"c2\":{}");
entry.done();
//NOTE: calling validateCacheUsage fills the cache with an empty diff for the path being validated.
//So, we need to make sure that each validation is done on a separate path.
//Cases that cache can answer (only c1 and c2 sub-trees are possibly changed)
validateCacheUsage(cache, from, to, "/a/b/c3", true);
validateCacheUsage(cache, from, to, "/a/b/c4/e/f/g", true);
//Cases that cache can't answer
//cached entry says that c1 sub-tree is changed
validateCacheUsage(cache, from, to, "/a/b/c1", false);
//cached entry says that c2 sub-tree is changed
validateCacheUsage(cache, from, to, "/a/b/c2/d", false);
//there is no cache entry for the whole hierarchy
validateCacheUsage(cache, from, to, "/c", false);
//Fill cache using journal
List<String> paths = Lists.newArrayList("/content/changed", "/content/changed1/child1");
StringSort sort = JournalEntry.newSorter();
add(sort, paths);
sort.sort();
JournalEntry.applyTo(sort, cache, "/", from, to);
validateCacheUsage(cache, from, to, "/topUnchanged", true);
validateCacheUsage(cache, from, to, "/content/changed/unchangedLeaf", true);
validateCacheUsage(cache, from, to, "/content/changed1/child2", true);
//check against an unjournalled revision (essentially empty cache)
validateCacheUsage(cache, from, unjournalled, "/unjournalledPath", false);
}
use of org.apache.jackrabbit.oak.commons.sort.StringSort in project jackrabbit-oak by apache.
the class JournalEntryTest method invalidateOnly.
@Test
public void invalidateOnly() throws Exception {
DocumentStore store = new MemoryDocumentStore();
JournalEntry invalidateEntry = JOURNAL.newDocument(store);
Set<String> paths = Sets.newHashSet();
addRandomPaths(paths);
invalidateEntry.modified(paths);
Revision r1 = new Revision(1, 0, 1);
Revision r2 = new Revision(2, 0, 1);
Revision r3 = new Revision(3, 0, 1);
UpdateOp op = invalidateEntry.asUpdateOp(r1.asBranchRevision());
assertTrue(store.create(JOURNAL, singletonList(op)));
JournalEntry entry = JOURNAL.newDocument(store);
entry.invalidate(singleton(r1));
op = entry.asUpdateOp(r2);
assertTrue(store.create(JOURNAL, singletonList(op)));
StringSort sort = JournalEntry.newSorter();
StringSort inv = JournalEntry.newSorter();
JournalEntry.fillExternalChanges(sort, inv, r2, r3, store);
assertEquals(0, sort.getSize());
assertEquals(0, inv.getSize());
JournalEntry.fillExternalChanges(sort, inv, r1, r2, store);
assertEquals(1, sort.getSize());
assertEquals(paths.size(), inv.getSize());
inv.close();
sort.close();
sort = JournalEntry.newSorter();
inv = JournalEntry.newSorter();
JournalEntry.fillExternalChanges(sort, inv, r1, r3, store);
assertEquals(1, sort.getSize());
assertEquals(paths.size(), inv.getSize());
sort.close();
inv.close();
}
Aggregations