PrefetchDispatcher extends ChangeDispatcher { @Override public synchronized void contentChanged(@NotNull NodeState root, @NotNull CommitInfo info) { if (root instanceof DocumentNodeState) { final DocumentNodeState state = (DocumentNodeState) root; if (state.isFromExternalChange()) { executor.execute(new Runnable() { private final NodeState before = PrefetchDispatcher.this.root; @Override public void run() { EditorDiff.process( new VisibleEditor(TraversingEditor.INSTANCE), before, state); } }); } } super.contentChanged(root, info); this.root = root; } PrefetchDispatcher(@NotNull NodeState root,
                              @NotNull Executor executor); @Override synchronized void contentChanged(@NotNull NodeState root,
                                            @NotNull CommitInfo info);  }
@Test public void prefetchVisibleChanges() throws Exception { final AtomicInteger numQueries = new AtomicInteger(); MemoryDocumentStore store = new MemoryDocumentStore() { @NotNull @Override public <T extends Document> List<T> query(Collection<T> collection, String fromKey, String toKey, int limit) { if (collection == Collection.NODES) { numQueries.incrementAndGet(); } return super.query(collection, fromKey, toKey, limit); } }; DocumentNodeStore ns1 = builderProvider.newBuilder() .setDocumentStore(store).setClusterId(1) .setPrefetchExternalChanges(false) .setAsyncDelay(0).getNodeStore(); DocumentNodeStore ns2 = builderProvider.newBuilder() .setDocumentStore(store).setClusterId(2) .setPrefetchExternalChanges(false) .setAsyncDelay(0).getNodeStore(); NodeBuilder builder = ns1.getRoot().builder(); builder.child("foo").child("bar").child("baz"); builder.child(":hidden").child("foo").child("bar"); ns1.merge(builder, EmptyHook.INSTANCE, CommitInfo.EMPTY); ns1.runBackgroundOperations(); DocumentNodeState before = ns2.getRoot(); ns2.runBackgroundOperations(); DocumentNodeState after = ns2.getRoot().fromExternalChange(); PrefetchDispatcher dispatcher = new PrefetchDispatcher( before, MoreExecutors.sameThreadExecutor()); numQueries.set(0); dispatcher.contentChanged(after, CommitInfo.EMPTY_EXTERNAL); assertEquals(2, numQueries.get()); }