Я хочу запустить два выражения XPath одновременно на двух ревизиях базы данных, которые оба возвращают результаты из Iterator / Iterable и сопоставляют результирующие узлы с узлами в списке.
Я думаю, что лучше всего запустить оба запроса в двух потоках из executorservice и сохранить результаты из обоих потоков в BlockingQueue
, тогда как другой поток собирается отсортировать результаты из BlockingQueue
или фактически сохранить входящие узлы или nodeKeys в правильном положении.
Тогда тривиально получить пересечение результирующего отсортированного списка и другого отсортированного списка.
Есть еще предложения? Я также могу свободно использовать любую технологию, которая мне нравится (желательно Java). Гуава в пути к классам, но я уже думал об использовании Актеров из Акки.
Редактировать: Еще один связанный с этим вопрос может быть связан с тем, быстрее ли использовать InsertionSort в конвейерном режиме (для обработки сгенерированных результатов XPath сразу после их получения) или дождаться, пока не будет создан весь результат, и использовать QuickSort или MergeSort. Я думаю, что InsertionSort должен быть предпочтительным независимо от полученного количества элементов.
В общем, я надеюсь, что сортировка и последующее вычисление пересечения двух списков выполняется быстрее, чем O(n^2)
, для поиска каждого элемента в списке результатов XPath, даже если список делится на количество доступных процессоров ЦП.
Edit:
В настоящее время я реализовал первую часть:
final ExecutorService executor = Executors.newFixedThreadPool(2);
final AbsTemporalAxis axis =
new NextRevisionAxis.Builder(mSession).setRevision(mRevision)
.setIncludeSelf(EIncludeSelf.YES).build();
for (final IReadTransaction rtx : axis) {
final ListenableFuture<Void> future =
Futures.makeListenable(executor.submit(new XPathEvaluation(rtx, mQuery)));
future.addListener(new Runnable() {
@Override
public void run() {
try {
mSemaphore.acquire();
} catch (final InterruptedException e) {
LOGWRAPPER.error(e.getMessage(), e);
}
}
}, executor);
}
executor.shutdown();
final ExecutorService sameThreadExecutor = MoreExecutors.sameThreadExecutor();
sameThreadExecutor.submit(new XPathResult());
sameThreadExecutor.shutdown();
return null;
Семафор инициализируется равным 2, и в XPathEvaluation
результирующие ключи узла добавляются к LinkedBlockingQueue
.
Затем я собираюсь отсортировать XPathResults, обозначенные комментарием, который еще не реализован:
private final class XPathResult implements Callable<Void> {
@Override
public Void call() throws AbsTTException, InterruptedException {
while (true) {
final long key = mQueue.take();
if (key == -1L) {
break;
}
if (mSemaphore.availablePermits() == 0) {
mQueue.put(-1L);
}
// Do InsertionSort.
}
return null;
}
}
Без какого-либо JavaDoc, но я думаю, что по крайней мере это должно работать, как вы думаете? Есть ли у вас какие-либо предпочтительные решения или я уже допустил некоторые ошибки?
С уважением,
Johannes