View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.index.context;
20  
21  import java.io.IOException;
22  import java.util.ArrayList;
23  import java.util.Collection;
24  import java.util.Collections;
25  import java.util.Iterator;
26  import java.util.List;
27  
28  import org.apache.lucene.index.IndexReader;
29  import org.apache.lucene.index.MultiReader;
30  import org.apache.lucene.search.IndexSearcher;
31  
32  public class NexusIndexMultiReader {
33      private final List<IndexingContext> contexts;
34  
35      private List<IndexSearcher> searchers;
36  
37      public NexusIndexMultiReader(final Collection<IndexingContext> contexts) {
38          this.contexts = Collections.unmodifiableList(new ArrayList<>(contexts));
39      }
40  
41      public synchronized IndexReader acquire() throws IOException {
42          if (searchers != null) {
43              release();
44              throw new IllegalStateException("acquire() called 2nd time without release() in between!");
45          }
46          this.searchers = new ArrayList<>();
47          final ArrayList<IndexReader> contextReaders = new ArrayList<>(contexts.size());
48          for (IndexingContext ctx : contexts) {
49              final IndexSearcher indexSearcher = ctx.acquireIndexSearcher();
50              searchers.add(indexSearcher);
51              contextReaders.add(indexSearcher.getIndexReader());
52          }
53          return new MultiReader(contextReaders.toArray(new IndexReader[contextReaders.size()]));
54      }
55  
56      public synchronized void release() throws IOException {
57          if (searchers != null) {
58              final Iterator<IndexingContext> ic = contexts.iterator();
59              final Iterator<IndexSearcher> is = searchers.iterator();
60  
61              while (ic.hasNext() && is.hasNext()) {
62                  ic.next().releaseIndexSearcher(is.next());
63              }
64  
65              if (ic.hasNext() || is.hasNext()) {
66                  throw new IllegalStateException("Context and IndexSearcher mismatch: " + contexts + " vs " + searchers);
67              }
68          }
69  
70          searchers = null;
71      }
72  
73      /**
74       * Watch out with this method, as it's use depends on (if you control it at all) was {@link #acquire()} method
75       * invoked at all or not. Returns {@code null} if not, otherwise the list of acquired searchers. Not thread safe.
76       *
77       * @return
78       */
79      public synchronized List<IndexSearcher> getAcquiredSearchers() {
80          return searchers;
81      }
82  }