Index: lucene/core/src/java/org/apache/lucene/search/thingy/SearcherThingy.java =================================================================== --- lucene/core/src/java/org/apache/lucene/search/thingy/SearcherThingy.java (revision 0) +++ lucene/core/src/java/org/apache/lucene/search/thingy/SearcherThingy.java (working copy) @@ -0,0 +1,69 @@ +package org.apache.lucene.search.thingy; + +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.io.IOException; + +import org.apache.lucene.index.IndexReader; +import org.apache.lucene.search.IndexSearcher; +import org.apache.lucene.search.SearcherFactory; + +public class SearcherThingy implements Thingy { + + private final IndexSearcher searcher; + private final SearcherFactory searcherFactory; + + public SearcherThingy(IndexReader reader, SearcherFactory searcherFactory) throws IOException { + this.searcherFactory = searcherFactory; + this.searcher = searcherFactory.newSearcher(reader); + } + + public void incRef() throws IOException { + searcher.getIndexReader().incRef(); + } + + public void decRef() throws IOException { + searcher.getIndexReader().decRef(); + } + + public boolean tryIncRef() { + return searcher.getIndexReader().tryIncRef(); + } + + public Thingy maybeRefresh() throws IOException { + IndexReader newReader = IndexReader.openIfChanged(searcher.getIndexReader()); + if (newReader != null) { + boolean success = false; + try { + SearcherThingy newThingy = new SearcherThingy(newReader, searcherFactory); + success = true; + return newThingy; + } finally { + if (!success) { + newReader.close(); + } + } + } + return this; + } + + public IndexSearcher get() { + return searcher; + } + +} Property changes on: lucene/core/src/java/org/apache/lucene/search/thingy/SearcherThingy.java ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* Added: svn:eol-style ## -0,0 +1 ## +native Index: lucene/core/src/java/org/apache/lucene/search/thingy/Thingy.java =================================================================== --- lucene/core/src/java/org/apache/lucene/search/thingy/Thingy.java (revision 0) +++ lucene/core/src/java/org/apache/lucene/search/thingy/Thingy.java (working copy) @@ -0,0 +1,30 @@ +package org.apache.lucene.search.thingy; + +import java.io.IOException; + +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +public interface Thingy { + + public void incRef() throws IOException; + public void decRef() throws IOException; + public boolean tryIncRef(); + public Thingy maybeRefresh() throws IOException; + public G get(); + +} Property changes on: lucene/core/src/java/org/apache/lucene/search/thingy/Thingy.java ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* Added: svn:eol-style ## -0,0 +1 ## +native Index: lucene/core/src/java/org/apache/lucene/search/thingy/ThingyManager.java =================================================================== --- lucene/core/src/java/org/apache/lucene/search/thingy/ThingyManager.java (revision 0) +++ lucene/core/src/java/org/apache/lucene/search/thingy/ThingyManager.java (working copy) @@ -0,0 +1,113 @@ +package org.apache.lucene.search.thingy; + +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.io.Closeable; +import java.io.IOException; +import java.util.concurrent.Semaphore; + +import org.apache.lucene.store.AlreadyClosedException; + +public final class ThingyManager implements Closeable { + + private static final String THINGY_MANAGER_IS_CLOSED = "this ThingyManager is closed"; + + private final Semaphore reopenLock = new Semaphore(1); + private Thingy currentThingy; + + public ThingyManager(Thingy thingy) { + currentThingy = thingy; + } + + public boolean maybeRefresh() throws IOException { + ensureOpen(); + // Ensure only 1 thread does reopen at once; other threads just return immediately: + if (reopenLock.tryAcquire()) { + try { + // nocommit: we should call acquire() so that it doesn't get null upon + // us if close() is called (see Mike's commit in rev 1208530. We can + // have an internalAcquire that returns Thingy. Will look at it + // later. + final Thingy newThingy = currentThingy.maybeRefresh(); + if (newThingy != currentThingy) { + boolean success = false; + try { + swapThingy(newThingy); + success = true; + } finally { + if (!success) { + release(newThingy); + } + } + } + return true; + } finally { + reopenLock.release(); + } + } else { + return false; + } + } + + public void release(Thingy thingy) throws IOException { + assert thingy != null; + thingy.decRef(); + } + + /** + * Close this SearcherManager to future searching. Any searches still in + * process in other threads won't be affected, and they should still call + * {@link #release} after they are done. + */ + public synchronized void close() throws IOException { + if (currentThingy != null) { + // make sure we can call this more than once + // closeable javadoc says: + // if this is already closed then invoking this method has no effect. + swapThingy(null); + } + } + + /** + * Obtain the current IndexSearcher. You must match every call to acquire with + * one call to {@link #release}; it's best to do so in a finally clause. + */ + public G acquire() { + Thingy thingy; + do { + if ((thingy = currentThingy) == null) { + throw new AlreadyClosedException(THINGY_MANAGER_IS_CLOSED); + } + } while (!thingy.tryIncRef()); + return thingy.get(); + } + + private void ensureOpen() { + if (currentThingy == null) { + throw new AlreadyClosedException(THINGY_MANAGER_IS_CLOSED); + } + } + + private synchronized void swapThingy(Thingy newThingy) throws IOException { + ensureOpen(); + final Thingy oldThingy = currentThingy; + currentThingy = newThingy; + release(oldThingy); + } + +} Property changes on: lucene/core/src/java/org/apache/lucene/search/thingy/ThingyManager.java ___________________________________________________________________ Added: svn:executable ## -0,0 +1 ## +* Added: svn:eol-style ## -0,0 +1 ## +native