package org.apache.lucene.index; /* * 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 java.util.concurrent.atomic.AtomicLong; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.search.ControlledRealTimeReopenThread; // javadocs import org.apache.lucene.search.Query; import org.apache.lucene.store.Directory; /** Class that tracks changes to a delegated * IndexWriter, used by {@link * ControlledRealTimeReopenThread} to ensure specific * changes are visible. Create this class (passing your * IndexWriter), and then pass this class to {@link * ControlledRealTimeReopenThread}. * Be sure to make all changes via the * TrackingIndexWriter, otherwise {@link * ControlledRealTimeReopenThread} won't know about the changes. * * @lucene.experimental */ public class TrackingIndexWriter { private final IndexWriter writer; private final AtomicLong indexingGen = new AtomicLong(1); /** Create a {@code TrackingIndexWriter} wrapping the * provided {@link IndexWriter}. */ public TrackingIndexWriter(IndexWriter writer) { this.writer = writer; } /** Calls {@link * IndexWriter#updateDocument(Term,IndexDocument,Analyzer)} * and returns the generation that reflects this change. */ public long updateDocument(Term t, IndexDocument d, Analyzer a) throws IOException { writer.updateDocument(t, d, a); // Return gen as of when indexing finished: return indexingGen.get(); } /** Calls {@link * IndexWriter#updateDocument(Term,IndexDocument)} and * returns the generation that reflects this change. */ public long updateDocument(Term t, IndexDocument d) throws IOException { writer.updateDocument(t, d); // Return gen as of when indexing finished: return indexingGen.get(); } /** Calls {@link * IndexWriter#updateDocuments(Term,Iterable,Analyzer)} * and returns the generation that reflects this change. */ public long updateDocuments(Term t, Iterable<? extends IndexDocument> docs, Analyzer a) throws IOException { writer.updateDocuments(t, docs, a); // Return gen as of when indexing finished: return indexingGen.get(); } /** Calls {@link * IndexWriter#updateDocuments(Term,Iterable)} and returns * the generation that reflects this change. */ public long updateDocuments(Term t, Iterable<? extends IndexDocument> docs) throws IOException { writer.updateDocuments(t, docs); // Return gen as of when indexing finished: return indexingGen.get(); } /** Calls {@link IndexWriter#deleteDocuments(Term)} and * returns the generation that reflects this change. */ public long deleteDocuments(Term t) throws IOException { writer.deleteDocuments(t); // Return gen as of when indexing finished: return indexingGen.get(); } /** Calls {@link IndexWriter#deleteDocuments(Term...)} and * returns the generation that reflects this change. */ public long deleteDocuments(Term... terms) throws IOException { writer.deleteDocuments(terms); // Return gen as of when indexing finished: return indexingGen.get(); } /** Calls {@link IndexWriter#deleteDocuments(Query)} and * returns the generation that reflects this change. */ public long deleteDocuments(Query q) throws IOException { writer.deleteDocuments(q); // Return gen as of when indexing finished: return indexingGen.get(); } /** Calls {@link IndexWriter#deleteDocuments(Query...)} * and returns the generation that reflects this change. */ public long deleteDocuments(Query... queries) throws IOException { writer.deleteDocuments(queries); // Return gen as of when indexing finished: return indexingGen.get(); } /** Calls {@link IndexWriter#deleteAll} and returns the * generation that reflects this change. */ public long deleteAll() throws IOException { writer.deleteAll(); // Return gen as of when indexing finished: return indexingGen.get(); } /** Calls {@link * IndexWriter#addDocument(IndexDocument,Analyzer)} and * returns the generation that reflects this change. */ public long addDocument(IndexDocument d, Analyzer a) throws IOException { writer.addDocument(d, a); // Return gen as of when indexing finished: return indexingGen.get(); } /** Calls {@link * IndexWriter#addDocuments(Iterable,Analyzer)} and * returns the generation that reflects this change. */ public long addDocuments(Iterable<? extends IndexDocument> docs, Analyzer a) throws IOException { writer.addDocuments(docs, a); // Return gen as of when indexing finished: return indexingGen.get(); } /** Calls {@link IndexWriter#addDocument(IndexDocument)} * and returns the generation that reflects this change. */ public long addDocument(IndexDocument d) throws IOException { writer.addDocument(d); // Return gen as of when indexing finished: return indexingGen.get(); } /** Calls {@link IndexWriter#addDocuments(Iterable)} and * returns the generation that reflects this change. */ public long addDocuments(Iterable<? extends IndexDocument> docs) throws IOException { writer.addDocuments(docs); // Return gen as of when indexing finished: return indexingGen.get(); } /** Calls {@link IndexWriter#addIndexes(Directory...)} and * returns the generation that reflects this change. */ public long addIndexes(Directory... dirs) throws IOException { writer.addIndexes(dirs); // Return gen as of when indexing finished: return indexingGen.get(); } /** Calls {@link IndexWriter#addIndexes(IndexReader...)} * and returns the generation that reflects this change. */ public long addIndexes(IndexReader... readers) throws IOException { writer.addIndexes(readers); // Return gen as of when indexing finished: return indexingGen.get(); } /** Return the current generation being indexed. */ public long getGeneration() { return indexingGen.get(); } /** Return the wrapped {@link IndexWriter}. */ public IndexWriter getIndexWriter() { return writer; } /** Return and increment current gen. * * @lucene.internal */ public long getAndIncrementGeneration() { return indexingGen.getAndIncrement(); } /** Cals {@link * IndexWriter#tryDeleteDocument(IndexReader,int)} and * returns the generation that reflects this change. */ public long tryDeleteDocument(IndexReader reader, int docID) throws IOException { if (writer.tryDeleteDocument(reader, docID)) { return indexingGen.get(); } else { return -1; } } }