Пример #1
0
  @NotNull
  @ThreadSafe
  private static QueryWrapper createQuery(@NotNull String queryString) throws SearchException {
    PhraseDetectingQueryParser queryParser =
        new PhraseDetectingQueryParser(
            IndexRegistry.LUCENE_VERSION, Fields.CONTENT.key(), IndexRegistry.getAnalyzer());
    queryParser.setAllowLeadingWildcard(true);
    RewriteMethod rewriteMethod = MultiTermQuery.SCORING_BOOLEAN_QUERY_REWRITE;
    queryParser.setMultiTermRewriteMethod(rewriteMethod);
    if (!SettingsConf.Bool.UseOrOperator.get())
      queryParser.setDefaultOperator(QueryParser.AND_OPERATOR);

    try {
      Query query = queryParser.parse(queryString);
      boolean isPhraseQuery = queryParser.isPhraseQuery();
      return new QueryWrapper(query, isPhraseQuery);
    } catch (IllegalArgumentException e) {
      /*
       * This happens for example when you enter a fuzzy search with
       * similarity >= 1, e.g. "fuzzy~1".
       */
      String msg = Msg.invalid_query.get() + "\n\n" + e.getMessage();
      throw new SearchException(msg);
    } catch (ParseException e) {
      String msg = Msg.invalid_query.get() + "\n\n" + e.getMessage();
      throw new SearchException(msg);
    }
  }
Пример #2
0
 /** Updates the cached indexes and replaces the current Lucene searcher with a new one. */
 @ThreadSafe
 @VisibleForPackageGroup
 public void replaceLuceneSearcher() {
   writeLock.lock();
   try {
     Closeables.close(luceneSearcher, false);
     setLuceneSearcher(indexRegistry.getIndexes());
   } catch (IOException e) {
     ioException = e; // Will be thrown later
   } finally {
     writeLock.unlock();
   }
 }
Пример #3
0
  /**
   * Disposes of the receiver. The caller should make sure that no more search requests are
   * submitted to the receiver after this method is called.
   */
  @ThreadSafe
  public void shutdown() {
    if (ioException != null) Util.printErr(ioException);

    writeLock.lock();
    try {
      indexRegistry.removeListeners(addedListener, null);
      Closeables.closeQuietly(luceneSearcher);
    } finally {
      writeLock.unlock();
    }

    /*
     * This should be done after closing the Lucene searcher in order to
     * ensure that no indexes will be deleted outside the deletion queue
     * while the Lucene searcher is still open.
     */
    synchronized (this) {
      deletionThread.interrupt();
    }
  }
Пример #4
0
  /**
   * This method should not be called by clients. Use {@link IndexRegistry#getSearcher()} instead.
   *
   * @param corruptedIndexes A list that will be filled by this constructor with indexes that
   *     couldn't be loaded.
   */
  @VisibleForPackageGroup
  public Searcher(
      @NotNull IndexRegistry indexRegistry,
      @NotNull FileFactory fileFactory,
      @NotNull OutlookMailFactory outlookMailFactory,
      @NotNull final List<CorruptedIndex> corruptedIndexes)
      throws IOException {
    Util.checkNotNull(indexRegistry, fileFactory, outlookMailFactory);
    this.indexRegistry = indexRegistry;
    this.fileFactory = fileFactory;
    this.outlookMailFactory = outlookMailFactory;

    readLock = indexRegistry.getReadLock();
    writeLock = indexRegistry.getWriteLock();

    // Handler for index additions
    addedListener =
        new Event.Listener<LuceneIndex>() {
          public void update(LuceneIndex eventData) {
            replaceLuceneSearcher();
          }
        };

    /*
     * This lock could be moved into the indexes handler, but we'll put it
     * here to avoid releasing and reacquiring it.
     */
    writeLock.lock();
    try {
      indexRegistry.addListeners(
          new ExistingIndexesHandler() {
            // Handle existing indexes
            public void handleExistingIndexes(List<LuceneIndex> indexes) {
              try {
                corruptedIndexes.addAll(setLuceneSearcher(indexes));
              } catch (IOException e) {
                ioException = e;
              }
            }
          },
          addedListener,
          null); // removedListener is null, see deletion thread below
    } finally {
      writeLock.unlock();
    }

    if (ioException != null) throw ioException;

    // Handler for index removals
    deletionThread =
        new Thread(Searcher.class.getName() + " (Approve pending deletions)") {
          public void run() {
            while (true) {
              try {
                List<PendingDeletion> deletions = deletionQueue.take();
                replaceLuceneSearcher();
                for (PendingDeletion deletion : deletions) deletion.setApprovedBySearcher();
              } catch (InterruptedException e) {
                break;
              }
            }
          }
        };
    deletionThread.start();
  }