@SuppressWarnings("rawtypes") @Override public void start(SenseiCore senseiCore) { persistentCaches = new HashMap<Integer, PersistentCache>(senseiCore.getPartitions().length); for (int partition : senseiCore.getPartitions()) { Zoie zoie = (Zoie) senseiCore.getIndexReaderFactory(partition); PersistentCache persistentCache = new PersistentCache(getPath(indexDirectory, nodeId, partition), versionComparator); PersistentCache.registerAsListener(persistentCache, zoie); persistentCaches.put(partition, persistentCache); } }
public final Res execute(final Req senseiReq) { SearchCounter.mark(); Set<Integer> partitions = senseiReq == null ? null : senseiReq.getPartitions(); if (partitions == null) { partitions = new HashSet<Integer>(); int[] containsPart = _core.getPartitions(); if (containsPart != null) { for (int part : containsPart) { partitions.add(part); } } } Res finalResult; if (partitions != null && partitions.size() > 0) { if (logger.isDebugEnabled()) { logger.debug("serving partitions: " + partitions.toString()); } final ArrayList<Res> resultList = new ArrayList<Res>(partitions.size()); Future<Res>[] futures = new Future[partitions.size() - 1]; int i = 0; for (final int partition : partitions) { final long start = System.currentTimeMillis(); final IndexReaderFactory<ZoieIndexReader<BoboIndexReader>> readerFactory = _core.getIndexReaderFactory(partition); if (i < partitions.size() - 1) // Search simultaneously. { try { futures[i] = (Future<Res>) _executorService.submit( new Callable<Res>() { public Res call() throws Exception { Timer timer = getTimer(partition); Res res = timer.time( new Callable<Res>() { @Override public Res call() throws Exception { return handleRequest( senseiReq, readerFactory, _core.getQueryBuilderFactory()); } }); long end = System.currentTimeMillis(); res.setTime(end - start); logger.info( "searching partition: " + partition + " browse took: " + res.getTime()); return res; } }); } catch (Exception e) { senseiReq.addError(new SenseiError(e.getMessage(), ErrorType.BoboExecutionError)); logger.error(e.getMessage(), e); } } else // Reuse current thread. { try { Timer timer = getTimer(partition); Res res = timer.time( new Callable<Res>() { @Override public Res call() throws Exception { return handleRequest( senseiReq, readerFactory, _core.getQueryBuilderFactory()); } }); resultList.add(res); long end = System.currentTimeMillis(); res.setTime(end - start); logger.info("searching partition: " + partition + " browse took: " + res.getTime()); } catch (Exception e) { logger.error(e.getMessage(), e); senseiReq.addError(new SenseiError(e.getMessage(), ErrorType.BoboExecutionError)); resultList.add(getEmptyResultInstance(e)); } } ++i; } for (i = 0; i < futures.length; ++i) { try { Res res = futures[i].get(_timeout, TimeUnit.MILLISECONDS); resultList.add(res); } catch (Exception e) { logger.error(e.getMessage(), e); if (e instanceof TimeoutException) { senseiReq.addError(new SenseiError(e.getMessage(), ErrorType.ExecutionTimeout)); } else { senseiReq.addError(new SenseiError(e.getMessage(), ErrorType.BoboExecutionError)); } resultList.add(getEmptyResultInstance(e)); } } try { finalResult = MergeTimer.time( new Callable<Res>() { public Res call() throws Exception { return mergePartitionedResults(senseiReq, resultList); } }); } catch (Exception e) { logger.error(e.getMessage(), e); finalResult = getEmptyResultInstance(null); finalResult.addError(new SenseiError(e.getMessage(), ErrorType.MergePartitionError)); } } else { if (logger.isInfoEnabled()) { logger.info("no partitions specified"); } finalResult = getEmptyResultInstance(null); finalResult.addError( new SenseiError("no partitions specified", ErrorType.PartitionCallError)); } if (logger.isInfoEnabled()) { logger.info( "searching partitions " + String.valueOf(partitions) + " took: " + finalResult.getTime()); } return finalResult; }